Skip to content

Submanifolds

Hypersurfaces embedded in : their induced metric, their curvature, and differential operators on them. The geometry is on Submanifolds.

Construction

julia
SubManifoldSym(OM, coords, tmp_coords = (), params = ();
               rules = Dict(), tmp_var = Dict(), to_coords = Dict())

coords holds one coordinate fewer than the ambient dimension: a surface in is parametrized by two. The unit normal is built automatically and completes the frame, so the stored bases remain -dimensional.

julia
using TensND, SymPy

R = symbols("R", positive = true)
θ = symbols("θ", positive = true)
ϕ = symbols("ϕ", real = true)

Sphere = SubManifoldSym(
    Tens(R * [sin(θ)cos(ϕ), sin(θ)sin(ϕ), cos(θ)]), (θ, ϕ), (), (R,);
    rules = Dict(abs(sin(θ)) => sin(θ)),
)
tsimplify.(components_canon(normal(Sphere)))

Use rules to resolve sign ambiguities

SymPy cannot know that  , so survives every simplification and multiplies the curvature by . The rules argument rewrites it away, as above. The same machinery is described under Coordinate systems.

The four accessors

FunctionReturns
normalthe unit normal
submetricthe first fundamental form
curvaturethe second fundamental form
connectionthe intrinsic connection coefficients
julia
get_array(submetric(Sphere))

julia
tsimplify.(get_array(curvature(Sphere)))

Both are returned as -dimensional order-2 tensors with a vanishing last row and column, so they combine directly with tensors in the embedded frame.

For a sphere with the outward normal,   :

julia
tsimplify.(get_array(curvature(Sphere)) + get_array(submetric(Sphere)) / R)

The orientation decides the sign

The normal is the generalized cross product of the tangent vectors in the order given, so swapping two coordinates reverses it — and with it the sign of curvature and of the mean curvature. State the orientation whenever a curvature is reported. The Gaussian curvature, being a determinant, is unaffected.

connection — renamed from Riemann

connection returns the connection coefficients (Christoffel symbols) of the induced metric, never a Riemann curvature tensor. The old name Riemann named the wrong object; it still works and forwards, with a deprecation warning. For the sphere it gives    and  . These are connection coefficients: not tensor components, and removable at any single point. Compute the intrinsic curvature from submetric and curvature instead.

Curvatures

The shape operator is the second form with one index raised,  ; its determinant is the Gaussian curvature and its normalized trace the mean curvature.

julia
using LinearAlgebra
a2 = tsimplify.(get_array(submetric(Sphere))[1:2, 1:2])
b2 = tsimplify.(get_array(curvature(Sphere))[1:2, 1:2])
S = tsimplify.(inv(a2) * b2)
(tsimplify(det(S)), tsimplify(tr(S) / 2))
(R^(-2), -1/R)
Surface
plane
sphere, radius , outward normal
cylinder, radius

Differential operators on the surface

A SubManifoldSym is an AbstractCoorSystem, so GRAD, DIV and LAPLACE apply to fields defined on it, with the intrinsic connection. The identity linking the two geometries is the Weingarten relation read as a gradient,

Compare tensors, not stored arrays

The two sides are stored on different bases and variances, so subtracting their get_arrays gives a nonzero — and plausible-looking — wrong answer. Bring both to a common basis and variance first:

julia
components(GRAD(normal(SM), SM), natural_basis(SM), (:cov, :cov)) +
components(curvature(SM),       natural_basis(SM), (:cov, :cov))

which is exactly zero. This is the practical face of Bases and variance.

A worked version of all of the above, on the sphere, cylinder, plane and paraboloid, is in Surfaces: fundamental forms and curvature.