1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | 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/>.
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 fine mesh diagonal
49 scalarField& coarseDiag = coarseMatrix.diag();
50 agglomeration_.restrictField
57 // Get reference to fine-level interfaces
58 const lduInterfaceFieldPtrsList& fineInterfaces =
59 interfaceLevel(fineLevelIndex);
61 // Get reference to fine-level boundary coefficients
62 const FieldField<Field, scalar>& fineInterfaceBouCoeffs =
63 coupleBouCoeffsLevel(fineLevelIndex);
65 // Get reference to fine-level internal coefficients
66 const FieldField<Field, scalar>& fineInterfaceIntCoeffs =
67 coupleIntCoeffsLevel(fineLevelIndex);
70 // Create coarse-level interfaces
74 new lduInterfaceFieldPtrsList(fineInterfaces.size())
77 lduInterfaceFieldPtrsList& coarseInterfaces =
78 interfaceLevels_[fineLevelIndex];
80 // Set coarse-level boundary coefficients
81 coupleLevelsBouCoeffs_.set
84 new FieldField<Field, scalar>(fineInterfaces.size())
86 FieldField<Field, scalar>& coarseInterfaceBouCoeffs =
87 coupleLevelsBouCoeffs_[fineLevelIndex];
89 // Set coarse-level internal coefficients
90 coupleLevelsIntCoeffs_.set
93 new FieldField<Field, scalar>(fineInterfaces.size())
95 FieldField<Field, scalar>& coarseInterfaceIntCoeffs =
96 coupleLevelsIntCoeffs_[fineLevelIndex];
98 // Add the coarse level
99 forAll (fineInterfaces, inti)
101 if (fineInterfaces.set(inti))
103 const GAMGInterface& coarseInterface =
104 refCast<const GAMGInterface>
106 agglomeration_.interfaceLevel(fineLevelIndex + 1)[inti]
112 GAMGInterfaceField::New
119 coarseInterfaceBouCoeffs.set
122 coarseInterface.agglomerateCoeffs(fineInterfaceBouCoeffs[inti])
125 coarseInterfaceIntCoeffs.set
128 coarseInterface.agglomerateCoeffs(fineInterfaceIntCoeffs[inti])
134 // Check if matrix is assymetric and if so agglomerate both upper and lower
136 if (fineMatrix.hasLower())
138 // Get off-diagonal matrix coefficients
139 const scalarField& fineUpper = fineMatrix.upper();
140 const scalarField& fineLower = fineMatrix.lower();
142 // Coarse matrix upper coefficients
143 scalarField& coarseUpper = coarseMatrix.upper();
144 scalarField& coarseLower = coarseMatrix.lower();
146 const labelList& restrictAddr =
147 agglomeration_.restrictAddressing(fineLevelIndex);
149 const unallocLabelList& l = fineMatrix.lduAddr().lowerAddr();
150 const unallocLabelList& cl = coarseMatrix.lduAddr().lowerAddr();
151 const unallocLabelList& cu = coarseMatrix.lduAddr().upperAddr();
153 forAll(faceRestrictAddr, fineFacei)
155 label cFace = faceRestrictAddr[fineFacei];
159 // Check the orientation of the fine-face relative to the
160 // coarse face it is being agglomerated into
161 if (cl[cFace] == restrictAddr[l[fineFacei]])
163 coarseUpper[cFace] += fineUpper[fineFacei];
164 coarseLower[cFace] += fineLower[fineFacei];
166 else if (cu[cFace] == restrictAddr[l[fineFacei]])
168 coarseUpper[cFace] += fineLower[fineFacei];
169 coarseLower[cFace] += fineUpper[fineFacei];
175 "GAMGSolver::agglomerateMatrix(const label)"
176 ) << "Inconsistent addressing between "
177 "fine and coarse grids"
183 // Add the fine face coefficients into the diagonal.
184 coarseDiag[-1 - cFace] +=
185 fineUpper[fineFacei] + fineLower[fineFacei];
189 else // ... Otherwise it is symmetric so agglomerate just the upper
191 // Get off-diagonal matrix coefficients
192 const scalarField& fineUpper = fineMatrix.upper();
194 // Coarse matrix upper coefficients
195 scalarField& coarseUpper = coarseMatrix.upper();
197 forAll(faceRestrictAddr, fineFacei)
199 label cFace = faceRestrictAddr[fineFacei];
203 coarseUpper[cFace] += fineUpper[fineFacei];
207 // Add the fine face coefficient into the diagonal.
208 coarseDiag[-1 - cFace] += 2*fineUpper[fineFacei];
215 // ************************************************************************* //