diff --git a/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.C b/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.C
index 0f78aef26e6e283500e164397f70a2ec3c80cf39..9383f233a2335316240f26bc00db6e825b26a9e7 100644
--- a/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.C
+++ b/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.C
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
+    Copyright (C) 2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,28 +31,87 @@ License
 #include "scalarMatrices.H"
 #include "ListOps.H"
 
-// * * * * * * * * * * * * * * * * Constructor  * * * * * * * * * * * * * * //
+#include "tensor.H"
+#include "diagTensor.H"
 
-Foam::SVD::SVD(const scalarRectangularMatrix& A, const scalar minCondition)
-:
-    U_(A),
-    V_(A.n(), A.n()),
-    S_(A.n()),
-    converged_(true),
-    nZeros_(0)
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Same as implementation in scalarMatrices, but for tensor/diagTensor/tensor
+static tensor do_multiply
+(
+    const tensor& A,
+    const diagTensor& B,
+    const tensor& C
+)
 {
+    constexpr direction size = 3;
+
+    tensor ans(Foam::zero{});
+
+    for (direction i = 0; i < size; ++i)
+    {
+        for (direction g = 0; g < size; ++g)
+        {
+            for (direction l = 0; l < size; ++l)
+            {
+                ans(i, g) += C(l, g)*A(i, l)*B[l];
+            }
+        }
+    }
+
+    return ans;
+}
+
+
+template<class MatrixType, class DiagMatrixType, class WorkArrayType>
+static std::pair<label, bool> SVDcomp
+(
+    // input
+    const MatrixType& A,
+
+    // input
+    const scalar minCondition,
+
+    // output
+    MatrixType& U_,
+
+    // output
+    MatrixType& V_,
+
+    // output
+    DiagMatrixType& S_,
+
+    // scratch space
+    WorkArrayType& rv1
+)
+{
+    label nZeros_(0);
+    bool converged_(true);
+
     // SVDcomp to find U_, V_ and S_ - the singular values
 
+    U_ = A;
+
     const label Un = U_.n();
     const label Um = U_.m();
 
-    scalarList rv1(Un);
     scalar g = 0;
     scalar scale = 0;
     scalar s = 0;
     scalar anorm = 0;
     label l = 0;
 
+
+    const auto sign = [](scalar a, scalar b) -> scalar
+    {
+        //return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
+        return b >= 0 ? a : -a;
+    };
+
+
     for (label i=0; i<Un; i++)
     {
         l = i + 2;
@@ -87,7 +147,7 @@ Foam::SVD::SVD(const scalarRectangularMatrix& A, const scalar minCondition)
                     }
 
                     f = s/h;
-                    for (label k=i; k<A.m(); k++)
+                    for (label k=i; k<Um; k++)
                     {
                         U_(k, j) += f*U_(k, i);
                     }
@@ -373,23 +433,91 @@ Foam::SVD::SVD(const scalarRectangularMatrix& A, const scalar minCondition)
 
     // Zero singular values that are less than minCondition*maxS
     const scalar minS = minCondition*S_[findMax(S_)];
-    forAll(S_, i)
+    for (auto& val : S_)
     {
-        if (S_[i] <= minS)
+        if (val <= minS)
         {
-            S_[i] = 0;
-            nZeros_++;
+            val = 0;
+            ++nZeros_;
         }
     }
+
+    return { nZeros_, converged_ };
+}
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * Constructor  * * * * * * * * * * * * * * //
+
+Foam::SVD::SVD(const scalarRectangularMatrix& A, const scalar minCondition)
+:
+    U_(),
+    V_(A.n(), A.n()),
+    S_(A.n()),
+    converged_(true),
+    nZeros_(0)
+{
+    scalarList rv1(A.n());
+
+    // SVDcomp to find U_, V_ and S_ - the singular values
+
+    auto status = SVDcomp(A, minCondition, U_, V_, S_, rv1);
+
+    nZeros_ = status.first;
+    converged_ = status.second;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::scalar Foam::SVD::minNonZeroS() const
+{
+    scalar minS = S_[0];
+    for (label i=1; i<S_.size(); i++)
+    {
+        scalar s = S_[i];
+        if (s > VSMALL && s < minS) minS = s;
+    }
+    return minS;
 }
 
 
 Foam::scalarRectangularMatrix Foam::SVD::VSinvUt() const
 {
     scalarRectangularMatrix VSinvUt;
-    multiply(VSinvUt, V_, inv(S_), U_.T());
+    multiply(VSinvUt, V_, Foam::inv(S_), U_.T());
     return VSinvUt;
 }
 
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::scalarRectangularMatrix Foam::SVD::pinv
+(
+    const scalarRectangularMatrix& A,
+    const scalar minCondition
+)
+{
+    SVD svd(A, minCondition);
+    return svd.VSinvUt();
+}
+
+
+Foam::Tensor<Foam::scalar>
+Foam::SVD::pinv(const Tensor<scalar>& A, const scalar minCondition)
+{
+    // SVDcomp to find U_, V_ and S_ - the singular values
+
+    tensor U_;
+    tensor V_;
+    diagTensor S_;
+    FixedList<scalar, 3> rv1;
+
+    SVDcomp(A, minCondition, U_, V_, S_, rv1);
+
+    return do_multiply(V_, Foam::inv(S_), U_.T());
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.H b/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.H
index 6bb5c5050aa5dd358173600d5817befd1ea08a51..005656b54c3d523f809a8625615e43b99d408f22 100644
--- a/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.H
+++ b/src/OpenFOAM/matrices/scalarMatrices/SVD/SVD.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,13 +31,12 @@ Description
     Singular value decomposition of a rectangular matrix.
 
 SourceFiles
-    SVDI.H
     SVD.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef SVD_H
-#define SVD_H
+#ifndef Foam_SVD_H
+#define Foam_SVD_H
 
 #include "scalarMatrices.H"
 
@@ -45,7 +45,8 @@ SourceFiles
 namespace Foam
 {
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Forward Declarations
+template<class Cmpt> class Tensor;
 
 /*---------------------------------------------------------------------------*\
                       Class SVD Declaration
@@ -53,7 +54,7 @@ namespace Foam
 
 class SVD
 {
-    // Private data
+    // Private Data
 
         //- Rectangular matrix with the same dimensions as the input
         scalarRectangularMatrix U_;
@@ -71,7 +72,9 @@ class SVD
         label nZeros_;
 
 
-    // Private Member Functions
+public:
+
+    // Generated Methods
 
         //- No copy construct
         SVD(const SVD&) = delete;
@@ -79,50 +82,65 @@ class SVD
         //- No copy assignment
         void operator=(const SVD&) = delete;
 
-        template<class T>
-        inline const T sign(const T& a, const T& b);
-
-
-public:
 
     // Constructors
 
         //- Construct from a rectangular Matrix
-        SVD(const scalarRectangularMatrix& A, const scalar minCondition = 0);
+        explicit SVD
+        (
+            const scalarRectangularMatrix& A,
+            const scalar minCondition = 0
+        );
 
 
-    // Access functions
+    // Access Functions
 
         //- Return U
-        inline const scalarRectangularMatrix& U() const;
+        const scalarRectangularMatrix& U() const noexcept { return U_; }
 
         //- Return the square matrix V
-        inline const scalarRectangularMatrix& V() const;
+        const scalarRectangularMatrix& V() const noexcept { return V_; }
 
         //- Return the singular values
-        inline const scalarDiagonalMatrix& S() const;
+        const scalarDiagonalMatrix& S() const noexcept { return S_; }
 
         //- Return the minimum non-zero singular value
-        inline bool converged() const;
+        bool converged() const noexcept { return converged_; }
 
         //- Return the number of zero singular values
-        inline label nZeros() const;
+        label nZeros() const noexcept { return nZeros_; }
 
         //- Return the minimum non-zero singular value
-        inline scalar minNonZeroS() const;
+        scalar minNonZeroS() const;
+
+
+    // Member Functions
 
         //- Return the matrix product V S^(-1) U^T (the pseudo inverse)
         scalarRectangularMatrix VSinvUt() const;
-};
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+    // Static Member Functions
+
+        //- Return the pseudo inverse of the given matrix
+        static scalarRectangularMatrix pinv
+        (
+            const scalarRectangularMatrix& A,
+            const scalar minCondition = 0
+        );
+
+        //- Return the pseudo inverse of the given tensor
+        static Tensor<scalar> pinv
+        (
+            const Tensor<scalar>& A,
+            const scalar minCondition = 0
+        );
+};
 
-} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "SVDI.H"
+} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/matrices/scalarMatrices/SVD/SVDI.H b/src/OpenFOAM/matrices/scalarMatrices/SVD/SVDI.H
deleted file mode 100644
index f23c90714f0bf4140dc816ddb5281b70632d874a..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/matrices/scalarMatrices/SVD/SVDI.H
+++ /dev/null
@@ -1,82 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | www.openfoam.com
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-    Copyright (C) 2011-2016 OpenFOAM Foundation
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-// * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * * //
-
-template<class T>
-inline const T Foam::SVD::sign(const T& a, const T& b)
-{
-    //return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
-    return b >= 0 ? a : -a;
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-inline const Foam::scalarRectangularMatrix& Foam::SVD::U() const
-{
-    return U_;
-}
-
-
-inline const Foam::scalarRectangularMatrix& Foam::SVD::V() const
-{
-    return V_;
-}
-
-
-inline const Foam::scalarDiagonalMatrix& Foam::SVD::S() const
-{
-    return S_;
-}
-
-
-inline bool Foam::SVD::converged() const
-{
-    return converged_;
-}
-
-
-inline Foam::label Foam::SVD::nZeros() const
-{
-    return nZeros_;
-}
-
-
-inline Foam::scalar Foam::SVD::minNonZeroS() const
-{
-    scalar minS = S_[0];
-    for (label i=1; i<S_.size(); i++)
-    {
-        scalar s = S_[i];
-        if (s > VSMALL && s < minS) minS = s;
-    }
-    return minS;
-}
-
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/scalarMatrices/scalarMatrices.C b/src/OpenFOAM/matrices/scalarMatrices/scalarMatrices.C
index 1bd42a36080dad51a0be66547ee16e168659252a..5d82783a0c9569192bc7ca92ca4c81c5c8a0539f 100644
--- a/src/OpenFOAM/matrices/scalarMatrices/scalarMatrices.C
+++ b/src/OpenFOAM/matrices/scalarMatrices/scalarMatrices.C
@@ -271,7 +271,7 @@ void Foam::multiply
             << abort(FatalError);
     }
 
-    ans = scalarRectangularMatrix(A.m(), C.n(), Zero);
+    ans = scalarRectangularMatrix(A.m(), C.n(), Foam::zero{});
 
     for (label i = 0; i < A.m(); ++i)
     {
@@ -312,7 +312,7 @@ void Foam::multiply
 
     const label size = A.m();
 
-    ans = scalarSquareMatrix(size, Zero);
+    ans = scalarSquareMatrix(size, Foam::zero{});
 
     for (label i = 0; i < size; ++i)
     {
@@ -334,8 +334,7 @@ Foam::scalarRectangularMatrix Foam::SVDinv
     scalar minCondition
 )
 {
-    SVD svd(A, minCondition);
-    return svd.VSinvUt();
+    return SVD::pinv(A, minCondition);
 }
 
 
diff --git a/src/OpenFOAM/primitives/SymmTensor/symmTensor/symmTensor.C b/src/OpenFOAM/primitives/SymmTensor/symmTensor/symmTensor.C
index fb41001b1f8009a25c3a12572172d697bd4b794c..d8c5af408e59df177a5d6202c658f6d160b9b3bb 100644
--- a/src/OpenFOAM/primitives/SymmTensor/symmTensor/symmTensor.C
+++ b/src/OpenFOAM/primitives/SymmTensor/symmTensor/symmTensor.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2020-2022 OpenCFD Ltd.
+    Copyright (C) 2020-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -345,19 +345,14 @@ Foam::symmTensor Foam::pinv(const symmTensor& st)
     if (detval < ROOTVSMALL)
     {
         // Fall back to pseudo inverse
-        scalarRectangularMatrix mat(3, 3);
-
-        mat(0,0) = st.xx(); mat(0,1) = st.xy(); mat(0,2) = st.xz();
-        mat(1,0) = st.yx(); mat(1,1) = st.yy(); mat(1,2) = st.yz();
-        mat(2,0) = st.zx(); mat(2,1) = st.zy(); mat(2,2) = st.zz();
-
-        mat = SVDinv(mat);
+        tensor mat(st);
+        tensor t = SVD::pinv(mat);
 
         return symmTensor
         (
-            mat(0,0), mat(0,1), mat(0,2),
-                      mat(1,1), mat(1,2),
-                                mat(2,2)
+            t.xx(), t.xy(), t.xz(),
+                    t.yy(), t.yz(),
+                            t.zz()
         );
     }
 
diff --git a/src/OpenFOAM/primitives/Tensor/floats/tensor.C b/src/OpenFOAM/primitives/Tensor/floats/tensor.C
index d26aad40a4147af6c05f97316a986534f555d6cf..e1b5dcff68ebe807f61381ebc0c0390109588f9f 100644
--- a/src/OpenFOAM/primitives/Tensor/floats/tensor.C
+++ b/src/OpenFOAM/primitives/Tensor/floats/tensor.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2020-2022 OpenCFD Ltd.
+    Copyright (C) 2020-2025 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -309,20 +309,7 @@ Foam::tensor Foam::pinv(const tensor& t)
     if (detval < ROOTVSMALL)
     {
         // Fall back to pseudo inverse
-        scalarRectangularMatrix mat(3, 3);
-
-        mat(0,0) = t.xx(); mat(0,1) = t.xy(); mat(0,2) = t.xz();
-        mat(1,0) = t.yx(); mat(1,1) = t.yy(); mat(1,2) = t.yz();
-        mat(2,0) = t.zx(); mat(2,1) = t.zy(); mat(2,2) = t.zz();
-
-        mat = SVDinv(mat);
-
-        return tensor
-        (
-            mat(0,0), mat(0,1), mat(0,2),
-            mat(1,0), mat(1,1), mat(1,2),
-            mat(2,0), mat(2,1), mat(2,2)
-        );
+        return SVD::pinv(t);
     }
 
     return Foam::inv(t, detval);