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 "GAMGAgglomeration.H"
27 #include "GAMGInterface.H"
28 #include "FieldFields.H"
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 void Foam::GAMGAgglomeration::agglomerateLduAddressing
34 const label fineLevelIndex
37 const lduMesh& fineMesh = meshLevel(fineLevelIndex);
38 const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
40 const unallocLabelList& upperAddr = fineMeshAddr.upperAddr();
41 const unallocLabelList& lowerAddr = fineMeshAddr.lowerAddr();
43 label nFineFaces = upperAddr.size();
45 // Get restriction map for current level
46 const labelField& restrictMap = restrictAddressing(fineLevelIndex);
48 if (min(restrictMap) == -1)
50 FatalErrorIn("GAMGAgglomeration::agglomerateLduAddressing")
51 << "min(restrictMap) == -1" << exit(FatalError);
54 if (restrictMap.size() != fineMeshAddr.size())
58 "GAMGAgglomeration::agglomerateLduAddressing"
59 "(const label fineLevelIndex)"
60 ) << "restrict map does not correspond to fine level. " << endl
61 << " Sizes: restrictMap: " << restrictMap.size()
62 << " nEqns: " << fineMeshAddr.size()
67 // Get the number of coarse cells
68 const label nCoarseCells = nCells_[fineLevelIndex];
70 // Storage for coarse cell neighbours and coefficients
72 // Guess initial maximum number of neighbours in coarse cell
75 // Number of faces for each coarse-cell
76 labelList cCellnFaces(nCoarseCells, 0);
78 // Setup initial packed storage for coarse-cell faces
79 labelList cCellFaces(maxNnbrs*nCoarseCells);
81 // Create face-restriction addressing
82 faceRestrictAddressing_.set(fineLevelIndex, new labelList(nFineFaces));
83 labelList& faceRestrictAddr = faceRestrictAddressing_[fineLevelIndex];
85 // Initial neighbour array (not in upper-triangle order)
86 labelList initCoarseNeighb(nFineFaces);
88 // Counter for coarse faces
89 label nCoarseFaces = 0;
91 // Loop through all fine faces
92 forAll (upperAddr, fineFacei)
94 label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
95 label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
97 if (rmUpperAddr == rmLowerAddr)
99 // For each fine face inside of a coarse cell keep the address
100 // of the cell corresponding to the face in the faceRestrictAddr
101 // as a negative index
102 faceRestrictAddr[fineFacei] = -(rmUpperAddr + 1);
106 // this face is a part of a coarse face
108 label cOwn = rmUpperAddr;
109 label cNei = rmLowerAddr;
111 // get coarse owner and neighbour
112 if (rmUpperAddr > rmLowerAddr)
118 // check the neighbour to see if this face has already been found
119 label* ccFaces = &cCellFaces[maxNnbrs*cOwn];
121 bool nbrFound = false;
122 label& ccnFaces = cCellnFaces[cOwn];
124 for (int i=0; i<ccnFaces; i++)
126 if (initCoarseNeighb[ccFaces[i]] == cNei)
129 faceRestrictAddr[fineFacei] = ccFaces[i];
136 if (ccnFaces >= maxNnbrs)
138 label oldMaxNnbrs = maxNnbrs;
141 cCellFaces.setSize(maxNnbrs*nCoarseCells);
143 forAllReverse(cCellnFaces, i)
145 label* oldCcNbrs = &cCellFaces[oldMaxNnbrs*i];
146 label* newCcNbrs = &cCellFaces[maxNnbrs*i];
148 for (int j=0; j<cCellnFaces[i]; j++)
150 newCcNbrs[j] = oldCcNbrs[j];
154 ccFaces = &cCellFaces[maxNnbrs*cOwn];
157 ccFaces[ccnFaces] = nCoarseFaces;
158 initCoarseNeighb[nCoarseFaces] = cNei;
159 faceRestrictAddr[fineFacei] = nCoarseFaces;
162 // new coarse face created
166 } // end for all fine faces
169 // Renumber into upper-triangular order
171 // All coarse owner-neighbour storage
172 labelList coarseOwner(nCoarseFaces);
173 labelList coarseNeighbour(nCoarseFaces);
174 labelList coarseFaceMap(nCoarseFaces);
176 label coarseFacei = 0;
178 forAll (cCellnFaces, cci)
180 label* cFaces = &cCellFaces[maxNnbrs*cci];
181 label ccnFaces = cCellnFaces[cci];
183 for (int i=0; i<ccnFaces; i++)
185 coarseOwner[coarseFacei] = cci;
186 coarseNeighbour[coarseFacei] = initCoarseNeighb[cFaces[i]];
187 coarseFaceMap[cFaces[i]] = coarseFacei;
192 forAll(faceRestrictAddr, fineFacei)
194 if (faceRestrictAddr[fineFacei] >= 0)
196 faceRestrictAddr[fineFacei] =
197 coarseFaceMap[faceRestrictAddr[fineFacei]];
201 // Clear the temporary storage for the coarse cell data
202 cCellnFaces.setSize(0);
203 cCellFaces.setSize(0);
204 initCoarseNeighb.setSize(0);
205 coarseFaceMap.setSize(0);
208 // Create coarse-level interfaces
210 // Get reference to fine-level interfaces
211 const lduInterfacePtrsList& fineInterfaces =
212 interfaceLevels_[fineLevelIndex];
214 // Initialise transfer of restrict addressing on the interface
215 forAll (fineInterfaces, inti)
217 if (fineInterfaces.set(inti))
219 if (fineInterfaces[inti].coupled())
221 fineInterfaces[inti].initInternalFieldTransfer
230 // Store coefficients to avoid tangled communications
232 FieldField<Field, label> fineInterfaceAddr(fineInterfaces.size());
234 forAll (fineInterfaces, inti)
236 if (fineInterfaces.set(inti))
238 if (fineInterfaces[inti].coupled())
240 fineInterfaceAddr.set
245 fineInterfaces[inti].internalFieldTransfer
256 // Add the coarse level
258 // Set the coarse ldu addressing onto the list
271 // Create coarse-level interfaces
275 new lduInterfacePtrsList(fineInterfaces.size())
278 lduInterfacePtrsList& coarseInterfaces =
279 interfaceLevels_[fineLevelIndex + 1];
281 labelListList coarseInterfaceAddr(fineInterfaces.size());
283 forAll (fineInterfaces, inti)
285 if (fineInterfaces.set(inti))
287 if (fineInterfaces[inti].coupled())
294 meshLevels_[fineLevelIndex],
295 fineInterfaces[inti],
296 fineInterfaces[inti].interfaceInternalField
300 fineInterfaceAddr[inti]
304 coarseInterfaceAddr[inti] = coarseInterfaces[inti].faceCells();
309 meshLevels_[fineLevelIndex].addInterfaces
313 fineMeshAddr.patchSchedule()
318 // ************************************************************************* //