1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 Tries to figure out what the refinement level is on refined cartesian
26 meshes. Run BEFORE snapping.
29 - volScalarField 'refinementLevel' with current refinement level.
30 - cellSet 'refCells' which are the cells that need to be refined to satisfy
33 Works by dividing cells into volume bins.
35 \*---------------------------------------------------------------------------*/
41 #include "SortableList.H"
42 #include "labelIOList.H"
44 #include "volFields.H"
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 // Return true if any cells had to be split to keep a difference between
51 // neighbouring refinement levels < limitDiff. Puts cells into refCells and
52 // update refLevel to account for refinement.
53 bool limitRefinementLevel
55 const primitiveMesh& mesh,
60 const labelListList& cellCells = mesh.cellCells();
62 label oldNCells = refCells.size();
64 forAll(cellCells, cellI)
66 const labelList& cCells = cellCells[cellI];
70 if (refLevel[cCells[i]] > (refLevel[cellI]+1))
72 // Found neighbour with >=2 difference in refLevel.
73 refCells.insert(cellI);
80 if (refCells.size() > oldNCells)
82 Info<< "Added an additional " << refCells.size() - oldNCells
83 << " cells to satisfy 1:2 refinement level"
97 int main(int argc, char *argv[])
99 argList::addBoolOption
102 "read level from refinementLevel file"
105 #include "setRootCase.H"
106 #include "createTime.H"
107 #include "createPolyMesh.H"
109 Info<< "Dividing cells into bins depending on cell volume.\nThis will"
110 << " correspond to refinement levels for a mesh with only 2x2x2"
112 << "The upper range for every bin is always 1.1 times the lower range"
113 << " to allow for some truncation error."
116 const bool readLevel = args.optionFound("readLevel");
118 const scalarField& vols = mesh.cellVolumes();
120 SortableList<scalar> sortedVols(vols);
122 // All cell labels, sorted per bin.
123 DynamicList<DynamicList<label> > bins;
125 // Lower/upper limits
126 DynamicList<scalar> lowerLimits;
127 DynamicList<scalar> upperLimits;
129 // Create bin0. Have upperlimit as factor times lowerlimit.
130 bins.append(DynamicList<label>());
131 lowerLimits.append(sortedVols[0]);
132 upperLimits.append(1.1 * lowerLimits.last());
134 forAll(sortedVols, i)
136 if (sortedVols[i] > upperLimits.last())
138 // New value outside of current bin
141 DynamicList<label>& bin = bins.last();
145 Info<< "Collected " << bin.size() << " elements in bin "
146 << lowerLimits.last() << " .. "
147 << upperLimits.last() << endl;
150 bins.append(DynamicList<label>());
151 lowerLimits.append(sortedVols[i]);
152 upperLimits.append(1.1 * lowerLimits.last());
154 Info<< "Creating new bin " << lowerLimits.last()
155 << " .. " << upperLimits.last()
159 // Append to current bin.
160 DynamicList<label>& bin = bins.last();
162 bin.append(sortedVols.indices()[i]);
166 bins.last().shrink();
168 lowerLimits.shrink();
169 upperLimits.shrink();
173 // Write to cellSets.
176 Info<< "Volume bins:" << nl;
179 const DynamicList<label>& bin = bins[binI];
181 cellSet cells(mesh, "vol" + name(binI), bin.size());
185 cells.insert(bin[i]);
188 Info<< " " << lowerLimits[binI] << " .. " << upperLimits[binI]
189 << " : writing " << bin.size() << " cells to cellSet "
190 << cells.name() << endl;
198 // Convert bins into refinement level.
202 // Construct fvMesh to be able to construct volScalarField
208 fvMesh::defaultRegion,
212 xferCopy(mesh.points()), // could we safely re-use the data?
213 xferCopy(mesh.faces()),
214 xferCopy(mesh.cells())
217 // Add the boundary patches
218 const polyBoundaryMesh& patches = mesh.boundaryMesh();
220 List<polyPatch*> p(patches.size());
224 p[patchI] = patches[patchI].clone(fMesh.boundaryMesh()).ptr();
227 fMesh.addFvPatches(p);
235 polyMesh::defaultRegion,
239 if (!readLevel && refHeader.headerOk())
241 WarningIn(args.executable())
242 << "Detected " << refHeader.name() << " file in "
243 << polyMesh::defaultRegion << " directory. Please remove to"
244 << " recreate it or use the -readLevel option to use it"
260 labelList(mesh.nCells(), 0)
265 refLevel = labelIOList(refHeader);
268 // Construct volScalarField with same info for post processing
269 volScalarField postRefLevel
280 dimensionedScalar("zero", dimless/dimTime, 0)
286 const DynamicList<label>& bin = bins[binI];
290 refLevel[bin[i]] = bins.size() - binI - 1;
291 postRefLevel[bin[i]] = refLevel[bin[i]];
296 // For volScalarField: set boundary values to same as cell.
297 // Note: could also put
298 // zeroGradient b.c. on postRefLevel and do evaluate.
299 forAll(postRefLevel.boundaryField(), patchI)
301 const polyPatch& pp = patches[patchI];
303 fvPatchScalarField& bField = postRefLevel.boundaryField()[patchI];
305 Info<< "Setting field for patch "<< endl;
307 forAll(bField, faceI)
309 label own = mesh.faceOwner()[pp.start() + faceI];
311 bField[faceI] = postRefLevel[own];
315 Info<< "Determined current refinement level and writing to "
316 << postRefLevel.name() << " (as volScalarField; for post processing)"
318 << polyMesh::defaultRegion/refLevel.name()
319 << " (as labelIOList; for meshing)" << nl
323 postRefLevel.write();
326 // Find out cells to refine to keep to 2:1 refinement level restriction
329 cellSet refCells(mesh, "refCells", 100);
336 refLevel, // current refinement level
337 refCells // cells to refine
344 Info<< "Collected " << refCells.size() << " cells that need to be"
345 << " refined to get closer to overall 2:1 refinement level limit"
347 << "Written cells to be refined to cellSet " << refCells.name()
352 Info<< "After refinement this tool can be run again to see if the 2:1"
353 << " limit is observed all over the mesh" << nl << endl;
357 Info<< "All cells in the mesh observe the 2:1 refinement level limit"
361 Info<< "\nEnd\n" << endl;
366 // ************************************************************************* //