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 
00027 
00028 
00029 #include "MGridGenGAMGAgglomeration.H"
00030 #include <finiteVolume/fvMesh.H>
00031 #include <OpenFOAM/syncTools.H>
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 void Foam::MGridGenGAMGAgglomeration::
00041 makeCompactCellFaceAddressingAndFaceWeights
00042 (
00043     const lduAddressing& fineAddressing,
00044     List<idxtype>& cellCells,
00045     List<idxtype>& cellCellOffsets,
00046     const vectorField& Si,
00047     List<scalar>& faceWeights
00048 )
00049 {
00050     const label nFineCells = fineAddressing.size();
00051     const label nFineFaces = fineAddressing.upperAddr().size();
00052 
00053     const unallocLabelList& upperAddr = fineAddressing.upperAddr();
00054     const unallocLabelList& lowerAddr = fineAddressing.lowerAddr();
00055 
00056     
00057     labelList nNbrs(nFineCells, 0);
00058 
00059     forAll (upperAddr, facei)
00060     {
00061         nNbrs[upperAddr[facei]]++;
00062     }
00063 
00064     forAll (lowerAddr, facei)
00065     {
00066         nNbrs[lowerAddr[facei]]++;
00067     }
00068 
00069     
00070     cellCellOffsets.setSize(nFineCells + 1);
00071     cellCells.setSize(2*nFineFaces);
00072     faceWeights.setSize(2*nFineFaces);
00073 
00074 
00075     cellCellOffsets[0] = 0;
00076     forAll (nNbrs, celli)
00077     {
00078         cellCellOffsets[celli+1] = cellCellOffsets[celli] + nNbrs[celli];
00079     }
00080 
00081     
00082     nNbrs = 0;
00083 
00084     forAll (upperAddr, facei)
00085     {
00086         label own = upperAddr[facei];
00087         label nei = lowerAddr[facei];
00088 
00089         label l1 = cellCellOffsets[own] + nNbrs[own]++;
00090         label l2 = cellCellOffsets[nei] + nNbrs[nei]++;
00091 
00092         cellCells[l1] = nei;
00093         cellCells[l2] = own;
00094 
00095         faceWeights[l1] = mag(Si[facei]);
00096         faceWeights[l2] = mag(Si[facei]);
00097     }
00098 }
00099 
00100 
00101 Foam::tmp<Foam::labelField> Foam::MGridGenGAMGAgglomeration::agglomerate
00102 (
00103     label& nCoarseCells,
00104     const label minSize,
00105     const label maxSize,
00106     const lduAddressing& fineAddressing,
00107     const scalarField& V,
00108     const vectorField& Sf,
00109     const scalarField& Sb
00110 )
00111 {
00112     const label nFineCells = fineAddressing.size();
00113 
00114     
00115     List<idxtype> cellCells;
00116     List<idxtype> cellCellOffsets;
00117 
00118     
00119     List<scalar> faceWeights;
00120 
00121     
00122     makeCompactCellFaceAddressingAndFaceWeights
00123     (
00124         fineAddressing,
00125         cellCells,
00126         cellCellOffsets,
00127         Sf,
00128         faceWeights
00129     );
00130 
00131     
00132     List<int> options(4, 0);
00133     options[0] = 4;                   
00134     options[1] = 6;                   
00135     options[2] = 128;                 
00136     options[3] = fvMesh_.nGeometricD(); 
00137 
00138 
00139     
00140     List<int> finalAgglom(nFineCells);
00141     int nMoves = -1;
00142         
00143     MGridGen
00144     (
00145         nFineCells,
00146         cellCellOffsets.begin(),
00147         const_cast<scalar*>(V.begin()),
00148         const_cast<scalar*>(Sb.begin()),
00149         cellCells.begin(),
00150         faceWeights.begin(),
00151         minSize,
00152         maxSize,
00153         options.begin(),
00154         &nMoves,
00155         &nCoarseCells,
00156         finalAgglom.begin()
00157     );
00158 
00159     return tmp<labelField>(new labelField(finalAgglom));
00160 }
00161 
00162 
00163