1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2010 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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "GAMGSolver.H"
27 #include "GAMGInterfaceField.H"
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 void Foam::GAMGSolver::agglomerateMatrix(const label fineLevelIndex)
34 const lduMatrix& fineMatrix = matrixLevel(fineLevelIndex);
36 // Set the coarse level matrix
40 new lduMatrix(agglomeration_.meshLevel(fineLevelIndex + 1))
42 lduMatrix& coarseMatrix = matrixLevels_[fineLevelIndex];
44 // Get face restriction map for current level
45 const labelList& faceRestrictAddr =
46 agglomeration_.faceRestrictAddressing(fineLevelIndex);
48 // Coarse matrix diagonal initialised by restricting the finer mesh diagonal
49 scalarField& coarseDiag = coarseMatrix.diag();
50 agglomeration_.restrictField(coarseDiag, fineMatrix.diag(), fineLevelIndex);
52 // Get reference to fine-level interfaces
53 const lduInterfaceFieldPtrsList& fineInterfaces =
54 interfaceLevel(fineLevelIndex);
56 // Get reference to fine-level boundary coefficients
57 const FieldField<Field, scalar>& fineInterfaceBouCoeffs =
58 interfaceBouCoeffsLevel(fineLevelIndex);
60 // Get reference to fine-level internal coefficients
61 const FieldField<Field, scalar>& fineInterfaceIntCoeffs =
62 interfaceIntCoeffsLevel(fineLevelIndex);
65 // Create coarse-level interfaces
69 new lduInterfaceFieldPtrsList(fineInterfaces.size())
72 lduInterfaceFieldPtrsList& coarseInterfaces =
73 interfaceLevels_[fineLevelIndex];
75 // Set coarse-level boundary coefficients
76 interfaceLevelsBouCoeffs_.set
79 new FieldField<Field, scalar>(fineInterfaces.size())
81 FieldField<Field, scalar>& coarseInterfaceBouCoeffs =
82 interfaceLevelsBouCoeffs_[fineLevelIndex];
84 // Set coarse-level internal coefficients
85 interfaceLevelsIntCoeffs_.set
88 new FieldField<Field, scalar>(fineInterfaces.size())
90 FieldField<Field, scalar>& coarseInterfaceIntCoeffs =
91 interfaceLevelsIntCoeffs_[fineLevelIndex];
93 // Add the coarse level
94 forAll(fineInterfaces, inti)
96 if (fineInterfaces.set(inti))
98 const GAMGInterface& coarseInterface =
99 refCast<const GAMGInterface>
101 agglomeration_.interfaceLevel(fineLevelIndex + 1)[inti]
107 GAMGInterfaceField::New
114 coarseInterfaceBouCoeffs.set
117 coarseInterface.agglomerateCoeffs(fineInterfaceBouCoeffs[inti])
120 coarseInterfaceIntCoeffs.set
123 coarseInterface.agglomerateCoeffs(fineInterfaceIntCoeffs[inti])
129 // Check if matrix is assymetric and if so agglomerate both upper and lower
131 if (fineMatrix.hasLower())
133 // Get off-diagonal matrix coefficients
134 const scalarField& fineUpper = fineMatrix.upper();
135 const scalarField& fineLower = fineMatrix.lower();
137 // Coarse matrix upper coefficients
138 scalarField& coarseUpper = coarseMatrix.upper();
139 scalarField& coarseLower = coarseMatrix.lower();
141 const labelList& restrictAddr =
142 agglomeration_.restrictAddressing(fineLevelIndex);
144 const labelUList& l = fineMatrix.lduAddr().lowerAddr();
145 const labelUList& cl = coarseMatrix.lduAddr().lowerAddr();
146 const labelUList& cu = coarseMatrix.lduAddr().upperAddr();
148 forAll(faceRestrictAddr, fineFacei)
150 label cFace = faceRestrictAddr[fineFacei];
154 // Check the orientation of the fine-face relative to the
155 // coarse face it is being agglomerated into
156 if (cl[cFace] == restrictAddr[l[fineFacei]])
158 coarseUpper[cFace] += fineUpper[fineFacei];
159 coarseLower[cFace] += fineLower[fineFacei];
161 else if (cu[cFace] == restrictAddr[l[fineFacei]])
163 coarseUpper[cFace] += fineLower[fineFacei];
164 coarseLower[cFace] += fineUpper[fineFacei];
170 "GAMGSolver::agglomerateMatrix(const label)"
171 ) << "Inconsistent addressing between "
172 "fine and coarse grids"
178 // Add the fine face coefficients into the diagonal.
179 coarseDiag[-1 - cFace] +=
180 fineUpper[fineFacei] + fineLower[fineFacei];
184 else // ... Otherwise it is symmetric so agglomerate just the upper
186 // Get off-diagonal matrix coefficients
187 const scalarField& fineUpper = fineMatrix.upper();
189 // Coarse matrix upper coefficients
190 scalarField& coarseUpper = coarseMatrix.upper();
192 forAll(faceRestrictAddr, fineFacei)
194 label cFace = faceRestrictAddr[fineFacei];
198 coarseUpper[cFace] += fineUpper[fineFacei];
202 // Add the fine face coefficient into the diagonal.
203 coarseDiag[-1 - cFace] += 2*fineUpper[fineFacei];
210 // ************************************************************************* //