Skip to content

Rotations and Euler angles

Every symmetry class in this library is defined up to an orientation — an axis for transverse isotropy, a full frame for orthotropy — so the angular convention is part of the specification, not a detail. This page states the one TensND implements, read off _rot3_raw in src/tens_projection.jl and rot2/rot3/ rot6 in src/special_tens.jl.

The convention: Z–Y–Z, in the order

Note the argument order: the function takes but the first rotation applied is . In Rotations.jl terms this is exactly RotZYZ(ϕ, θ, ψ).

Explicitly, with    and   :

The columns of are the new basis vectors expressed in the old frame, so that Basis(θ, ϕ, ψ) builds the RotatedBasis they span.

The third column is the axis

is therefore the polar angle from and the azimuth. This is what makes the convention the natural one here: a transversely isotropic tensor is oriented by alone, so its projection is parametrized by with irrelevant, while orthotropy needs all three. The degeneracy at  , where no longer affects , is why the multi-start grids in ext/TensNDNLoptExt.jl filter those duplicates.

Spherical coordinates use the same angles in a different slot order

The predefined spherical coordinate system returns its coordinates as , not , precisely so that    reproduces the canonical basis in the canonical order. See Curvilinear differential calculus.

Rotating tensors of each order

A rotation acts on an order- tensor by rotating every index. TensND provides the three cases that occur in practice:

FunctionReturnsActs on
rot2(θ)  rotation2-D
rot3(θ, ϕ, ψ)  rotation vectors, order-2 tensors
rot6(θ, ϕ, ψ)order-4 tensorminor-symmetric order-4 tensors

with

the symmetrized box product being what preserves minor symmetry. In the Kelvin–Mandel picture this order-4 object is the   matrix

sometimes called the Bond matrix. Its orthogonality — the property Voigt notation lacks — is what Kelvin–Mandel representation is about.

Recovering angles from a frame

The inverse problem, extracting from an orthonormal matrix, is angles(M, Val{3}) in src/bases.jl. It is used when a symmetry frame has been obtained as an eigenvector basis and must be reported as angles.

Two caveats, inherent to any three-angle parametrization of :

  • the map is not injective and     give the same ;

  • it degenerates at the poles (gimbal lock): at   the matrix reduces to  , so only the sum is determined; at   only the difference   is.

Neither affects the projections: the objective functions of Projection onto a symmetry class depend on the frame, not on the angles chosen to name it, so a degenerate parametrization costs at worst a redundant starting point.