Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / matrices / scalarMatrices / scalarSquareMatrix.C
blob073c1015427a115f193c6ae42cbba576f8915995
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend 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 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "scalarSquareMatrix.H"
28 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
30 Foam::scalarSquareMatrix::scalarSquareMatrix()
34 Foam::scalarSquareMatrix::scalarSquareMatrix(const label mSize)
36     SquareMatrix<scalar>(mSize, 0.0)
40 Foam::scalarSquareMatrix::scalarSquareMatrix
42     const label mSize,
43     const scalar v
46     SquareMatrix<scalar>(mSize, v)
50 Foam::scalarSquareMatrix::scalarSquareMatrix(const scalarSquareMatrix& matrix)
52     SquareMatrix<scalar>(matrix)
56 Foam::scalarSquareMatrix::scalarSquareMatrix(Istream& is)
58     SquareMatrix<scalar>(is)
62 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
64 void Foam::scalarSquareMatrix::LUDecompose
66     scalarSquareMatrix& matrix,
67     labelList& pivotIndices
70     label n = matrix.n();
71     scalar vv[n];
73     for (register label i=0; i<n; i++)
74     {
75         scalar largestCoeff = 0.0;
76         scalar temp;
77         const scalar* __restrict__ matrixi = matrix[i];
79         for (register label j=0; j<n; j++)
80         {
81             if ((temp = mag(matrixi[j])) > largestCoeff)
82             {
83                 largestCoeff = temp;
84             }
85         }
87         if (largestCoeff == 0.0)
88         {
89             FatalErrorIn
90             (
91                 "scalarSquareMatrix::LUdecompose"
92                 "(scalarSquareMatrix& matrix, labelList& rowIndices)"
93             )   << "Singular matrix" << exit(FatalError);
94         }
96         vv[i] = 1.0/largestCoeff;
97     }
99     for (register label j=0; j<n; j++)
100     {
101         scalar* __restrict__ matrixj = matrix[j];
103         for (register label i=0; i<j; i++)
104         {
105             scalar* __restrict__ matrixi = matrix[i];
107             scalar sum = matrixi[j];
108             for (register label k=0; k<i; k++)
109             {
110                 sum -= matrixi[k]*matrix[k][j];
111             }
112             matrixi[j] = sum;
113         }
115         label iMax = 0;
117         scalar largestCoeff = 0.0;
118         for (register label i=j; i<n; i++)
119         {
120             scalar* __restrict__ matrixi = matrix[i];
121             scalar sum = matrixi[j];
123             for (register label k=0; k<j; k++)
124             {
125                 sum -= matrixi[k]*matrix[k][j];
126             }
128             matrixi[j] = sum;
130             scalar temp;
131             if ((temp = vv[i]*mag(sum)) >= largestCoeff)
132             {
133                 largestCoeff = temp;
134                 iMax = i;
135             }
136         }
138         pivotIndices[j] = iMax;
140         if (j != iMax)
141         {
142             scalar* __restrict__ matrixiMax = matrix[iMax];
144             for (register label k=0; k<n; k++)
145             {
146                 Swap(matrixj[k], matrixiMax[k]);
147             }
149             vv[iMax] = vv[j];
150         }
152         if (matrixj[j] == 0.0)
153         {
154             matrixj[j] = SMALL;
155         }
157         if (j != n-1)
158         {
159             scalar rDiag = 1.0/matrixj[j];
161             for (register label i=j+1; i<n; i++)
162             {
163                 matrix[i][j] *= rDiag;
164             }
165         }
166     }
170 Foam::scalarSquareMatrix Foam::scalarSquareMatrix::LUinvert() const
172     scalarSquareMatrix luMatrix = *this;
174     scalarSquareMatrix luInvert(luMatrix.n());
175     scalarField column(luMatrix.n());
177     labelList pivotIndices(luMatrix.n());
179     LUDecompose(luMatrix, pivotIndices);
181     for (label j = 0; j < luMatrix.n(); j++)
182     {
183         for (label i = 0; i < luMatrix.n(); i++)
184         {
185             column[i] = 0.0;
186         }
188         column[j] = 1.0;
190         LUBacksubstitute(luMatrix, pivotIndices, column);
192         for (label i = 0; i < luMatrix.n(); i++)
193         {
194             luInvert[i][j] = column[i];
195         }
196     }
198     return luInvert;
202 // ************************************************************************* //