1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 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 "GaussSeidelSmoother.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 defineTypeNameAndDebug(GaussSeidelSmoother, 0);
35 lduMatrix::smoother::addsymMatrixConstructorToTable<GaussSeidelSmoother>
36 addGaussSeidelSmootherSymMatrixConstructorToTable_;
38 lduMatrix::smoother::addasymMatrixConstructorToTable<GaussSeidelSmoother>
39 addGaussSeidelSmootherAsymMatrixConstructorToTable_;
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
45 Foam::GaussSeidelSmoother::GaussSeidelSmoother
47 const word& fieldName,
48 const lduMatrix& matrix,
49 const FieldField<Field, scalar>& interfaceBouCoeffs,
50 const FieldField<Field, scalar>& interfaceIntCoeffs,
51 const lduInterfaceFieldPtrsList& interfaces
65 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
67 void Foam::GaussSeidelSmoother::smooth
69 const word& fieldName_,
71 const lduMatrix& matrix_,
72 const scalarField& source,
73 const FieldField<Field, scalar>& interfaceBouCoeffs_,
74 const lduInterfaceFieldPtrsList& interfaces_,
79 register scalar* __restrict__ psiPtr = psi.begin();
81 register const label nCells = psi.size();
83 scalarField bPrime(nCells);
84 register scalar* __restrict__ bPrimePtr = bPrime.begin();
86 register const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
87 register const scalar* const __restrict__ upperPtr =
88 matrix_.upper().begin();
89 register const scalar* const __restrict__ lowerPtr =
90 matrix_.lower().begin();
92 register const label* const __restrict__ uPtr =
93 matrix_.lduAddr().upperAddr().begin();
95 register const label* const __restrict__ ownStartPtr =
96 matrix_.lduAddr().ownerStartAddr().begin();
99 // Parallel boundary initialisation. The parallel boundary is treated
100 // as an effective jacobi interface in the boundary.
101 // Note: there is a change of sign in the coupled
102 // interface update. The reason for this is that the
103 // internal coefficients are all located at the l.h.s. of
104 // the matrix whereas the "implicit" coefficients on the
105 // coupled boundaries are all created as if the
106 // coefficient contribution is of a source-kind (i.e. they
107 // have a sign as if they are on the r.h.s. of the matrix.
108 // To compensate for this, it is necessary to turn the
109 // sign of the contribution.
111 FieldField<Field, scalar> mBouCoeffs(interfaceBouCoeffs_.size());
113 forAll(mBouCoeffs, patchi)
115 if (interfaces_.set(patchi))
117 mBouCoeffs.set(patchi, -interfaceBouCoeffs_[patchi]);
121 for (label sweep=0; sweep<nSweeps; sweep++)
125 matrix_.initMatrixInterfaces
134 matrix_.updateMatrixInterfaces
143 register scalar curPsi;
144 register label fStart;
145 register label fEnd = ownStartPtr[0];
147 for (register label cellI=0; cellI<nCells; cellI++)
149 #ifdef ICC_IA64_PREFETCH
150 __builtin_prefetch (&psiPtr[cellI+64],0,1);
151 __builtin_prefetch (&bPrimePtr[cellI+64],0,1);
152 __builtin_prefetch (&ownStartPtr[cellI+64],0,1);
153 __builtin_prefetch (&diagPtr[cellI+64],0,1);
154 __builtin_prefetch (&uPtr[ownStartPtr[cellI+24]],0,1);
155 __builtin_prefetch (&uPtr[ownStartPtr[cellI+25]],0,1);
156 __builtin_prefetch (&uPtr[ownStartPtr[cellI+26]],0,1);
157 __builtin_prefetch (&uPtr[ownStartPtr[cellI+27]],0,1);
158 __builtin_prefetch (&upperPtr[ownStartPtr[cellI+24]],0,1);
159 __builtin_prefetch (&lowerPtr[ownStartPtr[cellI+24]],0,1);
162 // Start and end of this row
164 fEnd = ownStartPtr[cellI + 1];
166 // Get the accumulated neighbour side
167 curPsi = bPrimePtr[cellI];
169 // Accumulate the owner product side
170 for (register label curFace=fStart; curFace<fEnd; curFace++)
172 curPsi -= upperPtr[curFace]*psiPtr[uPtr[curFace]];
175 // Finish current psi
176 curPsi /= diagPtr[cellI];
178 // Distribute the neighbour side using current psi
179 for (register label curFace=fStart; curFace<fEnd; curFace++)
181 bPrimePtr[uPtr[curFace]] -= lowerPtr[curFace]*curPsi;
184 psiPtr[cellI] = curPsi;
190 void Foam::GaussSeidelSmoother::smooth
193 const scalarField& source,
194 const direction cmpt,
212 // ************************************************************************* //