Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "GAMGAgglomeration.H"
00027 #include <OpenFOAM/GAMGInterface.H>
00028
00029
00030
00031 void Foam::GAMGAgglomeration::agglomerateLduAddressing
00032 (
00033 const label fineLevelIndex
00034 )
00035 {
00036 const lduMesh& fineMesh = meshLevel(fineLevelIndex);
00037 const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
00038
00039 const unallocLabelList& upperAddr = fineMeshAddr.upperAddr();
00040 const unallocLabelList& lowerAddr = fineMeshAddr.lowerAddr();
00041
00042 label nFineFaces = upperAddr.size();
00043
00044
00045 const labelField& restrictMap = restrictAddressing(fineLevelIndex);
00046
00047 if (min(restrictMap) == -1)
00048 {
00049 FatalErrorIn("GAMGAgglomeration::agglomerateLduAddressing")
00050 << "min(restrictMap) == -1" << exit(FatalError);
00051 }
00052
00053 if (restrictMap.size() != fineMeshAddr.size())
00054 {
00055 FatalErrorIn
00056 (
00057 "GAMGAgglomeration::agglomerateLduAddressing"
00058 "(const label fineLevelIndex)"
00059 ) << "restrict map does not correspond to fine level. " << endl
00060 << " Sizes: restrictMap: " << restrictMap.size()
00061 << " nEqns: " << fineMeshAddr.size()
00062 << abort(FatalError);
00063 }
00064
00065
00066
00067 const label nCoarseCells = nCells_[fineLevelIndex];
00068
00069
00070
00071
00072 label maxNnbrs = 10;
00073
00074
00075 labelList cCellnFaces(nCoarseCells, 0);
00076
00077
00078 labelList cCellFaces(maxNnbrs*nCoarseCells);
00079
00080
00081 faceRestrictAddressing_.set(fineLevelIndex, new labelList(nFineFaces));
00082 labelList& faceRestrictAddr = faceRestrictAddressing_[fineLevelIndex];
00083
00084
00085 labelList initCoarseNeighb(nFineFaces);
00086
00087
00088 label nCoarseFaces = 0;
00089
00090
00091 forAll (upperAddr, fineFacei)
00092 {
00093 label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
00094 label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
00095
00096 if (rmUpperAddr == rmLowerAddr)
00097 {
00098
00099
00100
00101 faceRestrictAddr[fineFacei] = -(rmUpperAddr + 1);
00102 }
00103 else
00104 {
00105
00106
00107 label cOwn = rmUpperAddr;
00108 label cNei = rmLowerAddr;
00109
00110
00111 if (rmUpperAddr > rmLowerAddr)
00112 {
00113 cOwn = rmLowerAddr;
00114 cNei = rmUpperAddr;
00115 }
00116
00117
00118 label* ccFaces = &cCellFaces[maxNnbrs*cOwn];
00119
00120 bool nbrFound = false;
00121 label& ccnFaces = cCellnFaces[cOwn];
00122
00123 for (int i=0; i<ccnFaces; i++)
00124 {
00125 if (initCoarseNeighb[ccFaces[i]] == cNei)
00126 {
00127 nbrFound = true;
00128 faceRestrictAddr[fineFacei] = ccFaces[i];
00129 break;
00130 }
00131 }
00132
00133 if (!nbrFound)
00134 {
00135 if (ccnFaces >= maxNnbrs)
00136 {
00137 label oldMaxNnbrs = maxNnbrs;
00138 maxNnbrs *= 2;
00139
00140 cCellFaces.setSize(maxNnbrs*nCoarseCells);
00141
00142 forAllReverse(cCellnFaces, i)
00143 {
00144 label* oldCcNbrs = &cCellFaces[oldMaxNnbrs*i];
00145 label* newCcNbrs = &cCellFaces[maxNnbrs*i];
00146
00147 for (int j=0; j<cCellnFaces[i]; j++)
00148 {
00149 newCcNbrs[j] = oldCcNbrs[j];
00150 }
00151 }
00152
00153 ccFaces = &cCellFaces[maxNnbrs*cOwn];
00154 }
00155
00156 ccFaces[ccnFaces] = nCoarseFaces;
00157 initCoarseNeighb[nCoarseFaces] = cNei;
00158 faceRestrictAddr[fineFacei] = nCoarseFaces;
00159 ccnFaces++;
00160
00161
00162 nCoarseFaces++;
00163 }
00164 }
00165 }
00166
00167
00168
00169
00170
00171 labelList coarseOwner(nCoarseFaces);
00172 labelList coarseNeighbour(nCoarseFaces);
00173 labelList coarseFaceMap(nCoarseFaces);
00174
00175 label coarseFacei = 0;
00176
00177 forAll (cCellnFaces, cci)
00178 {
00179 label* cFaces = &cCellFaces[maxNnbrs*cci];
00180 label ccnFaces = cCellnFaces[cci];
00181
00182 for (int i=0; i<ccnFaces; i++)
00183 {
00184 coarseOwner[coarseFacei] = cci;
00185 coarseNeighbour[coarseFacei] = initCoarseNeighb[cFaces[i]];
00186 coarseFaceMap[cFaces[i]] = coarseFacei;
00187 coarseFacei++;
00188 }
00189 }
00190
00191 forAll(faceRestrictAddr, fineFacei)
00192 {
00193 if (faceRestrictAddr[fineFacei] >= 0)
00194 {
00195 faceRestrictAddr[fineFacei] =
00196 coarseFaceMap[faceRestrictAddr[fineFacei]];
00197 }
00198 }
00199
00200
00201 cCellnFaces.setSize(0);
00202 cCellFaces.setSize(0);
00203 initCoarseNeighb.setSize(0);
00204 coarseFaceMap.setSize(0);
00205
00206
00207
00208
00209
00210 const lduInterfacePtrsList& fineInterfaces =
00211 interfaceLevels_[fineLevelIndex];
00212
00213
00214 interfaceLevels_.set
00215 (
00216 fineLevelIndex + 1,
00217 new lduInterfacePtrsList(fineInterfaces.size())
00218 );
00219
00220 lduInterfacePtrsList& coarseInterfaces =
00221 interfaceLevels_[fineLevelIndex + 1];
00222
00223 labelListList coarseInterfaceAddr(fineInterfaces.size());
00224
00225
00226 forAll (fineInterfaces, inti)
00227 {
00228 if (fineInterfaces.set(inti))
00229 {
00230 fineInterfaces[inti].initInternalFieldTransfer
00231 (
00232 Pstream::blocking,
00233 restrictMap
00234 );
00235 }
00236 }
00237
00238
00239 forAll (fineInterfaces, inti)
00240 {
00241 if (fineInterfaces.set(inti))
00242 {
00243 coarseInterfaces.set
00244 (
00245 inti,
00246 GAMGInterface::New
00247 (
00248 fineInterfaces[inti],
00249 fineInterfaces[inti].interfaceInternalField(restrictMap),
00250 fineInterfaces[inti].internalFieldTransfer
00251 (
00252 Pstream::blocking,
00253 restrictMap
00254 )
00255 ).ptr()
00256 );
00257
00258 coarseInterfaceAddr[inti] = coarseInterfaces[inti].faceCells();
00259 }
00260 }
00261
00262
00263
00264 meshLevels_.set
00265 (
00266 fineLevelIndex,
00267 new lduPrimitiveMesh
00268 (
00269 nCoarseCells,
00270 coarseOwner,
00271 coarseNeighbour,
00272 coarseInterfaceAddr,
00273 coarseInterfaces,
00274 fineMeshAddr.patchSchedule(),
00275 true
00276 )
00277 );
00278 }
00279
00280
00281