70static const scalar edgeTol = 1
e-3;
75 Info<<
"Writing " << msg <<
" (" <<
cells.size() <<
") to cellSet "
88 if (
mag(normal.x()) > 1-edgeTol)
92 else if (
mag(normal.y()) > 1-edgeTol)
96 else if (
mag(normal.z()) > 1-edgeTol)
123 for (
const edge&
e : edges)
127 scalar eMag =
mag(eVec);
131 if (
mag(eVec.x()) > 1-edgeTol)
136 else if (
mag(eVec.y()) > 1-edgeTol)
141 else if (
mag(eVec.z()) > 1-edgeTol)
154 <<
"Mesh edge statistics:" <<
nl
155 <<
" x aligned : number:" << nX
156 <<
"\tminLen:" << limitsX.min() <<
"\tmaxLen:" << limitsX.max() <<
nl
157 <<
" y aligned : number:" << nY
158 <<
"\tminLen:" << limitsY.min() <<
"\tmaxLen:" << limitsY.max() <<
nl
159 <<
" z aligned : number:" << nZ
160 <<
"\tminLen:" << limitsZ.min() <<
"\tmaxLen:" << limitsZ.max() <<
nl
161 <<
" other : number:" << nAny
162 <<
"\tminLen:" << limitsAny.min()
163 <<
"\tmaxLen:" << limitsAny.max() <<
nl <<
endl;
207 label patchi =
mesh.boundaryMesh().findPatchID(patchName);
227 mesh.nInternalFaces(),
230 emptyPolyPatch::typeName
252 mesh.removeBoundary();
253 mesh.addPatches(newPatches);
255 Info<<
"Created patch oldInternalFaces at " << patchi <<
endl;
259 Info<<
"Reusing patch oldInternalFaces at " << patchi <<
endl;
268void selectCurvatureCells
273 const scalar nearDist,
274 const scalar curvature,
309 const bool selectInside,
310 const bool selectOutside,
320 for (
const label celli : cutCells)
326 const label facei = cFaces[i];
328 if (
mesh.isInternalFace(facei))
330 label nbr =
mesh.faceOwner()[facei];
334 nbr =
mesh.faceNeighbour()[facei];
337 if (selectInside && inside.
found(nbr))
339 addCutFaces.insert(nbr);
341 else if (selectOutside && outside.
found(nbr))
343 addCutFaces.insert(nbr);
349 Info<<
" Selected an additional " << addCutFaces.size()
350 <<
" neighbours of cutCells to refine" <<
endl;
352 for (
const label facei : addCutFaces)
354 cutCells.insert(facei);
363bool limitRefinementLevel
366 const label limitDiff,
375 if (!excludeCells.
found(celli))
381 label nbr = cCells[i];
383 if (!excludeCells.
found(nbr))
385 if (refLevel[celli] - refLevel[nbr] >= limitDiff)
388 <<
"Level difference between neighbouring cells "
389 << celli <<
" and " << nbr
390 <<
" greater than or equal to " << limitDiff <<
endl
391 <<
"refLevels:" << refLevel[celli] <<
' '
402 for (
const label celli : cutCells)
409 const label nbr = cCells[i];
411 if (!excludeCells.
found(nbr) && !cutCells.found(nbr))
413 if (refLevel[celli] + 1 - refLevel[nbr] >= limitDiff)
415 addCutCells.insert(nbr);
421 if (addCutCells.size())
425 Info<<
"Added an additional " << addCutCells.size() <<
" cells"
426 <<
" to satisfy 1:" << limitDiff <<
" refinement level"
429 for (
const label celli : addCutCells)
431 cutCells.insert(celli);
436 Info<<
"Added no additional cells"
437 <<
" to satisfy 1:" << limitDiff <<
" refinement level"
454 label oldCells =
mesh.nCells();
470 for (label celli = oldCells; celli <
mesh.nCells(); celli++)
477 forAll(addedCells, oldCelli)
479 const labelList& added = addedCells[oldCelli];
485 label masterLevel = ++refLevel[oldCelli];
489 refLevel[added[i]] = masterLevel;
500 const label writeMesh,
511 Info<<
"Mesh has:" <<
mesh.nCells() <<
" cells."
512 <<
" Removing:" << cellLabels.size() <<
" cells" <<
endl;
515 labelList exposedFaces(cellRemover.getExposedFaces(cellLabels));
518 cellRemover.setRefinement
533 if (morphMap().hasMotionPoints())
535 mesh.movePoints(morphMap().preMotionPoints());
539 cellRemover.updateMesh(morphMap());
542 const labelList& cellMap = morphMap().cellMap();
548 newRefLevel[i] = refLevel[cellMap[i]];
556 Info<<
"Writing refined mesh to time " <<
runTime.timeName() <<
nl
586 const bool selectCut,
587 const bool selectInside,
588 const bool selectOutside,
590 const label nCutLayers,
617 selected.
addSet(cutCells);
628 Info<<
"Determined cell status:" <<
endl
629 <<
" inside :" << inside.
size() <<
endl
630 <<
" outside :" << outside.
size() <<
endl
631 <<
" cutCells:" << cutCells.
size() <<
endl
632 <<
" selected:" << selected.
size() <<
endl
635 writeSet(inside,
"inside cells");
636 writeSet(outside,
"outside cells");
637 writeSet(cutCells,
"cut cells");
638 writeSet(selected,
"selected cells");
643int main(
int argc,
char *argv[])
647 "Refine cells near to a surface"
656 label newPatchi = addPatch(
mesh,
"oldInternalFaces");
663 Info<<
"Checking for motionProperties\n" <<
endl;
679 Info<<
"Reading " <<
runTime.constant() /
"motionProperties"
684 if (motionProperties.get<
bool>(
"twoDMotion"))
695 "snappyRefineMeshDict",
705 const label nCutLayers(refineDict.
get<label>(
"nCutLayers"));
706 const label cellLimit(refineDict.
get<label>(
"cellLimit"));
707 const bool selectCut(refineDict.
get<
bool>(
"selectCut"));
708 const bool selectInside(refineDict.
get<
bool>(
"selectInside"));
709 const bool selectOutside(refineDict.
get<
bool>(
"selectOutside"));
710 const bool selectHanging(refineDict.
get<
bool>(
"selectHanging"));
712 const scalar minEdgeLen(refineDict.
get<scalar>(
"minEdgeLen"));
713 const scalar maxEdgeLen(refineDict.
get<scalar>(
"maxEdgeLen"));
714 const scalar curvature(refineDict.
get<scalar>(
"curvature"));
715 const scalar curvDist(refineDict.
get<scalar>(
"curvatureDistance"));
717 const label refinementLimit(refineDict.
get<label>(
"splitLevel"));
718 const bool writeMesh(refineDict.
get<
bool>(
"writeMesh"));
720 Info<<
"Cells to be used for meshing (0=false, 1=true):" <<
nl
721 <<
" cells cut by surface : " << selectCut <<
nl
722 <<
" cells inside of surface : " << selectInside <<
nl
723 <<
" cells outside of surface : " << selectOutside <<
nl
724 <<
" hanging cells : " << selectHanging <<
nl
728 if (nCutLayers > 0 && selectInside)
731 <<
"Illogical settings : Both nCutLayers>0 and selectInside true."
733 <<
"This would mean that inside cells get removed but should be"
734 <<
" included in final mesh" <<
endl;
747 forAll(outsidePts, outsidei)
749 const point& outsidePoint = outsidePts[outsidei];
751 if (queryMesh.findCell(outsidePoint, -1,
false) == -1)
754 <<
"outsidePoint " << outsidePoint
755 <<
" is not inside any cell"
777 label maxLevel =
max(refLevel);
781 Info<<
"Read existing refinement level from file "
783 <<
" min level : " <<
min(refLevel) <<
nl
784 <<
" max level : " << maxLevel <<
nl
789 Info<<
"Created zero refinement level in file "
798 direction normalDir(getNormalDir(correct2DPtr));
799 scalar meshMinEdgeLen = getEdgeStats(
mesh, normalDir);
801 while (meshMinEdgeLen > minEdgeLen)
828 Info<<
" Selected " << cutCells.
name() <<
" with "
829 << cutCells.
size() <<
" cells" <<
endl;
831 if ((curvDist > 0) && (meshMinEdgeLen < maxEdgeLen))
848 Info<<
" Selected " << curveCells.name() <<
" with "
849 << curveCells.size() <<
" cells" <<
endl;
868 cutCells.
subset(curveCells);
870 Info<<
" Removed cells not on surface curvature. Selected "
879 subsetMesh(
mesh, writeMesh, newPatchi, inside, cutCells, refLevel);
898 Info<<
" Current cells : " <<
mesh.nCells() <<
nl
899 <<
" Selected for refinement :" << cutCells.
size() <<
nl
902 if (cutCells.
empty())
904 Info<<
"Stopping refining since 0 cells selected to be refined ..."
909 if ((
mesh.nCells() + 8*cutCells.
size()) > cellLimit)
911 Info<<
"Stopping refining since cell limit reached ..." <<
nl
912 <<
"Would refine from " <<
mesh.nCells()
913 <<
" to " <<
mesh.nCells() + 8*cutCells.
size() <<
" cells."
926 Info<<
" After refinement:" <<
mesh.nCells() <<
nl
931 Info<<
" Writing refined mesh to time " <<
runTime.timeName()
944 meshMinEdgeLen = getEdgeStats(
mesh, normalDir);
980 Info<<
"Detected " << hanging.
size() <<
" hanging cells"
981 <<
" (cells with all points on"
982 <<
" outside of cellSet 'selected').\nThese would probably result"
983 <<
" in flattened cells when snapping the mesh to the surface"
986 Info<<
"Refining " << hanging.
size() <<
" hanging cells" <<
nl
1003 doRefinement(
mesh, refineDict, hanging, refLevel);
1005 Info<<
"Writing refined mesh to time " <<
runTime.timeName() <<
nl
1018 else if (!writeMesh)
1022 Info<<
"Writing refined mesh to time " <<
runTime.timeName() <<
nl
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
List< Key > toc() const
The table of contents (the keys) in unsorted order.
bool empty() const noexcept
True if the hash table is empty.
bool found(const Key &key) const
Same as contains().
label size() const noexcept
The number of elements in table.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
const word & name() const noexcept
Return the object name.
fileName objectPath() const
The complete path + object name.
static unsigned int minPrecision(unsigned int prec) noexcept
Set the minimum default precision.
static unsigned int defaultPrecision() noexcept
Return the default precision.
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
void setSize(label n)
Alias for resize().
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
void size(const label n)
Older name for setAddressableSize.
static void noParallel()
Remove the parallel options.
static void addNote(const string ¬e)
Add extra notes for the usage information.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
A bounding box defined in terms of min/max extrema points.
A collection of cell labels.
virtual void updateMesh(const mapPolyMesh &morphMap)
Update any stored data for new labels.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return an entry data stream. FatalIOError if not found, or not a stream.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Empty front and back plane patch. Used for 2-D geometries.
A class for handling file names.
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Does multiple pass refinement to refine cells in multiple directions.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
Mesh consisting of general polyhedral cells.
static word defaultRegion
Return the default region name.
A patch is a list of labels that address the faces in the global face list.
Direct mesh changes based on v1.3 polyTopoChange syntax.
Cell-face mesh analysis engine.
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
Given list of cells to remove, insert all the topology changes.
string & expand(const bool allowEmpty=false)
Inplace expand initial tags, tildes, and all occurrences of environment variables as per stringOps::e...
static labelHashSet getHangingCells(const primitiveMesh &mesh, const labelHashSet &internalCells)
Get cells using points on 'outside' only.
static void getSurfaceSets(const polyMesh &mesh, const fileName &surfName, const triSurface &surf, const triSurfaceSearch &querySurf, const pointField &outsidePts, const label nCutLayers, labelHashSet &inside, labelHashSet &outside, labelHashSet &cut)
Divide cells into cut,inside and outside.
A topoSetCellSource to select cells based on relation to a surface given by an external file.
@ ADD
Add elements to current set.
virtual void subset(const labelUList &elems)
Subset contents. Only elements present in both sets remain.
virtual void addSet(const labelUList &elems)
Add given elements to the set.
Helper class to search on triSurface.
const triSurface & surface() const
Return reference to the surface.
Triangulated surface description with patch information.
Class applies a two-dimensional correction to mesh motion point field.
const vector & planeNormal() const
Return plane normal.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
const polyBoundaryMesh & patches
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
List< edge > edgeList
List of edge.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
IOList< label > labelIOList
IO for a List of label.
messageStream Info
Information stream (stdout output on master, null elsewhere).
MinMax< scalar > scalarMinMax
A scalar min/max range.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.