Adding a coordinate system
The most common extension. There are three routes, in increasing order of effort and of control.
1. Numerical, from a position map
The cheapest. Supply a differentiable OM(x) and everything else is derived by automatic differentiation:
CS = CoorSystemNum(x -> [a * cosh(x[1]) * cos(x[2]), a * sinh(x[1]) * sin(x[2])], 2)Nothing else is required — no symbolic setup, no simplification rules. Use this whenever pointwise values are enough. See Numerical coordinate systems.
2. Symbolic, from a position vector
CoorSystemSym(OM, coords)The natural basis
3. Symbolic, with simplification machinery
For anything harder, the intermediate expressions must be tamed or the result is correct and unusable. Four optional arguments do it:
| Argument | Role |
|---|---|
tmp_coords | auxiliary symbols standing for compound expressions |
params | constants appearing in |
tmp_var | substitutions replacing expressions by those symbols |
to_coords | how to eliminate them again before differentiating |
rules | rewrite rules applied after each simplification |
The prolate spheroidal chart is the reference example — see the source of coorsys_spheroidal:
ϕ, p = symbols("ϕ p", real = true)
p̄, q, q̄, c = symbols("p̄ q q̄ c", positive = true)
OM = Tens(c * [p̄ * q̄ * cos(ϕ), p̄ * q̄ * sin(ϕ), p * q])
Spheroidal = CoorSystemSym(
OM, (ϕ, p, q), (p̄, q̄), (c,);
tmp_var = Dict(1 - p^2 => p̄^2, q^2 - 1 => q̄^2),
to_coords = Dict(p̄ => √(1 - p^2), q̄ => √(q^2 - 1)),
)The pattern: introduce a symbol for each radical, declare it positive so SymPy does not carry an absolute value, tell tmp_var how to recognize it, and to_coords how to undo it before differentiating.
rules is the escape hatch for sign ambiguities that assumptions cannot express, such as
4. Supplying the basis directly
When the normalized basis and the Lamé coefficients are known in closed form, give them instead of letting them be derived:
CoorSystemSym(OM, coords, bnorm, χᵢ)This is what the predefined systems do, and it is much faster than differentiating the position vector.
Checklist for a new system
Does
Lamereturn something readable? If not, go to route 3.Do the
Christoffelsymbols match ? The check is one comprehension — see Christoffel symbols.Is a known harmonic function annihilated by
LAPLACE? This is the strongest single test: it fails unless every connection term is right.If a numerical counterpart exists, do the two agree at a point?
Steps 2–4 are exactly what test/test_coorsystems.jl and test/test_coorsystems_num.jl do for the predefined systems.