Expand description
The scalar floating-point type and the small/large numeric constants. Spectral decomposition of 3x3 tensors – eigenvalues, eigenvectors, and the basis every isotropic tensor function (logarithm, exponential, square root) is built on. Eigenvalues and eigenvectors of 3x3 tensors.
§What this is for
A spectral decomposition turns a tensor into “three directions, each with a stretch”. That is exactly what several continuum-mechanics operations need:
- Principal stresses and strains — the eigenvalues of the stress or strain tensor, and the directions they act along.
- Isotropic tensor functions — any function of a symmetric tensor (logarithm, exponential, square root) is defined by applying the scalar function to the eigenvalues and rebuilding in the same eigenbasis. The logarithmic (Hencky) strain measure used by finite-strain plasticity is the motivating case.
- Polar decomposition — separating rotation from stretch.
§Method
Both routines solve the characteristic cubic
det(T - λI) = 0 directly with CubicEqn, rather than iterating a Jacobi
or QR sweep. That is upstream OpenFOAM’s approach and it is the right one at
3x3: the closed-form cubic is exact up to round-off, has no iteration count
to tune, and reuses the polynomial solver this crate already carries.
Eigenvectors then come from the sub-determinants of T - λI, choosing the
largest sub-determinant for conditioning, with dedicated fallbacks for
repeated and triple eigenvalues.
§Ordering and normalisation
Eigenvalues are returned in ascending order, matching upstream. The
eigenvector rows of the returned Tensor correspond to the eigenvalues in
that same order, and each is normalised to unit length.
§Degeneracy
Repeated eigenvalues do not have unique eigenvectors — any vector in the degenerate subspace will do. The symmetric routines return an orthonormal set spanning the right subspaces, which is what an isotropic tensor function needs; do not read meaning into which particular basis of a degenerate subspace comes back.
Accuracy near a degeneracy is limited to √(machine epsilon), about
1.5e-8, and this is inherent to the method rather than a defect. A
repeated root of a polynomial is ill-conditioned: perturbing the
coefficients by δ moves a double root by √δ. Since both routines get
their eigenvalues from the characteristic cubic, a tensor with a repeated
eigenvalue yields that eigenvalue to roughly eight digits, not sixteen — so
T v - λ v for such a pair sits near 1e-8, not near 1e-16.
Two consequences worth knowing before relying on this:
- Do not set a residual tolerance tighter than about 1e-7 on a spectrum that may be degenerate.
- A computed tensor (
C = FᵀF, say) splits an exactly-repeated eigenvalue into two numerically distinct ones. The symmetric routines handle that —eigen_vectors_symm_withorthonormalises for exactly this reason — but the generaleigen_vectors_withdoes not, because a non-symmetric tensor has no orthogonal eigenbasis to restore.
Functions§
- eigen_
values - Eigenvalues of a general (possibly non-symmetric) 3x3 tensor, ascending.
- eigen_
values_ checked - As
eigen_values, but also reports whether any root was complex. - eigen_
values_ symm - Eigenvalues of a symmetric 3x3 tensor, ascending.
- eigen_
vectors - Eigenvectors of a general tensor, as tensor rows, ordered by ascending eigenvalue.
- eigen_
vectors_ symm - Eigenvectors of a symmetric tensor, as tensor rows, ordered by ascending eigenvalue.
- eigen_
vectors_ symm_ with - Eigenvectors of a symmetric tensor for given eigenvalues, as tensor rows.
- eigen_
vectors_ with - Eigenvectors of a general tensor for given eigenvalues, as tensor rows.