1 /*---------------------------------------------------------------------------*\
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 -------------------------------------------------------------------------------
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/>.
28 Symmetric Gauss-Seidel preconditioning
31 Hrvoje Jasak, Wikki Ltd. All rights reserved
33 \*---------------------------------------------------------------------------*/
35 #include "symGaussSeidelPrecon.H"
36 #include "addToRunTimeSelectionTable.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 defineTypeNameAndDebug(symGaussSeidelPrecon, 0);
45 addsymMatrixConstructorToTable<symGaussSeidelPrecon>
46 addsymGaussSeidelPreconditionerSymMatrixConstructorToTable_;
49 addasymMatrixConstructorToTable<symGaussSeidelPrecon>
50 addsymGaussSeidelPreconditionerAsymMatrixConstructorToTable_;
54 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
56 Foam::symGaussSeidelPrecon::symGaussSeidelPrecon
58 const lduMatrix& matrix,
59 const FieldField<Field, scalar>& coupleBouCoeffs,
60 const FieldField<Field, scalar>& coupleIntCoeffs,
61 const lduInterfaceFieldPtrsList& interfaces
71 bPrime_(matrix.lduAddr().size())
75 Foam::symGaussSeidelPrecon::symGaussSeidelPrecon
77 const lduMatrix& matrix,
78 const FieldField<Field, scalar>& coupleBouCoeffs,
79 const FieldField<Field, scalar>& coupleIntCoeffs,
80 const lduInterfaceFieldPtrsList& interfaces,
81 const dictionary& dict
91 bPrime_(matrix.lduAddr().size())
95 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
97 void Foam::symGaussSeidelPrecon::precondition
100 const scalarField& b,
104 // Execute preconditioning
105 if (matrix_.diagonal())
107 x = b/matrix_.diag();
109 else if (matrix_.symmetric() || matrix_.asymmetric())
111 scalar* __restrict__ xPtr = x.begin();
113 const scalar* __restrict__ diagPtr = matrix_.diag().begin();
115 scalar* __restrict__ bPrimePtr = bPrime_.begin();
117 const label* const __restrict__ uPtr =
118 matrix_.lduAddr().upperAddr().begin();
120 const label* const __restrict__ ownStartPtr =
121 matrix_.lduAddr().ownerStartAddr().begin();
123 const scalar* const __restrict__ lowerPtr = matrix_.lower().begin();
124 const scalar* const __restrict__ upperPtr = matrix_.upper().begin();
126 const label nRows = x.size();
132 // Coupled boundary update
134 matrix_.initMatrixInterfaces
141 true // switch to lhs of system
144 matrix_.updateMatrixInterfaces
151 true // switch to lhs of system
156 for (register label rowI = 0; rowI < nRows; rowI++)
158 // lRow is equal to rowI
159 scalar& curX = xPtr[rowI];
161 // Grab the accumulated neighbour side
162 curX = bPrimePtr[rowI];
164 // Start and end of this row
165 fStart = ownStartPtr[rowI];
166 fEnd = ownStartPtr[rowI + 1];
168 // Accumulate the owner product side
169 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
171 curX -= upperPtr[curCoeff]*xPtr[uPtr[curCoeff]];
175 curX /= diagPtr[rowI];
177 // Distribute the neighbour side using current x
178 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
180 bPrimePtr[uPtr[curCoeff]] -= lowerPtr[curCoeff]*curX;
185 for (register label rowI = nRows - 1; rowI >= 0; rowI--)
187 // lRow is equal to rowI
188 scalar& curX = xPtr[rowI];
190 // Grab the accumulated neighbour side
191 curX = bPrimePtr[rowI];
193 // Start and end of this row
194 fStart = ownStartPtr[rowI];
195 fEnd = ownStartPtr[rowI + 1];
197 // Accumulate the owner product side
198 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
200 curX -= upperPtr[curCoeff]*xPtr[uPtr[curCoeff]];
204 curX /= diagPtr[rowI];
206 // No need to update bPrime on reverse sweep. VV, 20/May/2015.
212 void Foam::symGaussSeidelPrecon::preconditionT
215 const scalarField& b,
219 // Execute preconditioning
220 if (matrix_.diagonal())
222 x = b/matrix_.diag();
224 else if (matrix_.symmetric() || matrix_.asymmetric())
226 scalar* __restrict__ xPtr = x.begin();
228 const scalar* __restrict__ diagPtr = matrix_.diag().begin();
230 scalar* __restrict__ bPrimePtr = bPrime_.begin();
232 const label* const __restrict__ uPtr =
233 matrix_.lduAddr().upperAddr().begin();
235 const label* const __restrict__ ownStartPtr =
236 matrix_.lduAddr().ownerStartAddr().begin();
238 const scalar* const __restrict__ lowerPtr = matrix_.lower().begin();
239 const scalar* const __restrict__ upperPtr = matrix_.upper().begin();
241 const label nRows = x.size();
247 // Coupled boundary update
249 matrix_.initMatrixInterfaces
256 true // switch to lhs of system
259 matrix_.updateMatrixInterfaces
266 true // switch to lhs of system
271 for (register label rowI = 0; rowI < nRows; rowI++)
273 // lRow is equal to rowI
274 scalar& curX = xPtr[rowI];
276 // Grab the accumulated neighbour side
277 curX = bPrimePtr[rowI];
279 // Start and end of this row
280 fStart = ownStartPtr[rowI];
281 fEnd = ownStartPtr[rowI + 1];
283 // Accumulate the owner product side
284 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
286 // Transpose multiplication. HJ, 10/Jul/2007
287 curX -= lowerPtr[curCoeff]*xPtr[uPtr[curCoeff]];
291 curX /= diagPtr[rowI];
293 // Distribute the neighbour side using current x
294 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
296 // Transpose multiplication. HJ, 10/Jul/2007
297 bPrimePtr[uPtr[curCoeff]] -= upperPtr[curCoeff]*curX;
302 for (register label rowI = nRows - 1; rowI >= 0; rowI--)
304 // lRow is equal to rowI
305 scalar& curX = xPtr[rowI];
307 // Grab the accumulated neighbour side
308 curX = bPrimePtr[rowI];
310 // Start and end of this row
311 fStart = ownStartPtr[rowI];
312 fEnd = ownStartPtr[rowI + 1];
314 // Accumulate the owner product side
315 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
317 // Transpose multiplication. HJ, 10/Jul/2007
318 curX -= lowerPtr[curCoeff]*xPtr[uPtr[curCoeff]];
322 curX /= diagPtr[rowI];
324 // No need to update bPrime on reverse sweep. VV, 20/May/2015.
330 // ************************************************************************* //