Add `cartesian_tensor<T>`, a fixed 3x3 second-order Cartesian tensor that
serves as a representation type for tensor-character quantities (e.g.
`isq::stress`, `isq::strain`, `isq::moment_of_inertia`), which previously had
no instantiable representation. It mirrors the `cartesian_vector` design
(hidden-friend operations in a `*_iface` base, const-qualified operator
constraints, no `operator%`).
Operations follow ISO 80000-2:2019 clause 18 (second order): `+`, `-`, unary
`-`, scalar `*`//`, compound assignments, `==`; `tensor_product` (dyadic of two
vectors, 2-18.21), `inner_product` (tensor.tensor 2-18.23, tensor.vector
2-18.24), `scalar_product` (double-dot `:`, 2-18.25), and a Frobenius norm.
Fourth-order `T(x)S` (2-18.22), `transpose`/`trace`, and `a.T` are intentionally
out of scope for now.
Activate the previously stubbed tensor representation concepts: `Tensor` is a
permissive mirror of `Vector` (a tensor of order zero is a scalar and of order
one is a vector, ISO 80000-2:2019 18), so real scalars and `cartesian_vector`
also satisfy tensor character as degenerate lower-rank cases. A genuine
second-order `cartesian_tensor` opts out of the lower-rank `Vector` concept via
`disable_vector`, and `std::complex` opts out of `Tensor` via `disable_tensor`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>