Documentation 6b54b78464
Loading...
Searching...
No Matches
CMatrixInverse.hpp
Go to the documentation of this file.
1/*!
2 * \file CMatrixInverse.hpp
3 * \brief Dense small-matrix inversion via Gauss-Jordan elimination, shared between the host
4 * (CSysMatrix::MatrixInverse) and device (CSysPreconditionerGPU.cu) implementations.
5 * \author F. Palacios, A. Bueno, T. Economon, P. Gomes
6 * \version 8.5.0 "Harrier"
7 *
8 * SU2 Project Website: https://su2code.github.io
9 *
10 * The SU2 Project is maintained by the SU2 Foundation
11 * (http://su2foundation.org)
12 *
13 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
14 *
15 * SU2 is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * SU2 is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
27 */
28
29#pragma once
30
31#include <cmath>
32
33#include "../code_config.hpp"
34
35namespace SU2_LinAlg {
36
37/*!
38 * \brief Regularize a pivot that is too small to prevent divide-by-zero, on host and device
39 * this needs to clamp to the same value so that the two produce the same factors.
40 */
41template <class ScalarType>
42SU2_CUDA_HOST_DEVICE inline void RegularizePivot(ScalarType& pivot) {
43 const float eps = 1e-12;
44#ifdef __CUDA_ARCH__
45 if (fabs(pivot) < eps) pivot = copysign(ScalarType(eps), pivot);
46#else
47 if (std::abs(pivot) < eps) pivot = std::copysign(ScalarType(eps), pivot);
48#endif
49}
50
51/*!
52 * \brief Invert the \p nVar by \p nVar dense matrix \p matrix into \p inverse via Gauss-Jordan
53 * elimination with partial pivoting on the diagonal.
54 * \note \p matrix is used as scratch space and destroyed, \p inverse must not alias it.
55 */
56template <class ScalarType>
57SU2_CUDA_HOST_DEVICE inline void MatrixInverse(unsigned long nVar, ScalarType* matrix, ScalarType* inverse) {
58#define A(I, J) matrix[(I)*nVar + (J)]
59#define M(I, J) inverse[(I)*nVar + (J)]
60
61 /*--- Initialize the inverse with the identity. ---*/
62 for (auto iVar = 0ul; iVar < nVar; iVar++)
63 for (auto jVar = 0ul; jVar < nVar; jVar++) M(iVar, jVar) = ScalarType(iVar == jVar);
64
65 /*--- Transform system in Upper Matrix. ---*/
66 for (auto iVar = 1ul; iVar < nVar; iVar++) {
67 for (auto jVar = 0ul; jVar < iVar; jVar++) {
68 RegularizePivot(A(jVar, jVar));
69
70 const ScalarType weight = A(iVar, jVar) / A(jVar, jVar);
71 for (auto kVar = jVar; kVar < nVar; kVar++) A(iVar, kVar) -= weight * A(jVar, kVar);
72
73 /*--- At this stage M is lower triangular so not all cols need updating. ---*/
74 for (auto kVar = 0ul; kVar <= jVar; kVar++) M(iVar, kVar) -= weight * M(jVar, kVar);
75 }
76 }
77
78 /*--- Backwards substitution. ---*/
79 for (auto iVar = nVar; iVar > 0ul;) {
80 iVar--; // unsigned type
81 for (auto jVar = iVar + 1; jVar < nVar; jVar++)
82 for (auto kVar = 0ul; kVar < nVar; kVar++) M(iVar, kVar) -= A(iVar, jVar) * M(jVar, kVar);
83
84 RegularizePivot(A(iVar, iVar));
85
86 for (auto kVar = 0ul; kVar < nVar; kVar++) M(iVar, kVar) /= A(iVar, iVar);
87 }
88
89#undef A
90#undef M
91}
92
93} // namespace SU2_LinAlg
#define M(I, J)
#define A(I, J)
#define SU2_CUDA_HOST_DEVICE
Definition code_config.hpp:57
Definition CMatrixInverse.hpp:35
void MatrixInverse(unsigned long nVar, ScalarType *matrix, ScalarType *inverse)
Invert the nVar by nVar dense matrix matrix into inverse via Gauss-Jordan elimination with partial pi...
Definition CMatrixInverse.hpp:57
void RegularizePivot(ScalarType &pivot)
Regularize a pivot that is too small to prevent divide-by-zero, on host and device this needs to clam...
Definition CMatrixInverse.hpp:42