1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "scalarMatrices.H"
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 void Foam::LUDecompose
34 scalarSquareMatrix& matrix,
35 labelList& pivotIndices
41 for (register label i=0; i<n; i++)
43 scalar largestCoeff = 0.0;
45 const scalar* __restrict__ matrixi = matrix[i];
47 for (register label j=0; j<n; j++)
49 if ((temp = mag(matrixi[j])) > largestCoeff)
55 if (largestCoeff == 0.0)
60 "(scalarSquareMatrix& matrix, labelList& rowIndices)"
61 ) << "Singular matrix" << exit(FatalError);
64 vv[i] = 1.0/largestCoeff;
67 for (register label j=0; j<n; j++)
69 scalar* __restrict__ matrixj = matrix[j];
71 for (register label i=0; i<j; i++)
73 scalar* __restrict__ matrixi = matrix[i];
75 scalar sum = matrixi[j];
76 for (register label k=0; k<i; k++)
78 sum -= matrixi[k]*matrix[k][j];
85 scalar largestCoeff = 0.0;
86 for (register label i=j; i<n; i++)
88 scalar* __restrict__ matrixi = matrix[i];
89 scalar sum = matrixi[j];
91 for (register label k=0; k<j; k++)
93 sum -= matrixi[k]*matrix[k][j];
99 if ((temp = vv[i]*mag(sum)) >= largestCoeff)
106 pivotIndices[j] = iMax;
110 scalar* __restrict__ matrixiMax = matrix[iMax];
112 for (register label k=0; k<n; k++)
114 Swap(matrixj[k], matrixiMax[k]);
120 if (matrixj[j] == 0.0)
127 scalar rDiag = 1.0/matrixj[j];
129 for (register label i=j+1; i<n; i++)
131 matrix[i][j] *= rDiag;
138 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
142 scalarRectangularMatrix& ans, // value changed in return
143 const scalarRectangularMatrix& A,
144 const scalarRectangularMatrix& B
152 "scalarRectangularMatrix& answer "
153 "const scalarRectangularMatrix& A, "
154 "const scalarRectangularMatrix& B)"
155 ) << "A and B must have identical inner dimensions but A.m = "
156 << A.m() << " and B.n = " << B.n()
157 << abort(FatalError);
160 ans = scalarRectangularMatrix(A.n(), B.m(), scalar(0));
162 for(register label i = 0; i < A.n(); i++)
164 for(register label j = 0; j < B.m(); j++)
166 for(register label l = 0; l < B.n(); l++)
168 ans[i][j] += A[i][l]*B[l][j];
177 scalarRectangularMatrix& ans, // value changed in return
178 const scalarRectangularMatrix& A,
179 const scalarRectangularMatrix& B,
180 const scalarRectangularMatrix& C
188 "const scalarRectangularMatrix& A, "
189 "const scalarRectangularMatrix& B, "
190 "const scalarRectangularMatrix& C, "
191 "scalarRectangularMatrix& answer)"
192 ) << "A and B must have identical inner dimensions but A.m = "
193 << A.m() << " and B.n = " << B.n()
194 << abort(FatalError);
202 "const scalarRectangularMatrix& A, "
203 "const scalarRectangularMatrix& B, "
204 "const scalarRectangularMatrix& C, "
205 "scalarRectangularMatrix& answer)"
206 ) << "B and C must have identical inner dimensions but B.m = "
207 << B.m() << " and C.n = " << C.n()
208 << abort(FatalError);
211 ans = scalarRectangularMatrix(A.n(), C.m(), scalar(0));
213 for(register label i = 0; i < A.n(); i++)
215 for(register label g = 0; g < C.m(); g++)
217 for(register label l = 0; l < C.n(); l++)
220 for(register label j = 0; j < A.m(); j++)
222 ab += A[i][j]*B[j][l];
224 ans[i][g] += C[l][g] * ab;
233 scalarRectangularMatrix& ans, // value changed in return
234 const scalarRectangularMatrix& A,
235 const DiagonalMatrix<scalar>& B,
236 const scalarRectangularMatrix& C
239 if (A.m() != B.size())
244 "const scalarRectangularMatrix& A, "
245 "const DiagonalMatrix<scalar>& B, "
246 "const scalarRectangularMatrix& C, "
247 "scalarRectangularMatrix& answer)"
248 ) << "A and B must have identical inner dimensions but A.m = "
249 << A.m() << " and B.n = " << B.size()
250 << abort(FatalError);
253 if (B.size() != C.n())
258 "const scalarRectangularMatrix& A, "
259 "const DiagonalMatrix<scalar>& B, "
260 "const scalarRectangularMatrix& C, "
261 "scalarRectangularMatrix& answer)"
262 ) << "B and C must have identical inner dimensions but B.m = "
263 << B.size() << " and C.n = " << C.n()
264 << abort(FatalError);
267 ans = scalarRectangularMatrix(A.n(), C.m(), scalar(0));
269 for(register label i = 0; i < A.n(); i++)
271 for(register label g = 0; g < C.m(); g++)
273 for(register label l = 0; l < C.n(); l++)
275 ans[i][g] += C[l][g] * A[i][l]*B[l];
282 Foam::RectangularMatrix<Foam::scalar> Foam::SVDinv
284 const scalarRectangularMatrix& A,
288 SVD svd(A, minCondition);
289 return svd.VSinvUt();
293 // ************************************************************************* //