1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
5 \\ / A nd | 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 Finest AMG level container, using matrix and field references
31 Klas Jareteg, 2013-04-15
33 \*---------------------------------------------------------------------------*/
35 #include "fineBlockAmgLevel.H"
36 #include "coarseBlockAmgLevel.H"
39 #include "BlockGaussSeidelSolver.H"
40 #include "BlockSolverPerformance.H"
41 #include "BlockCoeffNorm.H"
42 #include "BlockCoeffTwoNorm.H"
44 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 // Construct from components
48 Foam::fineBlockAmgLevel<Type>::fineBlockAmgLevel
50 const BlockLduMatrix<Type>& matrix,
51 const dictionary& dict,
52 const word& coarseningType,
53 const label groupSize,
54 const label minCoarseEqns,
55 const word& smootherType
62 BlockMatrixCoarsening<Type>::New
73 BlockLduSmoother<Type>::New
82 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
85 Foam::Field<Type>& Foam::fineBlockAmgLevel<Type>::x()
87 FatalErrorIn("Field<Type>& Foam::fineBlockAmgLevel<Type>::x()")
88 << "x is not available."
92 return const_cast<Field<Type>&>(Field<Type>::null());
97 Foam::Field<Type>& Foam::fineBlockAmgLevel<Type>::b()
99 FatalErrorIn("Field<Type>& Foam::fineBlockAmgLevel<Type>::b()")
100 << "b is not available."
101 << abort(FatalError);
104 return const_cast<Field<Type>&>(Field<Type>::null());
109 void Foam::fineBlockAmgLevel<Type>::residual
111 const Field<Type>& x,
112 const Field<Type>& b,
125 res[i] = b[i] - res[i];
131 void Foam::fineBlockAmgLevel<Type>::restrictResidual
133 const Field<Type>& x,
134 const Field<Type>& b,
135 Field<Type>& xBuffer,
136 Field<Type>& coarseRes,
142 // Calculate residual
143 residual(x, b, xBuffer);
146 // Here x != 0. It is assumed that the buffer will contain the residual
147 // if no pre-sweeps have been done. HJ, 4/Sep/2006
148 coarseningPtr_->restrictResidual(xBuffer, coarseRes);
153 void Foam::fineBlockAmgLevel<Type>::prolongateCorrection
156 const Field<Type>& coarseX
159 coarseningPtr_->prolongateCorrection(x, coarseX);
164 void Foam::fineBlockAmgLevel<Type>::smooth
167 const Field<Type>& b,
171 smootherPtr_->smooth(x, b, nSweeps);
176 void Foam::fineBlockAmgLevel<Type>::solve
179 const Field<Type>& b,
180 const scalar tolerance,
185 Info<<"Fine level solver"<<endl;
187 if (matrix_.symmetric())
189 BlockSolverPerformance<Type> coarseSolverPerf =
197 if (lduMatrix::debug >= 2)
199 coarseSolverPerf.print();
204 BlockSolverPerformance<Type> coarseSolverPerf =
205 BlockBiCGStabSolver<Type>
212 if (lduMatrix::debug >= 2)
214 coarseSolverPerf.print();
221 void Foam::fineBlockAmgLevel<Type>::scaleX
224 const Field<Type>& b,
229 // KRJ: 2013-02-05: Removed subfield, creating a new field
230 Field<Type> Ax(x.size());
234 reinterpret_cast<Field<Type>&>(Ax),
238 scalar scalingFactorNum = sumProd(x,b);
239 scalar scalingFactorDenom = sumProd(x,Ax);
241 vector scalingVector(scalingFactorNum, scalingFactorDenom, 0);
242 reduce(scalingVector, sumOp<vector>());
247 scalingVector[0]*scalingVector[1] <= 0
248 || mag(scalingVector[0]) < mag(scalingVector[1])
251 // Factor = 1.0, no scaling
253 else if (mag(scalingVector[0]) > 2*mag(scalingVector[1]))
261 x *= scalingVector[0]/stabilise(scalingVector[1], SMALL);
267 Foam::autoPtr<Foam::BlockAmgLevel<Type> >
268 Foam::fineBlockAmgLevel<Type>::makeNextLevel() const
270 if (coarseningPtr_->coarsen())
272 return autoPtr<Foam::BlockAmgLevel<Type> >
274 new coarseBlockAmgLevel<Type>
276 coarseningPtr_->restrictMatrix(),
278 coarseningPtr_->type(),
279 coarseningPtr_->groupSize(),
280 coarseningPtr_->minCoarseEqns(),
287 // Final level: cannot coarsen
288 return autoPtr<Foam::BlockAmgLevel<Type> >();
293 // ************************************************************************* //