1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2007 H. Jasak All rights reserved
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 Reduced Rank Extrapolation Algebraic Multigrid solver with run-time
27 selection of policy and cycle
30 Hrvoje Jasak, Wikki Ltd. All rights reserved
32 \*---------------------------------------------------------------------------*/
34 #include "rreAmgSolver.H"
35 #include "scalarMatrices.H"
36 #include "DenseMatrixTools.H"
37 #include "FieldFields.H"
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 defineTypeNameAndDebug(rreAmgSolver, 0);
46 lduSolver::addsymMatrixConstructorToTable<rreAmgSolver>
47 addrreAmgSolverSymMatrixConstructorToTable_;
49 lduSolver::addasymMatrixConstructorToTable<rreAmgSolver>
50 addrreAmgSolverAsymMatrixConstructorToTable_;
54 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
56 //- Construct from matrix and solver data stream
57 Foam::rreAmgSolver::rreAmgSolver
59 const word& fieldName,
60 const lduMatrix& matrix,
61 const FieldField<Field, scalar>& coupleBouCoeffs,
62 const FieldField<Field, scalar>& coupleIntCoeffs,
63 const lduInterfaceFieldPtrsList& interfaces,
64 const dictionary& dict
84 kDimension_(readLabel(dict.lookup("kDimension")))
88 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
90 Foam::lduSolverPerformance Foam::rreAmgSolver::solve
97 // Prepare solver performance
98 lduSolverPerformance solverPerf(typeName, fieldName());
100 scalar normFactor = this->normFactor(x, b, cmpt);
102 // Calculate initial residual
103 solverPerf.initialResidual() =
104 gSumMag(amg_.residual(x, b, cmpt))/normFactor;
106 solverPerf.finalResidual() = solverPerf.initialResidual();
109 typedef FieldField<Field, scalar> scalarFieldField;
111 scalarFieldField xSave(kDimension_ + 1);
115 xSave.set(i, new scalarField(x.size()));
118 scalarFieldField xSecondDiffs(kDimension_ - 1);
120 forAll (xSecondDiffs, i)
122 xSecondDiffs.set(i, new scalarField(x.size()));
125 scalarField xRhs(x.size());
128 scalarSquareMatrix AN(kDimension_ - 1);
129 scalarField xN(kDimension_ - 1);
130 scalarField bN(kDimension_ - 1);
132 // Remember last extrapolation index
133 label lastExtrapolation = kDimension_;
138 if (!stop(solverPerf))
140 scalarField psiSave(x.size());
144 amg_.cycle(x, b, cmpt);
146 label curIndex = (solverPerf.nIterations()) % (kDimension_ + 1);
153 solverPerf.nIterations() >= lastExtrapolation
154 && curIndex == kDimension_
159 // Calculate first differences
160 for (label i = 0; i < kDimension_; i++)
162 xSave[i] = xSave[i + 1] - xSave[i];
165 // Calculate second differences
166 for (label i = 0; i < kDimension_ - 1; i++)
168 xSecondDiffs[i] = xSave[i + 1] - xSave[i];
171 // Perform Q-R decomposition
172 DenseMatrixTools::qrDecompose
179 // Solve the normal system
180 for (label i = 0; i < kDimension_ - 1; i++)
182 bN[i] = -gSum(xSecondDiffs[i]*xSave[0]);
185 DenseMatrixTools::solve(AN, xN, bN);
187 // Re-asemble the solution
189 for (label i = 0; i < kDimension_ - 1; i++)
194 // Increment last extrapolation
195 lastExtrapolation = solverPerf.nIterations() + kDimension_;
198 // Re-calculate residual
199 solverPerf.finalResidual() =
200 gSumMag(amg_.residual(x, b, cmpt))/normFactor;
201 solverPerf.nIterations()++;
202 } while (!stop(solverPerf));
209 // ************************************************************************* //