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 "pairGAMGAgglomeration.H"
00027 #include <OpenFOAM/lduAddressing.H>
00028
00029
00030
00031 Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
00032 (
00033 label& nCoarseCells,
00034 const lduAddressing& fineMatrixAddressing,
00035 const scalarField& faceWeights
00036 )
00037 {
00038 const label nFineCells = fineMatrixAddressing.size();
00039
00040 const unallocLabelList& upperAddr = fineMatrixAddressing.upperAddr();
00041 const unallocLabelList& lowerAddr = fineMatrixAddressing.lowerAddr();
00042
00043
00044 labelList cellFaces(upperAddr.size() + lowerAddr.size());
00045 labelList cellFaceOffsets(nFineCells + 1);
00046
00047
00048 {
00049 labelList nNbrs(nFineCells, 0);
00050
00051 forAll (upperAddr, facei)
00052 {
00053 nNbrs[upperAddr[facei]]++;
00054 }
00055
00056 forAll (lowerAddr, facei)
00057 {
00058 nNbrs[lowerAddr[facei]]++;
00059 }
00060
00061 cellFaceOffsets[0] = 0;
00062 forAll (nNbrs, celli)
00063 {
00064 cellFaceOffsets[celli+1] = cellFaceOffsets[celli] + nNbrs[celli];
00065 }
00066
00067
00068 nNbrs = 0;
00069
00070 forAll (upperAddr, facei)
00071 {
00072 cellFaces
00073 [
00074 cellFaceOffsets[upperAddr[facei]] + nNbrs[upperAddr[facei]]
00075 ] = facei;
00076
00077 nNbrs[upperAddr[facei]]++;
00078 }
00079
00080 forAll (lowerAddr, facei)
00081 {
00082 cellFaces
00083 [
00084 cellFaceOffsets[lowerAddr[facei]] + nNbrs[lowerAddr[facei]]
00085 ] = facei;
00086
00087 nNbrs[lowerAddr[facei]]++;
00088 }
00089 }
00090
00091
00092
00093
00094 tmp<labelField> tcoarseCellMap(new labelField(nFineCells, -1));
00095 labelField& coarseCellMap = tcoarseCellMap();
00096
00097 nCoarseCells = 0;
00098
00099 for (label celli=0; celli<nFineCells; celli++)
00100 {
00101 if (coarseCellMap[celli] < 0)
00102 {
00103 label matchFaceNo = -1;
00104 scalar maxFaceWeight = -GREAT;
00105
00106
00107 for
00108 (
00109 label faceOs=cellFaceOffsets[celli];
00110 faceOs<cellFaceOffsets[celli+1];
00111 faceOs++
00112 )
00113 {
00114 label facei = cellFaces[faceOs];
00115
00116
00117
00118 if
00119 (
00120 coarseCellMap[upperAddr[facei]] < 0
00121 && coarseCellMap[lowerAddr[facei]] < 0
00122 && faceWeights[facei] > maxFaceWeight
00123 )
00124 {
00125
00126 matchFaceNo = facei;
00127 maxFaceWeight = faceWeights[facei];
00128 }
00129 }
00130
00131 if (matchFaceNo >= 0)
00132 {
00133
00134 coarseCellMap[upperAddr[matchFaceNo]] = nCoarseCells;
00135 coarseCellMap[lowerAddr[matchFaceNo]] = nCoarseCells;
00136 nCoarseCells++;
00137 }
00138 else
00139 {
00140
00141
00142 label clusterMatchFaceNo = -1;
00143 scalar clusterMaxFaceCoeff = -GREAT;
00144
00145 for
00146 (
00147 label faceOs=cellFaceOffsets[celli];
00148 faceOs<cellFaceOffsets[celli+1];
00149 faceOs++
00150 )
00151 {
00152 label facei = cellFaces[faceOs];
00153
00154 if (faceWeights[facei] > clusterMaxFaceCoeff)
00155 {
00156 clusterMatchFaceNo = facei;
00157 clusterMaxFaceCoeff = faceWeights[facei];
00158 }
00159 }
00160
00161 if (clusterMatchFaceNo >= 0)
00162 {
00163
00164 coarseCellMap[celli] = max
00165 (
00166 coarseCellMap[upperAddr[clusterMatchFaceNo]],
00167 coarseCellMap[lowerAddr[clusterMatchFaceNo]]
00168 );
00169 }
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177 for (label celli=0; celli<nFineCells; celli++)
00178 {
00179 if (coarseCellMap[celli] < 0)
00180 {
00181 coarseCellMap[celli] = nCoarseCells;
00182 nCoarseCells++;
00183 }
00184 }
00185
00186
00187
00188 nCoarseCells--;
00189
00190 forAll (coarseCellMap, celli)
00191 {
00192 coarseCellMap[celli] = nCoarseCells - coarseCellMap[celli];
00193 }
00194
00195 nCoarseCells++;
00196
00197 return tcoarseCellMap;
00198 }
00199
00200
00201 void Foam::pairGAMGAgglomeration::agglomerate
00202 (
00203 const lduMesh& mesh,
00204 const scalarField& faceWeights
00205 )
00206 {
00207
00208 interfaceLevels_.set
00209 (
00210 0,
00211 new lduInterfacePtrsList(mesh.interfaces())
00212 );
00213
00214
00215 scalarField* faceWeightsPtr = const_cast<scalarField*>(&faceWeights);
00216
00217
00218
00219
00220 label nPairLevels = 0;
00221 label nCreatedLevels = 0;
00222
00223 while (nCreatedLevels < maxLevels_ - 1)
00224 {
00225 label nCoarseCells = -1;
00226
00227 tmp<labelField> finalAgglomPtr = agglomerate
00228 (
00229 nCoarseCells,
00230 meshLevel(nCreatedLevels).lduAddr(),
00231 *faceWeightsPtr
00232 );
00233
00234 if (continueAgglomerating(nCoarseCells))
00235 {
00236 nCells_[nCreatedLevels] = nCoarseCells;
00237 restrictAddressing_.set(nCreatedLevels, finalAgglomPtr);
00238 }
00239 else
00240 {
00241 break;
00242 }
00243
00244 agglomerateLduAddressing(nCreatedLevels);
00245
00246
00247 {
00248 scalarField* aggFaceWeightsPtr
00249 (
00250 new scalarField
00251 (
00252 meshLevels_[nCreatedLevels].upperAddr().size(),
00253 0.0
00254 )
00255 );
00256
00257 restrictFaceField
00258 (
00259 *aggFaceWeightsPtr,
00260 *faceWeightsPtr,
00261 nCreatedLevels
00262 );
00263
00264 if (nCreatedLevels)
00265 {
00266 delete faceWeightsPtr;
00267 }
00268
00269 faceWeightsPtr = aggFaceWeightsPtr;
00270 }
00271
00272 if (nPairLevels % mergeLevels_)
00273 {
00274 combineLevels(nCreatedLevels);
00275 }
00276 else
00277 {
00278 nCreatedLevels++;
00279 }
00280
00281 nPairLevels++;
00282 }
00283
00284
00285 compactLevels(nCreatedLevels);
00286
00287
00288 if (nCreatedLevels)
00289 {
00290 delete faceWeightsPtr;
00291 }
00292 }
00293
00294
00295