1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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
26 coupledGaussSeidelPrecon
29 GaussSeidel preconditioning
32 Hrvoje Jasak, Wikki Ltd. All rights reserved.
34 \*----------------------------------------------------------------------------*/
36 #include "coupledGaussSeidelPrecon.H"
37 #include "addToRunTimeSelectionTable.H"
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 defineTypeNameAndDebug(coupledGaussSeidelPrecon, 0);
45 addToRunTimeSelectionTable
48 coupledGaussSeidelPrecon,
54 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
56 void Foam::coupledGaussSeidelPrecon::forwardSweep
58 const lduMatrix& matrix,
63 const scalarField& diag = matrix.diag();
64 const scalarField& lower = matrix.lower();
65 const scalarField& upper = matrix.upper();
67 const labelList& upperAddr = matrix.lduAddr().upperAddr();
68 const labelList& ownStartAddr = matrix.lduAddr().ownerStartAddr();
70 const label nRows = x.size();
73 for (register label rowI = 0; rowI < nRows; rowI++)
75 // lRow is equal to rowI
76 scalar& curX = x[rowI];
78 // Grab the accumulated neighbour side
81 // Start and end of this row
82 fStart = ownStartAddr[rowI];
83 fEnd = ownStartAddr[rowI + 1];
85 // Accumulate the owner product side
86 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
88 curX -= upper[curCoeff]*x[upperAddr[curCoeff]];
94 // Distribute the neighbour side using current x
95 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
97 bPrime[upperAddr[curCoeff]] -= lower[curCoeff]*curX;
103 void Foam::coupledGaussSeidelPrecon::reverseSweep
105 const lduMatrix& matrix,
110 const scalarField& diag = matrix.diag();
111 const scalarField& lower = matrix.lower();
112 const scalarField& upper = matrix.upper();
114 const labelList& upperAddr = matrix.lduAddr().upperAddr();
115 const labelList& ownStartAddr = matrix.lduAddr().ownerStartAddr();
117 const label nRows = x.size();
120 for (register label rowI = nRows - 1; rowI >= 0; rowI--)
122 // lRow is equal to rowI
123 scalar& curX = x[rowI];
125 // Grab the accumulated neighbour side
128 // Start and end of this row
129 fStart = ownStartAddr[rowI];
130 fEnd = ownStartAddr[rowI + 1];
132 // Accumulate the owner product side
133 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
135 curX -= upper[curCoeff]*x[upperAddr[curCoeff]];
141 // Distribute the neighbour side using current x
142 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
144 bPrime[upperAddr[curCoeff]] -= lower[curCoeff]*curX;
150 void Foam::coupledGaussSeidelPrecon::forwardSweepTranspose
152 const lduMatrix& matrix,
157 const scalarField& diag = matrix.diag();
158 const scalarField& lower = matrix.lower();
159 const scalarField& upper = matrix.upper();
161 const labelList& upperAddr = matrix.lduAddr().upperAddr();
162 const labelList& ownStartAddr = matrix.lduAddr().ownerStartAddr();
164 const label nRows = x.size();
167 for (register label rowI = 0; rowI < nRows; rowI++)
169 // lRow is equal to rowI
170 scalar& curX = x[rowI];
172 // Grab the accumulated neighbour side
175 // Start and end of this row
176 fStart = ownStartAddr[rowI];
177 fEnd = ownStartAddr[rowI + 1];
179 // Accumulate the owner product side
180 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
182 // Transpose multiplication. HJ, 19/Jan/2009
183 curX -= lower[curCoeff]*x[upperAddr[curCoeff]];
189 // Distribute the neighbour side using current x
190 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
192 // Transpose multiplication. HJ, 19/Jan/2009
193 bPrime[upperAddr[curCoeff]] -= upper[curCoeff]*curX;
199 void Foam::coupledGaussSeidelPrecon::reverseSweepTranspose
201 const lduMatrix& matrix,
206 const scalarField& diag = matrix.diag();
207 const scalarField& lower = matrix.lower();
208 const scalarField& upper = matrix.upper();
210 const labelList& upperAddr = matrix.lduAddr().upperAddr();
211 const labelList& ownStartAddr = matrix.lduAddr().ownerStartAddr();
213 const label nRows = x.size();
216 for (register label rowI = nRows - 1; rowI >= 0; rowI--)
218 // lRow is equal to rowI
219 scalar& curX = x[rowI];
221 // Grab the accumulated neighbour side
224 // Start and end of this row
225 fStart = ownStartAddr[rowI];
226 fEnd = ownStartAddr[rowI + 1];
228 // Accumulate the owner product side
229 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
231 // Transpose multiplication. HJ, 19/Jan/2009
232 curX -= lower[curCoeff]*x[upperAddr[curCoeff]];
238 // Distribute the neighbour side using current x
239 for (register label curCoeff = fStart; curCoeff < fEnd; curCoeff++)
241 // Transpose multiplication. HJ, 19/Jan/2009
242 bPrime[upperAddr[curCoeff]] -= upper[curCoeff]*curX;
248 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
250 Foam::coupledGaussSeidelPrecon::coupledGaussSeidelPrecon
252 const coupledLduMatrix& matrix,
253 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
254 const PtrList<FieldField<Field, scalar> >& intCoeffs,
255 const lduInterfaceFieldPtrsListList& interfaces
265 mBouCoeffs_(bouCoeffs),
266 bPrime_(matrix.size())
268 // Invert boundary coefficients
269 forAll (mBouCoeffs_, rowI)
271 mBouCoeffs_[rowI] *= -1;
274 // Hook bPrime components
275 forAll (matrix_, rowI)
277 bPrime_.set(rowI, new scalarField(matrix_[rowI].lduAddr().size(), 0));
282 Foam::coupledGaussSeidelPrecon::coupledGaussSeidelPrecon
284 const coupledLduMatrix& matrix,
285 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
286 const PtrList<FieldField<Field, scalar> >& intCoeffs,
287 const lduInterfaceFieldPtrsListList& interfaces,
288 const dictionary& dict
298 mBouCoeffs_(bouCoeffs),
299 bPrime_(matrix.size())
301 // Invert boundary coefficients
302 forAll (mBouCoeffs_, rowI)
304 mBouCoeffs_[rowI] *= -1;
307 // Hook bPrime components
308 forAll (matrix_, rowI)
310 bPrime_.set(rowI, new scalarField(matrix_[rowI].lduAddr().size(), 0));
315 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
317 void Foam::coupledGaussSeidelPrecon::precondition
319 FieldField<Field, scalar>& x,
320 const FieldField<Field, scalar>& b,
324 // Execute preconditioning
325 if (matrix_.diagonal())
327 forAll (matrix_, rowI)
329 x[rowI] = b[rowI]/matrix_[rowI].diag();
332 else if (matrix_.symmetric() || matrix_.asymmetric())
336 // Parallel boundary update
338 matrix_.initMatrixInterfaces
347 matrix_.updateMatrixInterfaces
358 forAll (matrix_, rowI)
360 forwardSweep(matrix_[rowI], x[rowI], bPrime_[rowI]);
364 forAllReverse (matrix_, rowI)
366 reverseSweep(matrix_[rowI], x[rowI], bPrime_[rowI]);
372 void Foam::coupledGaussSeidelPrecon::preconditionT
374 FieldField<Field, scalar>& x,
375 const FieldField<Field, scalar>& b,
379 // Execute preconditioning
380 if (matrix_.diagonal())
382 forAll (matrix_, rowI)
384 x[rowI] = b[rowI]/matrix_[rowI].diag();
387 else if (matrix_.symmetric() || matrix_.asymmetric())
391 // Parallel boundary update
393 matrix_.initMatrixInterfaces
402 matrix_.updateMatrixInterfaces
413 forAll (matrix_, rowI)
415 forwardSweepTranspose(matrix_[rowI], x[rowI], bPrime_[rowI]);
419 forAllReverse (matrix_, rowI)
421 reverseSweepTranspose(matrix_[rowI], x[rowI], bPrime_[rowI]);
427 // ************************************************************************* //