Merge branch 'feature-snappyHexMesh-gapRefinement' into 'develop'

Feature snappy hex mesh gap refinement

Adding automatic gap refinement capability

See merge request !2
This commit is contained in:
Andrew Heather
2015-11-09 11:48:06 +00:00
39 changed files with 6037 additions and 147 deletions

View File

@ -1075,6 +1075,26 @@ int main(int argc, char *argv[])
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl; << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Optionally read limit shells
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const dictionary limitDict(refineDict.subOrEmptyDict("limitRegions"));
if (!limitDict.empty())
{
Info<< "Reading limit shells." << endl;
}
shellSurfaces limitShells(allGeometry, limitDict);
if (!limitDict.empty())
{
Info<< "Read refinement shells in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
}
// Read feature meshes // Read feature meshes
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
@ -1105,7 +1125,8 @@ int main(int argc, char *argv[])
overwrite, // overwrite mesh files? overwrite, // overwrite mesh files?
surfaces, // for surface intersection refinement surfaces, // for surface intersection refinement
features, // for feature edges/point based refinement features, // for feature edges/point based refinement
shells // for volume (inside/outside) refinement shells, // for volume (inside/outside) refinement
limitShells // limit of volume refinement
); );
Info<< "Calculated surface intersections in = " Info<< "Calculated surface intersections in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl; << mesh.time().cpuTimeIncrement() << " s" << nl << endl;

View File

@ -95,10 +95,10 @@ castellatedMeshControls
// actually be a lot less. // actually be a lot less.
maxGlobalCells 2000000; maxGlobalCells 2000000;
// The surface refinement loop might spend lots of iterations refining just a // The surface refinement loop might spend lots of iterations refining just
// few cells. This setting will cause refinement to stop if <= minimumRefine // a few cells. This setting will cause refinement to stop if
// are selected for refinement. Note: it will at least do one iteration // <= minimumRefine cells are selected for refinement. Note: it will
// (unless the number of cells to refine is 0) // at least do one iteration (unless the number of cells to refine is 0)
minRefinementCells 0; minRefinementCells 0;
// Allow a certain level of imbalance during refining // Allow a certain level of imbalance during refining
@ -244,11 +244,27 @@ castellatedMeshControls
} }
//sphere.stl //sphere.stl
//{ //{
// mode distance; // mode inside;
// levels ((1.0 5) (2.0 3)); // levels ((1.0 4));
// // Optional override of uniform refinement level such
// // that in small gaps we're getting more cells.
// // The specification is
// // - numGapCells : minimum number of cells in the gap
// // - minLevel : min refinement level at which to kick in
// // - maxLevel : upper refinement level
// // All three settings can be overridden on a surface by
// // surface basis in the refinementSurfaces section.
// gapLevel (<numGapCells> <minLevel> <maxlevel>);
//} //}
} }
// Limit refinement in geometric region
limitRegions
{
}
// Mesh selection // Mesh selection
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~

View File

@ -59,6 +59,8 @@ parallel/Allwmake $targetType $*
wmake $targetType ODE wmake $targetType ODE
wmake $targetType randomProcesses wmake $targetType randomProcesses
wmake $targetType fvMotionSolver
transportModels/Allwmake $targetType $* transportModels/Allwmake $targetType $*
thermophysicalModels/Allwmake $targetType $* thermophysicalModels/Allwmake $targetType $*
TurbulenceModels/Allwmake $targetType $* TurbulenceModels/Allwmake $targetType $*
@ -69,7 +71,6 @@ mesh/Allwmake $targetType $*
renumber/Allwmake $targetType $* renumber/Allwmake $targetType $*
fvAgglomerationMethods/Allwmake $targetType $* fvAgglomerationMethods/Allwmake $targetType $*
wmake $targetType fvMotionSolver
wmake $targetType engine wmake $targetType engine
wmake $targetType fvOptions wmake $targetType fvOptions
wmake $targetType regionCoupled wmake $targetType regionCoupled

View File

@ -2,8 +2,8 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -95,6 +95,12 @@ public:
t_(t) t_(t)
{} {}
//- Construct from integer
explicit volumeType(const int t)
:
t_(static_cast<volumeType::type>(t))
{}
// Member Functions // Member Functions

View File

@ -15,6 +15,7 @@ $(autoHexMesh)/meshRefinement/meshRefinement.C
$(autoHexMesh)/meshRefinement/meshRefinementMerge.C $(autoHexMesh)/meshRefinement/meshRefinementMerge.C
$(autoHexMesh)/meshRefinement/meshRefinementProblemCells.C $(autoHexMesh)/meshRefinement/meshRefinementProblemCells.C
$(autoHexMesh)/meshRefinement/meshRefinementRefine.C $(autoHexMesh)/meshRefinement/meshRefinementRefine.C
$(autoHexMesh)/meshRefinement/meshRefinementGapRefine.C
$(autoHexMesh)/meshRefinement/patchFaceOrientation.C $(autoHexMesh)/meshRefinement/patchFaceOrientation.C
$(autoHexMesh)/refinementFeatures/refinementFeatures.C $(autoHexMesh)/refinementFeatures/refinementFeatures.C

View File

@ -105,7 +105,10 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
false, // internalRefinement false, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -179,6 +182,128 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
} }
Foam::label Foam::autoRefineDriver::smallFeatureRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter = 0;
// See if any surface has an extendedGapLevel
labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
labelList shellMaxLevel(meshRefiner_.shells().maxGapLevel());
if (max(surfaceMaxLevel) == 0 && max(shellMaxLevel) == 0)
{
return iter;
}
for (; iter < maxIter; iter++)
{
Info<< nl
<< "Small surface feature refinement iteration " << iter << nl
<< "--------------------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement
false, // featureDistanceRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
true, // smallFeatureRefinement
false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum necessary
// iterations and not enough cells to refine.
if (nCellsToRefine == 0)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"small feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"small feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::surfaceOnlyRefine Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
( (
const refinementParameters& refineParams, const refinementParameters& refineParams,
@ -218,7 +343,10 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
false, // internalRefinement false, // internalRefinement
true, // surfaceRefinement true, // surfaceRefinement
true, // curvatureRefinement true, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -352,7 +480,10 @@ Foam::label Foam::autoRefineDriver::gapOnlyRefine
false, // internalRefinement false, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // smallFeatureRefinement
true, // gapRefinement true, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -527,6 +658,148 @@ Foam::label Foam::autoRefineDriver::gapOnlyRefine
} }
Foam::label Foam::autoRefineDriver::bigGapOnlyRefine
(
const refinementParameters& refineParams,
const bool spreadGapSize,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter = 0;
// See if any surface has an extendedGapLevel
labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
labelList shellMaxLevel(meshRefiner_.shells().maxGapLevel());
label overallMaxLevel(max(max(surfaceMaxLevel), max(shellMaxLevel)));
if (overallMaxLevel == 0)
{
return iter;
}
for (; iter < maxIter; iter++)
{
Info<< nl
<< "Big gap refinement iteration " << iter << nl
<< "------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement
false, // featureDistanceRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement
true, // bigGapRefinement
spreadGapSize, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromBigGap." << endl;
cellSet c(mesh, "candidateCellsFromBigGap", candidateCells);
c.instance() = meshRefiner_.timeName();
c.write();
}
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum necessary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= overallMaxLevel
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"big gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"big gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::danglingCellRefine Foam::label Foam::autoRefineDriver::danglingCellRefine
( (
const refinementParameters& refineParams, const refinementParameters& refineParams,
@ -1108,7 +1381,10 @@ Foam::label Foam::autoRefineDriver::shellRefine
true, // internalRefinement true, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -1630,6 +1906,13 @@ void Foam::autoRefineDriver::doRefine
0 // min cells to refine 0 // min cells to refine
); );
// Refine cells that contain a gap
smallFeatureRefine
(
refineParams,
100 // maxIter
);
// Refine based on surface // Refine based on surface
surfaceOnlyRefine surfaceOnlyRefine
( (
@ -1650,6 +1933,14 @@ void Foam::autoRefineDriver::doRefine
1 // nBufferLayers 1 // nBufferLayers
); );
// Refine consistently across narrow gaps (a form of shell refinement)
bigGapOnlyRefine
(
refineParams,
true, // spreadGapSize
100 // maxIter
);
// Internal mesh refinement // Internal mesh refinement
shellRefine shellRefine
( (

View File

@ -84,6 +84,13 @@ class autoRefineDriver
const label minRefine const label minRefine
); );
//- Refine all cells containing small surface features
label smallFeatureRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Refine all cells interacting with the surface //- Refine all cells interacting with the surface
label surfaceOnlyRefine label surfaceOnlyRefine
( (
@ -98,6 +105,14 @@ class autoRefineDriver
const label maxIter const label maxIter
); );
//- Refine all cells in large gaps
label bigGapOnlyRefine
(
const refinementParameters& refineParams,
const bool spreadGapSize,
const label maxIter
);
//- Refine cells with almost all sides refined //- Refine cells with almost all sides refined
label danglingCellRefine label danglingCellRefine
( (

View File

@ -215,6 +215,55 @@ void Foam::meshRefinement::calcNeighbourData
} }
void Foam::meshRefinement::calcCellCellRays
(
const pointField& neiCc,
const labelList& neiLevel,
const labelList& testFaces,
pointField& start,
pointField& end,
labelList& minLevel
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
start.setSize(testFaces.size());
end.setSize(testFaces.size());
minLevel.setSize(testFaces.size());
forAll(testFaces, i)
{
label faceI = testFaces[i];
label own = mesh_.faceOwner()[faceI];
if (mesh_.isInternalFace(faceI))
{
label nei = mesh_.faceNeighbour()[faceI];
start[i] = cellCentres[own];
end[i] = cellCentres[nei];
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
}
else
{
label bFaceI = faceI - mesh_.nInternalFaces();
start[i] = cellCentres[own];
end[i] = neiCc[bFaceI];
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
}
}
// Extend segments a bit
{
const vectorField smallVec(ROOTSMALL*(end-start));
start -= smallVec;
end += smallVec;
}
}
// Find intersections of edges (given by their two endpoints) with surfaces. // Find intersections of edges (given by their two endpoints) with surfaces.
// Returns first intersection if there are more than one. // Returns first intersection if there are more than one.
void Foam::meshRefinement::updateIntersections(const labelList& changedFaces) void Foam::meshRefinement::updateIntersections(const labelList& changedFaces)
@ -1187,7 +1236,8 @@ Foam::meshRefinement::meshRefinement
const bool overwrite, const bool overwrite,
const refinementSurfaces& surfaces, const refinementSurfaces& surfaces,
const refinementFeatures& features, const refinementFeatures& features,
const shellSurfaces& shells const shellSurfaces& shells,
const shellSurfaces& limitShells
) )
: :
mesh_(mesh), mesh_(mesh),
@ -1197,6 +1247,7 @@ Foam::meshRefinement::meshRefinement
surfaces_(surfaces), surfaces_(surfaces),
features_(features), features_(features),
shells_(shells), shells_(shells),
limitShells_(limitShells),
meshCutter_ meshCutter_
( (
mesh, mesh,

View File

@ -34,6 +34,7 @@ Description
SourceFiles SourceFiles
meshRefinement.C meshRefinement.C
meshRefinementBaffles.C meshRefinementBaffles.C
meshRefinementGapRefine.C
meshRefinementMerge.C meshRefinementMerge.C
meshRefinementProblemCells.C meshRefinementProblemCells.C
meshRefinementRefine.C meshRefinementRefine.C
@ -53,6 +54,8 @@ SourceFiles
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "wordPairHashTable.H" #include "wordPairHashTable.H"
#include "surfaceZonesInfo.H" #include "surfaceZonesInfo.H"
#include "volumeType.H"
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -176,6 +179,9 @@ private:
//- All shell-refinement interaction //- All shell-refinement interaction
const shellSurfaces& shells_; const shellSurfaces& shells_;
//- All limit-refinement interaction
const shellSurfaces& limitShells_;
//- Refinement engine //- Refinement engine
hexRef8 meshCutter_; hexRef8 meshCutter_;
@ -226,10 +232,18 @@ private:
); );
//- Calculate coupled boundary end vector and refinement level //- Calculate coupled boundary end vector and refinement level
void calcNeighbourData void calcNeighbourData(labelList& neiLevel, pointField& neiCc) const;
//- Calculate rays from cell-centre to cell-centre and corresponding
// min cell refinement level
void calcCellCellRays
( (
labelList& neiLevel, const pointField& neiCc,
pointField& neiCc const labelList& neiLevel,
const labelList& testFaces,
pointField& start,
pointField& end,
labelList& minLevel
) const; ) const;
//- Remove cells. Put exposedFaces into exposedPatchIDs. //- Remove cells. Put exposedFaces into exposedPatchIDs.
@ -241,12 +255,12 @@ private:
removeCells& cellRemover removeCells& cellRemover
); );
// Get cells which are inside any closed surface. Note that //- Get cells which are inside any closed surface. Note that
// all closed surfaces // all closed surfaces
// will have already been oriented to have keepPoint outside. // will have already been oriented to have keepPoint outside.
labelList getInsideCells(const word&) const; labelList getInsideCells(const word&) const;
// Do all to remove inside cells //- Do all to remove inside cells
autoPtr<mapPolyMesh> removeInsideCells autoPtr<mapPolyMesh> removeInsideCells
( (
const string& msg, const string& msg,
@ -302,6 +316,14 @@ private:
label& nRefine label& nRefine
) const; ) const;
//- Unmark cells for refinement based on limit-shells. Return number
// of limited cells.
label unmarkInternalRefinement
(
labelList& refineCell,
label& nRefine
) const;
//- Collect faces that are intersected and whose neighbours aren't //- Collect faces that are intersected and whose neighbours aren't
// yet marked for refinement. // yet marked for refinement.
labelList getRefineCandidateFaces labelList getRefineCandidateFaces
@ -319,6 +341,104 @@ private:
label& nRefine label& nRefine
) const; ) const;
//- Mark cells intersected by the surface if they are inside
// close gaps
label markSurfaceGapRefinement
(
const scalar planarCos,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const;
//- Generate single ray from nearPoint in direction of nearNormal
label generateRays
(
const point& nearPoint,
const vector& nearNormal,
const FixedList<label, 3>& gapInfo,
const volumeType& mode,
const label cLevel,
DynamicField<point>& start,
DynamicField<point>& end
) const;
//- Generate pairs of rays through cell centre
// Each ray pair has start, end, and expected gap size
label generateRays
(
const bool useSurfaceNormal,
const point& nearPoint,
const vector& nearNormal,
const FixedList<label, 3>& gapInfo,
const volumeType& mode,
const point& cc,
const label cLevel,
DynamicField<point>& start,
DynamicField<point>& end,
DynamicField<scalar>& gapSize,
DynamicField<point>& start2,
DynamicField<point>& end2,
DynamicField<scalar>& gapSize2
) const;
//- Select candidate cells (cells inside a shell with gapLevel
// specified)
void selectGapCandidates
(
const labelList& refineCell,
const label nRefine,
labelList& cellMap,
List<FixedList<label, 3> >& shellGapInfo,
List<volumeType>& shellGapMode
) const;
//- Merge gap information coming from shell and from surface
// (surface wins)
void mergeGapInfo
(
const FixedList<label, 3>& shellGapInfo,
const volumeType shellGapMode,
const FixedList<label, 3>& surfGapInfo,
const volumeType surfGapMode,
FixedList<label, 3>& gapInfo,
volumeType& gapMode
) const;
//- Mark cells for non-surface intersection based gap refinement
label markInternalGapRefinement
(
const scalar planarCos,
const bool spreadGapSize,
const label nAllowRefine,
labelList& refineCell,
label& nRefine,
labelList& numGapCells,
scalarField& gapSize
) const;
//- Refine cells containing small gaps
label markSmallFeatureRefinement
(
const scalar planarCos,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const;
//- Helper: count number of normals1 that are in normals2 //- Helper: count number of normals1 that are in normals2
label countMatches label countMatches
( (
@ -387,6 +507,7 @@ private:
void getIntersections void getIntersections
( (
const labelList& surfacesToTest, const labelList& surfacesToTest,
const labelList& neiLevel,
const pointField& neiCc, const pointField& neiCc,
const labelList& testFaces, const labelList& testFaces,
@ -567,7 +688,7 @@ private:
const labelList& cellToZone, const labelList& cellToZone,
const labelList& neiCellZone, const labelList& neiCellZone,
const labelList& faceToZone, const labelList& faceToZone,
const boolList& meshFlipMap, const PackedBoolList& meshFlipMap,
polyTopoChange& meshMod polyTopoChange& meshMod
) const; ) const;
@ -631,7 +752,7 @@ private:
const labelList& nMasterFaces, const labelList& nMasterFaces,
const labelList& faceToZone, const labelList& faceToZone,
const Map<label>& zoneToOrientation, const Map<label>& zoneToOrientation,
boolList& meshFlipMap PackedBoolList& meshFlipMap
) const; ) const;
@ -657,6 +778,7 @@ public:
const bool overwrite, const bool overwrite,
const refinementSurfaces&, const refinementSurfaces&,
const refinementFeatures&, const refinementFeatures&,
const shellSurfaces&,
const shellSurfaces& const shellSurfaces&
); );
@ -855,7 +977,10 @@ public:
const bool internalRefinement, const bool internalRefinement,
const bool surfaceRefinement, const bool surfaceRefinement,
const bool curvatureRefinement, const bool curvatureRefinement,
const bool smallFeatureRefinement,
const bool gapRefinement, const bool gapRefinement,
const bool bigGapRefinement,
const bool spreadGapSize,
const label maxGlobalCells, const label maxGlobalCells,
const label maxLocalCells const label maxLocalCells
) const; ) const;

View File

@ -175,6 +175,7 @@ Foam::label Foam::meshRefinement::createBaffle
void Foam::meshRefinement::getIntersections void Foam::meshRefinement::getIntersections
( (
const labelList& surfacesToTest, const labelList& surfacesToTest,
const labelList& neiLevel,
const pointField& neiCc, const pointField& neiCc,
const labelList& testFaces, const labelList& testFaces,
@ -198,8 +199,6 @@ void Foam::meshRefinement::getIntersections
<< str().name() << nl << endl; << str().name() << nl << endl;
} }
const pointField& cellCentres = mesh_.cellCentres();
globalRegion1.setSize(mesh_.nFaces()); globalRegion1.setSize(mesh_.nFaces());
globalRegion1 = -1; globalRegion1 = -1;
@ -213,29 +212,17 @@ void Foam::meshRefinement::getIntersections
pointField start(testFaces.size()); pointField start(testFaces.size());
pointField end(testFaces.size()); pointField end(testFaces.size());
forAll(testFaces, i)
{ {
label faceI = testFaces[i]; labelList minLevel;
calcCellCellRays
label own = mesh_.faceOwner()[faceI]; (
neiCc,
if (mesh_.isInternalFace(faceI)) neiLevel,
{ testFaces,
start[i] = cellCentres[own]; start,
end[i] = cellCentres[mesh_.faceNeighbour()[faceI]]; end,
} minLevel
else );
{
start[i] = cellCentres[own];
end[i] = neiCc[faceI-mesh_.nInternalFaces()];
}
}
// Extend segments a bit
{
const vectorField smallVec(ROOTSMALL*(end-start));
start -= smallVec;
end += smallVec;
} }
@ -319,6 +306,7 @@ void Foam::meshRefinement::getBafflePatches
getIntersections getIntersections
( (
surfaceZonesInfo::getUnnamedSurfaces(surfaces_.surfZones()), surfaceZonesInfo::getUnnamedSurfaces(surfaces_.surfZones()),
neiLevel,
neiCc, neiCc,
testFaces, testFaces,
globalRegion1, globalRegion1,
@ -2608,7 +2596,7 @@ void Foam::meshRefinement::consistentOrientation
const labelList& nMasterFacesPerEdge, const labelList& nMasterFacesPerEdge,
const labelList& faceToZone, const labelList& faceToZone,
const Map<label>& zoneToOrientation, const Map<label>& zoneToOrientation,
boolList& meshFlipMap PackedBoolList& meshFlipMap
) const ) const
{ {
const polyBoundaryMesh& bm = mesh_.boundaryMesh(); const polyBoundaryMesh& bm = mesh_.boundaryMesh();
@ -2858,7 +2846,7 @@ void Foam::meshRefinement::zonify
const labelList& cellToZone, const labelList& cellToZone,
const labelList& neiCellZone, const labelList& neiCellZone,
const labelList& faceToZone, const labelList& faceToZone,
const boolList& meshFlipMap, const PackedBoolList& meshFlipMap,
polyTopoChange& meshMod polyTopoChange& meshMod
) const ) const
{ {
@ -3902,6 +3890,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
getIntersections getIntersections
( (
identity(surfaces_.surfaces().size()), // surfacesToTest, identity(surfaces_.surfaces().size()), // surfacesToTest,
neiLevel,
neiCc, neiCc,
intersectedFaces(), // testFaces intersectedFaces(), // testFaces
globalRegion1, globalRegion1,
@ -4297,7 +4286,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
} }
// 2. Combine faceZoneNames allocated on different processors // 2.Combine faceZoneNames allocated on different processors
Pstream::mapCombineGather(zonesToFaceZone, eqOp<word>()); Pstream::mapCombineGather(zonesToFaceZone, eqOp<word>());
Pstream::mapCombineScatter(zonesToFaceZone); Pstream::mapCombineScatter(zonesToFaceZone);
@ -4438,7 +4427,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
// - do a consistent orientation // - do a consistent orientation
// - check number of faces with consistent orientation // - check number of faces with consistent orientation
// - if <0 flip the whole patch // - if <0 flip the whole patch
boolList meshFlipMap(mesh_.nFaces(), false); PackedBoolList meshFlipMap(mesh_.nFaces(), false);
{ {
// Collect all data on zone faces without cellZones on either side. // Collect all data on zone faces without cellZones on either side.
const indirectPrimitivePatch patch const indirectPrimitivePatch patch

File diff suppressed because it is too large Load Diff

View File

@ -742,7 +742,7 @@ Foam::label Foam::meshRefinement::markInternalDistanceToFeatureRefinement
} }
} }
// Do test to see whether cells is inside/outside shell with higher level // Do test to see whether cells are inside/outside shell with higher level
labelList maxLevel; labelList maxLevel;
features_.findHigherLevel(testCc, testLevels, maxLevel); features_.findHigherLevel(testCc, testLevels, maxLevel);
@ -820,7 +820,7 @@ Foam::label Foam::meshRefinement::markInternalRefinement
} }
} }
// Do test to see whether cells is inside/outside shell with higher level // Do test to see whether cells are inside/outside shell with higher level
labelList maxLevel; labelList maxLevel;
shells_.findHigherLevel(testCc, testLevels, maxLevel); shells_.findHigherLevel(testCc, testLevels, maxLevel);
@ -869,6 +869,56 @@ Foam::label Foam::meshRefinement::markInternalRefinement
} }
Foam::label Foam::meshRefinement::unmarkInternalRefinement
(
labelList& refineCell,
label& nRefine
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
label oldNRefine = nRefine;
// Collect cells to test
pointField testCc(nRefine);
labelList testLevels(nRefine);
label testI = 0;
forAll(cellLevel, cellI)
{
if (refineCell[cellI] >= 0)
{
testCc[testI] = cellCentres[cellI];
testLevels[testI] = cellLevel[cellI];
testI++;
}
}
// Do test to see whether cells are inside/outside shell with higher level
labelList levelShell;
limitShells_.findLevel(testCc, testLevels, levelShell);
// Mark for refinement. Note that we didn't store the original cellID so
// now just reloop in same order.
testI = 0;
forAll(cellLevel, cellI)
{
if (refineCell[cellI] >= 0)
{
if (levelShell[testI] != -1)
{
refineCell[cellI] = -1;
nRefine--;
}
testI++;
}
}
return returnReduce(oldNRefine-nRefine, sumOp<label>());
}
// Collect faces that are intersected and whose neighbours aren't yet marked // Collect faces that are intersected and whose neighbours aren't yet marked
// for refinement. // for refinement.
Foam::labelList Foam::meshRefinement::getRefineCandidateFaces Foam::labelList Foam::meshRefinement::getRefineCandidateFaces
@ -922,7 +972,6 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
) const ) const
{ {
const labelList& cellLevel = meshCutter_.cellLevel(); const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
label oldNRefine = nRefine; label oldNRefine = nRefine;
@ -941,36 +990,15 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
pointField end(testFaces.size()); pointField end(testFaces.size());
labelList minLevel(testFaces.size()); labelList minLevel(testFaces.size());
forAll(testFaces, i) calcCellCellRays
{ (
label faceI = testFaces[i]; neiCc,
neiLevel,
label own = mesh_.faceOwner()[faceI]; testFaces,
start,
if (mesh_.isInternalFace(faceI)) end,
{ minLevel
label nei = mesh_.faceNeighbour()[faceI]; );
start[i] = cellCentres[own];
end[i] = cellCentres[nei];
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
}
else
{
label bFaceI = faceI - mesh_.nInternalFaces();
start[i] = cellCentres[own];
end[i] = neiCc[bFaceI];
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
}
}
// Extend segments a bit
{
const vectorField smallVec(ROOTSMALL*(end-start));
start -= smallVec;
end += smallVec;
}
// Do test for higher intersections // Do test for higher intersections
@ -1130,6 +1158,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
pointField end(testFaces.size()); pointField end(testFaces.size());
labelList minLevel(testFaces.size()); labelList minLevel(testFaces.size());
// Note: uses isMasterFace otherwise could be call to calcCellCellRays
forAll(testFaces, i) forAll(testFaces, i)
{ {
label faceI = testFaces[i]; label faceI = testFaces[i];
@ -1719,7 +1748,6 @@ Foam::label Foam::meshRefinement::markProximityRefinement
) const ) const
{ {
const labelList& cellLevel = meshCutter_.cellLevel(); const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
label oldNRefine = nRefine; label oldNRefine = nRefine;
@ -1739,36 +1767,15 @@ Foam::label Foam::meshRefinement::markProximityRefinement
pointField end(testFaces.size()); pointField end(testFaces.size());
labelList minLevel(testFaces.size()); labelList minLevel(testFaces.size());
forAll(testFaces, i) calcCellCellRays
{ (
label faceI = testFaces[i]; neiCc,
neiLevel,
label own = mesh_.faceOwner()[faceI]; testFaces,
start,
if (mesh_.isInternalFace(faceI)) end,
{ minLevel
label nei = mesh_.faceNeighbour()[faceI]; );
start[i] = cellCentres[own];
end[i] = cellCentres[nei];
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
}
else
{
label bFaceI = faceI - mesh_.nInternalFaces();
start[i] = cellCentres[own];
end[i] = neiCc[bFaceI];
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
}
}
// Extend segments a bit
{
const vectorField smallVec(ROOTSMALL*(end-start));
start -= smallVec;
end += smallVec;
}
// Test for all intersections (with surfaces of higher gap level than // Test for all intersections (with surfaces of higher gap level than
@ -2045,7 +2052,10 @@ Foam::labelList Foam::meshRefinement::refineCandidates
const bool internalRefinement, const bool internalRefinement,
const bool surfaceRefinement, const bool surfaceRefinement,
const bool curvatureRefinement, const bool curvatureRefinement,
const bool smallFeatureRefinement,
const bool gapRefinement, const bool gapRefinement,
const bool bigGapRefinement,
const bool spreadGapSize,
const label maxGlobalCells, const label maxGlobalCells,
const label maxLocalCells const label maxLocalCells
) const ) const
@ -2096,6 +2106,8 @@ Foam::labelList Foam::meshRefinement::refineCandidates
calcNeighbourData(neiLevel, neiCc); calcNeighbourData(neiLevel, neiCc);
const scalar planarCos = Foam::cos(degToRad(planarAngle));
// Cells pierced by feature lines // Cells pierced by feature lines
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -2163,6 +2175,30 @@ Foam::labelList Foam::meshRefinement::refineCandidates
); );
Info<< "Marked for refinement due to surface intersection " Info<< "Marked for refinement due to surface intersection "
<< ": " << nSurf << " cells." << endl; << ": " << nSurf << " cells." << endl;
// Refine intersected-cells only inside gaps. See
// markInternalGapRefinement to refine all cells inside gaps.
if
(
planarCos >= -1
&& planarCos <= 1
&& max(shells_.maxGapLevel()) > 0
)
{
label nGapSurf = markSurfaceGapRefinement
(
planarCos,
nAllowRefine,
neiLevel,
neiCc,
refineCell,
nRefine
);
Info<< "Marked for refinement due to surface intersection"
<< " (at gaps)"
<< ": " << nGapSurf << " cells." << endl;
}
} }
// Refinement based on curvature of surface // Refinement based on curvature of surface
@ -2190,7 +2226,33 @@ Foam::labelList Foam::meshRefinement::refineCandidates
} }
const scalar planarCos = Foam::cos(degToRad(planarAngle)); // Refinement based on features smaller than cell size
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if
(
smallFeatureRefinement
&& (planarCos >= -1 && planarCos <= 1)
&& max(shells_.maxGapLevel()) > 0
)
{
label nGap = markSmallFeatureRefinement
(
planarCos,
nAllowRefine,
neiLevel,
neiCc,
refineCell,
nRefine
);
Info<< "Marked for refinement due to close opposite surfaces "
<< ": " << nGap << " cells." << endl;
}
// Refinement based on gap (only neighbouring cells)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if if
( (
@ -2217,6 +2279,50 @@ Foam::labelList Foam::meshRefinement::refineCandidates
} }
// Refinement based on gaps larger than cell size
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if
(
bigGapRefinement
&& (planarCos >= -1 && planarCos <= 1)
&& max(shells_.maxGapLevel()) > 0
)
{
// Refine based on gap information provided by shell and nearest
// surface
labelList numGapCells;
scalarField gapSize;
label nGap = markInternalGapRefinement
(
planarCos,
spreadGapSize,
nAllowRefine,
refineCell,
nRefine,
numGapCells,
gapSize
);
Info<< "Marked for refinement due to opposite surfaces"
<< " "
<< ": " << nGap << " cells." << endl;
}
// Limit refinement
// ~~~~~~~~~~~~~~~~
{
label nUnmarked = unmarkInternalRefinement(refineCell, nRefine);
if (nUnmarked > 0)
{
Info<< "Unmarked for refinement due to limit shells"
<< " : " << nUnmarked << " cells." << endl;
}
}
// Pack cells-to-refine // Pack cells-to-refine
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::transportData
Description
Holds information (coordinate and distance). Walks out 0.5*distance.
SourceFiles
transportDataI.H
transportData.C
\*---------------------------------------------------------------------------*/
#ifndef transportData_H
#define transportData_H
#include "wallPointData.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyMesh;
/*---------------------------------------------------------------------------*\
Class transportData Declaration
\*---------------------------------------------------------------------------*/
class transportData
:
public wallPointData<scalar>
{
public:
//- Class used to pass additional data in
class trackData
{
public:
//- Per face the index of the surface hit
const labelList& surfaceIndex_;
trackData(const labelList& surfaceIndex)
:
surfaceIndex_(surfaceIndex)
{}
};
private:
// Private Member Functions
//- Evaluate distance to point. Update distSqr, origin from whomever
// is nearer pt. Return true if w2 is closer to point,
// false otherwise.
template<class TrackingData>
inline bool update
(
const point&,
const transportData& w2,
const scalar tol,
TrackingData& td
);
public:
// Constructors
//- Construct null
inline transportData();
//- Construct from origin, gapSize, distance
inline transportData
(
const point& origin,
const scalar gapSize,
const scalar distSqr
);
// Member Functions
// Needed by FaceCellWave
//- Influence of neighbouring face.
// Calls update(...) with cellCentre of cellI
template<class TrackingData>
inline bool updateCell
(
const polyMesh& mesh,
const label thisCellI,
const label neighbourFaceI,
const transportData& neighbourWallInfo,
const scalar tol,
TrackingData& td
);
//- Influence of neighbouring cell.
// Calls update(...) with faceCentre of faceI
template<class TrackingData>
inline bool updateFace
(
const polyMesh& mesh,
const label thisFaceI,
const label neighbourCellI,
const transportData& neighbourWallInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same face.
// Merge new and old info.
// Calls update(...) with faceCentre of faceI
template<class TrackingData>
inline bool updateFace
(
const polyMesh& mesh,
const label thisFaceI,
const transportData& neighbourWallInfo,
const scalar tol,
TrackingData& td
);
};
//- Data associated with transportData type is same as underlying
template<>
inline bool contiguous<transportData>()
{
return contiguous<wallPointData<scalar> >();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "transportDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "polyMesh.H"
#include "transform.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Update this with w2 if w2 nearer to pt.
template<class TrackingData>
inline bool Foam::transportData::update
(
const point& pt,
const transportData& w2,
const scalar tol,
TrackingData& td
)
{
scalar dist2 = magSqr(pt - w2.origin());
if (valid(td))
{
scalar diff = distSqr() - dist2;
if (diff < 0)
{
// Already nearer to pt
return false;
}
if ((diff < SMALL) || ((distSqr() > SMALL) && (diff/distSqr() < tol)))
{
// Don't propagate small changes
return false;
}
}
// Either *this is not yet valid or w2 is closer
{
// current not yet set so use any value
distSqr() = dist2;
origin() = w2.origin();
data() = w2.data();
if (distSqr() > sqr(0.25*data()))
{
// No need to transport gap data since too far away
return false;
}
return true;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::transportData::transportData()
:
wallPointData<scalar>()
{}
inline Foam::transportData::transportData
(
const point& origin,
const scalar gapSize,
const scalar distSqr
)
:
wallPointData<scalar>(origin, gapSize, distSqr)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class TrackingData>
inline bool Foam::transportData::updateCell
(
const polyMesh& mesh,
const label cellI,
const label faceI,
const transportData& neighbourWallInfo,
const scalar tol,
TrackingData& td
)
{
if (td.surfaceIndex_[faceI] != -1)
{
return false;
}
const vectorField& cellCentres = mesh.primitiveMesh::cellCentres();
bool updated = update
(
cellCentres[cellI],
neighbourWallInfo,
tol,
td
);
return updated;
}
template<class TrackingData>
inline bool Foam::transportData::updateFace
(
const polyMesh& mesh,
const label thisFaceI,
const label neighbourCellI,
const transportData& neighbourWallInfo,
const scalar tol,
TrackingData& td
)
{
if (td.surfaceIndex_[thisFaceI] != -1)
{
return false;
}
return update
(
mesh.faceCentres()[thisFaceI],
neighbourWallInfo,
tol,
td
);
}
template<class TrackingData>
inline bool Foam::transportData::updateFace
(
const polyMesh& mesh,
const label thisFaceI,
const transportData& neighbourWallInfo,
const scalar tol,
TrackingData& td
)
{
if (td.surfaceIndex_[thisFaceI] != -1)
{
return false;
}
return update
(
mesh.faceCentres()[thisFaceI],
neighbourWallInfo,
tol,
td
);
}
// ************************************************************************* //

View File

@ -157,11 +157,22 @@ Foam::refinementSurfaces::refinementSurfaces
labelList globalMinLevel(surfI, 0); labelList globalMinLevel(surfI, 0);
labelList globalMaxLevel(surfI, 0); labelList globalMaxLevel(surfI, 0);
labelList globalLevelIncr(surfI, 0); labelList globalLevelIncr(surfI, 0);
FixedList<label, 3> nullGapLevel;
nullGapLevel[0] = 0;
nullGapLevel[1] = 0;
nullGapLevel[2] = 0;
List<FixedList<label, 3> > globalGapLevel(surfI);
List<volumeType> globalGapMode(surfI);
scalarField globalAngle(surfI, -GREAT); scalarField globalAngle(surfI, -GREAT);
PtrList<dictionary> globalPatchInfo(surfI); PtrList<dictionary> globalPatchInfo(surfI);
List<Map<label> > regionMinLevel(surfI); List<Map<label> > regionMinLevel(surfI);
List<Map<label> > regionMaxLevel(surfI); List<Map<label> > regionMaxLevel(surfI);
List<Map<label> > regionLevelIncr(surfI); List<Map<label> > regionLevelIncr(surfI);
List<Map<FixedList<label, 3> > > regionGapLevel(surfI);
List<Map<volumeType> > regionGapMode(surfI);
List<Map<scalar> > regionAngle(surfI); List<Map<scalar> > regionAngle(surfI);
List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI); List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI);
@ -212,6 +223,44 @@ Foam::refinementSurfaces::refinementSurfaces
<< exit(FatalIOError); << exit(FatalIOError);
} }
// Optional gapLevel specification
globalGapLevel[surfI] = dict.lookupOrDefault
(
"gapLevel",
nullGapLevel
);
globalGapMode[surfI] = volumeType::names
[
dict.lookupOrDefault<word>
(
"gapMode",
volumeType::names[volumeType::MIXED]
)
];
if
(
globalGapMode[surfI] == volumeType::UNKNOWN
|| globalGapLevel[surfI][0] < 0
|| globalGapLevel[surfI][1] < 0
|| globalGapLevel[surfI][2] < 0
|| globalGapLevel[surfI][1] > globalGapLevel[surfI][2]
)
{
FatalIOErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&",
dict
) << "Illegal gapLevel specification for surface "
<< names_[surfI]
<< " : gapLevel:" << globalGapLevel[surfI]
<< " gapMode:" << volumeType::names[globalGapMode[surfI]]
<< exit(FatalIOError);
}
const searchableSurface& surface = allGeometry_[surfaces_[surfI]]; const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
// Surface zones // Surface zones
@ -275,6 +324,54 @@ Foam::refinementSurfaces::refinementSurfaces
<< exit(FatalIOError); << exit(FatalIOError);
} }
// Optional gapLevel specification
FixedList<label, 3> gapSpec
(
regionDict.lookupOrDefault
(
"gapLevel",
nullGapLevel
)
);
regionGapLevel[surfI].insert(regionI, gapSpec);
volumeType gapModeSpec
(
volumeType::names
[
regionDict.lookupOrDefault<word>
(
"gapMode",
volumeType::names[volumeType::MIXED]
)
]
);
regionGapMode[surfI].insert(regionI, gapModeSpec);
if
(
gapModeSpec == volumeType::UNKNOWN
|| gapSpec[0] < 0
|| gapSpec[1] < 0
|| gapSpec[2] < 0
|| gapSpec[1] > gapSpec[2]
)
{
FatalIOErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&,"
" const dictionary>&",
dict
) << "Illegal gapLevel specification for surface "
<< names_[surfI]
<< " : gapLevel:" << gapSpec
<< " gapMode:" << volumeType::names[gapModeSpec]
<< exit(FatalIOError);
}
if (regionDict.found("perpendicularAngle")) if (regionDict.found("perpendicularAngle"))
{ {
regionAngle[surfI].insert regionAngle[surfI].insert
@ -331,6 +428,10 @@ Foam::refinementSurfaces::refinementSurfaces
maxLevel_ = 0; maxLevel_ = 0;
gapLevel_.setSize(nRegions); gapLevel_.setSize(nRegions);
gapLevel_ = -1; gapLevel_ = -1;
extendedGapLevel_.setSize(nRegions);
extendedGapLevel_ = nullGapLevel;
extendedGapMode_.setSize(nRegions);
extendedGapMode_ = volumeType::UNKNOWN;
perpendicularAngle_.setSize(nRegions); perpendicularAngle_.setSize(nRegions);
perpendicularAngle_ = -GREAT; perpendicularAngle_ = -GREAT;
patchInfo_.setSize(nRegions); patchInfo_.setSize(nRegions);
@ -349,7 +450,8 @@ Foam::refinementSurfaces::refinementSurfaces
gapLevel_[globalRegionI] = gapLevel_[globalRegionI] =
maxLevel_[globalRegionI] maxLevel_[globalRegionI]
+ globalLevelIncr[surfI]; + globalLevelIncr[surfI];
extendedGapLevel_[globalRegionI] = globalGapLevel[surfI];
extendedGapMode_[globalRegionI] = globalGapMode[surfI];
perpendicularAngle_[globalRegionI] = globalAngle[surfI]; perpendicularAngle_[globalRegionI] = globalAngle[surfI];
if (globalPatchInfo.set(surfI)) if (globalPatchInfo.set(surfI))
{ {
@ -371,6 +473,10 @@ Foam::refinementSurfaces::refinementSurfaces
gapLevel_[globalRegionI] = gapLevel_[globalRegionI] =
maxLevel_[globalRegionI] maxLevel_[globalRegionI]
+ regionLevelIncr[surfI][iter.key()]; + regionLevelIncr[surfI][iter.key()];
extendedGapLevel_[globalRegionI] =
regionGapLevel[surfI][iter.key()];
extendedGapMode_[globalRegionI] =
regionGapMode[surfI][iter.key()];
} }
forAllConstIter(Map<scalar>, regionAngle[surfI], iter) forAllConstIter(Map<scalar>, regionAngle[surfI], iter)
{ {
@ -482,12 +588,28 @@ Foam::refinementSurfaces::refinementSurfaces
// } // }
Foam::labelList Foam::refinementSurfaces::maxGapLevel() const
{
labelList surfaceMax(surfaces_.size(), 0);
forAll(surfaces_, surfI)
{
const wordList& regionNames = allGeometry_[surfaces_[surfI]].regions();
forAll(regionNames, regionI)
{
label globalI = globalRegion(surfI, regionI);
const FixedList<label, 3>& gapInfo = extendedGapLevel_[globalI];
surfaceMax[surfI] = max(surfaceMax[surfI], gapInfo[2]);
}
}
return surfaceMax;
}
// Precalculate the refinement level for every element of the searchable // Precalculate the refinement level for every element of the searchable
// surface. // surface.
void Foam::refinementSurfaces::setMinLevelFields void Foam::refinementSurfaces::setMinLevelFields(const shellSurfaces& shells)
(
const shellSurfaces& shells
)
{ {
forAll(surfaces_, surfI) forAll(surfaces_, surfI)
{ {
@ -1208,6 +1330,99 @@ void Foam::refinementSurfaces::findNearestIntersection
} }
void Foam::refinementSurfaces::findNearestIntersection
(
const pointField& start,
const pointField& end,
labelList& surface1,
vectorField& normal1
) const
{
// Initialize arguments
surface1.setSize(start.size());
surface1 = -1;
normal1.setSize(start.size());
normal1 = vector::zero;
// Current end of segment to test.
pointField nearest(end);
// Work array
List<pointIndexHit> nearestInfo(start.size());
labelList region;
vectorField normal;
forAll(surfaces_, surfI)
{
const searchableSurface& geom = allGeometry_[surfaces_[surfI]];
// See if any intersection between start and current nearest
geom.findLine(start, nearest, nearestInfo);
geom.getNormal(nearestInfo, normal);
forAll(nearestInfo, pointI)
{
if (nearestInfo[pointI].hit())
{
surface1[pointI] = surfI;
normal1[pointI] = normal[pointI];
nearest[pointI] = nearestInfo[pointI].hitPoint();
}
}
}
}
void Foam::refinementSurfaces::findNearestIntersection
(
const pointField& start,
const pointField& end,
labelList& surface1,
List<pointIndexHit>& hitInfo1,
vectorField& normal1
) const
{
// 1. intersection from start to end
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialize arguments
surface1.setSize(start.size());
surface1 = -1;
hitInfo1.setSize(start.size());
hitInfo1 = pointIndexHit();
normal1.setSize(start.size());
normal1 = vector::zero;
// Current end of segment to test.
pointField nearest(end);
// Work array
List<pointIndexHit> nearestInfo(start.size());
labelList region;
vectorField normal;
forAll(surfaces_, surfI)
{
const searchableSurface& geom = allGeometry_[surfaces_[surfI]];
// See if any intersection between start and current nearest
geom.findLine(start, nearest, nearestInfo);
geom.getNormal(nearestInfo, normal);
forAll(nearestInfo, pointI)
{
if (nearestInfo[pointI].hit())
{
surface1[pointI] = surfI;
hitInfo1[pointI] = nearestInfo[pointI];
normal1[pointI] = normal[pointI];
nearest[pointI] = nearestInfo[pointI].hitPoint();
}
}
}
}
void Foam::refinementSurfaces::findAnyIntersection void Foam::refinementSurfaces::findAnyIntersection
( (
const pointField& start, const pointField& start,

View File

@ -42,6 +42,7 @@ SourceFiles
#include "vectorList.H" #include "vectorList.H"
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "surfaceZonesInfo.H" #include "surfaceZonesInfo.H"
#include "volumeType.H"
#include "pointList.H" #include "pointList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -85,6 +86,12 @@ class refinementSurfaces
//- From global region number to small-gap level //- From global region number to small-gap level
labelList gapLevel_; labelList gapLevel_;
//- From global region number to small-gap level specification
List<FixedList<label, 3> > extendedGapLevel_;
//- From global region number to side of surface to detect
List<volumeType> extendedGapMode_;
//- From global region number to perpendicular angle //- From global region number to perpendicular angle
scalarField perpendicularAngle_; scalarField perpendicularAngle_;
@ -188,6 +195,23 @@ public:
return gapLevel_; return gapLevel_;
} }
//- From global region number to specification of gap and its
// refinement: 3 labels specifying
// - minimum wanted number of cells in the gap
// - minimum cell level when to start trying to detect gaps
// - maximum cell level to refine to (so do not detect gaps if
// cell >= maximum level)
const List<FixedList<label, 3> >& extendedGapLevel() const
{
return extendedGapLevel_;
}
//- From global region number to side of surface to detect
const List<volumeType>& extendedGapMode() const
{
return extendedGapMode_;
}
//- From global region number to perpendicular angle //- From global region number to perpendicular angle
const scalarField& perpendicularAngle() const const scalarField& perpendicularAngle() const
{ {
@ -226,6 +250,9 @@ public:
return minLevel_.size(); return minLevel_.size();
} }
//- Per surface the maximum extendedGapLevel over all its regions
labelList maxGapLevel() const;
//- Calculate minLevelFields //- Calculate minLevelFields
void setMinLevelFields void setMinLevelFields
( (
@ -314,6 +341,25 @@ public:
vectorField& normal2 vectorField& normal2
) const; ) const;
//- Find nearest (to start only) intersection of edge
void findNearestIntersection
(
const pointField& start,
const pointField& end,
labelList& surfaces,
vectorField& normal
) const;
//- Find nearest (to start only) intersection of edge
void findNearestIntersection
(
const pointField& start,
const pointField& end,
labelList& surfaces,
List<pointIndexHit>&,
vectorField& normal
) const;
//- Used for debugging only: find intersection of edge. //- Used for debugging only: find intersection of edge.
void findAnyIntersection void findAnyIntersection
( (

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -124,7 +124,7 @@ void Foam::shellSurfaces::setAndCheckLevels
} }
else else
{ {
if (!allGeometry_[shells_[shellI]].hasVolumeType()) if (!shell.hasVolumeType())
{ {
FatalErrorIn FatalErrorIn
( (
@ -152,6 +152,46 @@ void Foam::shellSurfaces::setAndCheckLevels
} }
void Foam::shellSurfaces::checkGapLevels
(
const dictionary& shellDict,
const label shellI,
const List<FixedList<label, 3> >& levels
)
{
const searchableSurface& shell = allGeometry_[shells_[shellI]];
forAll(levels, regionI)
{
const FixedList<label, 3>& info = levels[regionI];
if (info[2] > 0)
{
if (modes_[shellI] == DISTANCE)
{
FatalIOErrorIn
(
"shellSurfaces::shellSurfaces(..)",
shellDict
) << "'gapLevel' specification cannot be used with mode "
<< refineModeNames_[DISTANCE]
<< " for shell " << shell.name()
<< exit(FatalIOError);
}
}
}
// Hardcode for region 0
if (levels[0][0] > 0)
{
Info<< "Refinement level up to " << levels[0][2]
<< " for all cells in gaps for shell "
<< shell.name() << endl;
}
}
// Specifically orient triSurfaces using a calculated point outside. // Specifically orient triSurfaces using a calculated point outside.
// Done since quite often triSurfaces not of consistent orientation which // Done since quite often triSurfaces not of consistent orientation which
// is (currently) necessary for sideness calculation // is (currently) necessary for sideness calculation
@ -288,18 +328,18 @@ void Foam::shellSurfaces::findHigherLevel
); );
// Update maxLevel // Update maxLevel
forAll(nearInfo, candidateI) forAll(nearInfo, i)
{ {
if (nearInfo[candidateI].hit()) if (nearInfo[i].hit())
{ {
// Check which level it actually is in. // Check which level it actually is in.
label minDistI = findLower label minDistI = findLower
( (
distances, distances,
mag(nearInfo[candidateI].hitPoint()-candidates[candidateI]) mag(nearInfo[i].hitPoint()-candidates[i])
); );
label pointI = candidateMap[candidateI]; label pointI = candidateMap[i];
// pt is inbetween shell[minDistI] and shell[minDistI+1] // pt is inbetween shell[minDistI] and shell[minDistI+1]
maxLevel[pointI] = levels[minDistI+1]; maxLevel[pointI] = levels[minDistI+1];
@ -356,6 +396,197 @@ void Foam::shellSurfaces::findHigherLevel
} }
void Foam::shellSurfaces::findHigherGapLevel
(
const pointField& pt,
const labelList& ptLevel,
const label shellI,
labelList& gapShell,
List<FixedList<label, 3> >& gapInfo,
List<volumeType>& gapMode
) const
{
//TBD: hardcoded for region 0 information
const FixedList<label, 3>& info = extendedGapLevel_[shellI][0];
volumeType mode = extendedGapMode_[shellI][0];
if (info[2] == 0)
{
return;
}
// Collect all those points that have a current maxLevel less than the
// shell.
labelList candidateMap(pt.size());
label candidateI = 0;
forAll(ptLevel, pointI)
{
if (ptLevel[pointI] >= info[1] && ptLevel[pointI] < info[2])
{
candidateMap[candidateI++] = pointI;
}
}
candidateMap.setSize(candidateI);
// Do the expensive nearest test only for the candidate points.
List<volumeType> volType;
allGeometry_[shells_[shellI]].getVolumeType
(
pointField(pt, candidateMap),
volType
);
forAll(volType, i)
{
label pointI = candidateMap[i];
bool isInside = (volType[i] == volumeType::INSIDE);
if
(
(
(modes_[shellI] == INSIDE && isInside)
|| (modes_[shellI] == OUTSIDE && !isInside)
)
&& info[2] > gapInfo[pointI][2]
)
{
gapShell[pointI] = shellI;
gapInfo[pointI] = info;
gapMode[pointI] = mode;
}
}
}
void Foam::shellSurfaces::findLevel
(
const pointField& pt,
const label shellI,
labelList& minLevel,
labelList& shell
) const
{
const labelList& levels = levels_[shellI];
if (modes_[shellI] == DISTANCE)
{
// Distance mode.
const scalarField& distances = distances_[shellI];
// Collect all those points that have a current level equal/greater
// (any of) the shell. Also collect the furthest distance allowable
// to any shell with a higher level.
pointField candidates(pt.size());
labelList candidateMap(pt.size());
scalarField candidateDistSqr(pt.size());
label candidateI = 0;
forAll(shell, pointI)
{
if (shell[pointI] == -1)
{
forAllReverse(levels, levelI)
{
if (levels[levelI] <= minLevel[pointI])
{
candidates[candidateI] = pt[pointI];
candidateMap[candidateI] = pointI;
candidateDistSqr[candidateI] = sqr(distances[levelI]);
candidateI++;
break;
}
}
}
}
candidates.setSize(candidateI);
candidateMap.setSize(candidateI);
candidateDistSqr.setSize(candidateI);
// Do the expensive nearest test only for the candidate points.
List<pointIndexHit> nearInfo;
allGeometry_[shells_[shellI]].findNearest
(
candidates,
candidateDistSqr,
nearInfo
);
// Update maxLevel
forAll(nearInfo, i)
{
if (nearInfo[i].hit())
{
// Check which level it actually is in.
label minDistI = findLower
(
distances,
mag(nearInfo[i].hitPoint()-candidates[i])
);
label pointI = candidateMap[i];
// pt is inbetween shell[minDistI] and shell[minDistI+1]
shell[pointI] = shellI;
minLevel[pointI] = levels[minDistI+1];
}
}
}
else
{
// Inside/outside mode
// Collect all those points that have a current maxLevel less than the
// shell.
pointField candidates(pt.size());
labelList candidateMap(pt.size());
label candidateI = 0;
forAll(shell, pointI)
{
if (shell[pointI] == -1 && levels[0] <= minLevel[pointI])
{
candidates[candidateI] = pt[pointI];
candidateMap[candidateI] = pointI;
candidateI++;
}
}
candidates.setSize(candidateI);
candidateMap.setSize(candidateI);
// Do the expensive nearest test only for the candidate points.
List<volumeType> volType;
allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
forAll(volType, i)
{
if
(
(
modes_[shellI] == INSIDE
&& volType[i] == volumeType::INSIDE
)
|| (
modes_[shellI] == OUTSIDE
&& volType[i] == volumeType::OUTSIDE
)
)
{
label pointI = candidateMap[i];
shell[pointI] = shellI;
minLevel[pointI] = levels[0];
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::shellSurfaces::shellSurfaces Foam::shellSurfaces::shellSurfaces
@ -387,6 +618,15 @@ Foam::shellSurfaces::shellSurfaces
distances_.setSize(shellI); distances_.setSize(shellI);
levels_.setSize(shellI); levels_.setSize(shellI);
extendedGapLevel_.setSize(shellI);
extendedGapMode_.setSize(shellI);
FixedList<label, 3> nullGapLevel;
nullGapLevel[0] = 0;
nullGapLevel[1] = 0;
nullGapLevel[2] = 0;
HashSet<word> unmatchedKeys(shellsDict.toc()); HashSet<word> unmatchedKeys(shellsDict.toc());
shellI = 0; shellI = 0;
@ -407,6 +647,85 @@ Foam::shellSurfaces::shellSurfaces
// Read pairs of distance+level // Read pairs of distance+level
setAndCheckLevels(shellI, dict.lookup("levels")); setAndCheckLevels(shellI, dict.lookup("levels"));
// Gap specification
// ~~~~~~~~~~~~~~~~~
// Shell-wide gap level specification
const searchableSurface& surface = allGeometry_[geomI];
const wordList& regionNames = surface.regions();
FixedList<label, 3> gapSpec
(
dict.lookupOrDefault
(
"gapLevel",
nullGapLevel
)
);
extendedGapLevel_[shellI].setSize(regionNames.size());
extendedGapLevel_[shellI] = gapSpec;
volumeType gapModeSpec
(
volumeType::names
[
dict.lookupOrDefault<word>
(
"gapMode",
volumeType::names[volumeType::MIXED]
)
]
);
extendedGapMode_[shellI].setSize(regionNames.size());
extendedGapMode_[shellI] = gapModeSpec;
// Override on a per-region basis?
if (dict.found("regions"))
{
const dictionary& regionsDict = dict.subDict("regions");
forAll(regionNames, regionI)
{
if (regionsDict.found(regionNames[regionI]))
{
// Get the dictionary for region
const dictionary& regionDict = regionsDict.subDict
(
regionNames[regionI]
);
FixedList<label, 3> gapSpec
(
regionDict.lookupOrDefault
(
"gapLevel",
nullGapLevel
)
);
extendedGapLevel_[shellI][regionI] = gapSpec;
volumeType gapModeSpec
(
volumeType::names
[
regionDict.lookupOrDefault<word>
(
"gapMode",
volumeType::names[volumeType::MIXED]
)
]
);
extendedGapMode_[shellI][regionI] = gapModeSpec;
}
}
}
checkGapLevels(dict, shellI, extendedGapLevel_[shellI]);
shellI++; shellI++;
} }
} }
@ -444,6 +763,22 @@ Foam::label Foam::shellSurfaces::maxLevel() const
} }
Foam::labelList Foam::shellSurfaces::maxGapLevel() const
{
labelList surfaceMax(extendedGapLevel_.size(), 0);
forAll(extendedGapLevel_, shellI)
{
const List<FixedList<label, 3> >& levels = extendedGapLevel_[shellI];
forAll(levels, i)
{
surfaceMax[shellI] = max(surfaceMax[shellI], levels[i][2]);
}
}
return surfaceMax;
}
void Foam::shellSurfaces::findHigherLevel void Foam::shellSurfaces::findHigherLevel
( (
const pointField& pt, const pointField& pt,
@ -461,4 +796,66 @@ void Foam::shellSurfaces::findHigherLevel
} }
void Foam::shellSurfaces::findHigherGapLevel
(
const pointField& pt,
const labelList& ptLevel,
labelList& gapShell,
List<FixedList<label, 3> >& gapInfo,
List<volumeType>& gapMode
) const
{
gapShell.setSize(pt.size());
gapShell = -1;
FixedList<label, 3> nullGapLevel;
nullGapLevel[0] = 0;
nullGapLevel[1] = 0;
nullGapLevel[2] = 0;
gapInfo.setSize(pt.size());
gapInfo = nullGapLevel;
gapMode.setSize(pt.size());
gapMode = volumeType::MIXED;
forAll(shells_, shellI)
{
findHigherGapLevel(pt, ptLevel, shellI, gapShell, gapInfo, gapMode);
}
}
void Foam::shellSurfaces::findHigherGapLevel
(
const pointField& pt,
const labelList& ptLevel,
List<FixedList<label, 3> >& gapInfo,
List<volumeType>& gapMode
) const
{
labelList gapShell;
findHigherGapLevel(pt, ptLevel, gapShell, gapInfo, gapMode);
}
void Foam::shellSurfaces::findLevel
(
const pointField& pt,
const labelList& ptLevel,
labelList& shell
) const
{
shell.setSize(pt.size());
shell = -1;
labelList minLevel(ptLevel);
forAll(shells_, shellI)
{
findLevel(pt, shellI, minLevel, shell);
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,8 +2,8 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -85,6 +85,15 @@ private:
labelListList levels_; labelListList levels_;
// Gap level refinement
//- Per shell, per region the small-gap level specification
List<List<FixedList<label, 3> > > extendedGapLevel_;
//- Per shell, per region the small-gap level specification
List<List<volumeType> > extendedGapMode_;
// Private data // Private data
//- refineMode names //- refineMode names
@ -93,15 +102,24 @@ private:
// Private Member Functions // Private Member Functions
//- Helper function for initialisation. //- Helper function for initialisation of levels
void setAndCheckLevels void setAndCheckLevels
( (
const label shellI, const label shellI,
const List<Tuple2<scalar, label> >& const List<Tuple2<scalar, label> >&
); );
//- Helper function for checking of gap information
void checkGapLevels
(
const dictionary&,
const label shellI,
const List<FixedList<label, 3> >& levels
);
void orient(); void orient();
//- Find first shell with a level higher than maxLevel
void findHigherLevel void findHigherLevel
( (
const pointField& pt, const pointField& pt,
@ -109,6 +127,27 @@ private:
labelList& maxLevel labelList& maxLevel
) const; ) const;
//- Update highest min gap level
void findHigherGapLevel
(
const pointField& pt,
const labelList& ptLevel,
const label shellI,
labelList& gapShell,
List<FixedList<label, 3> >& gapInfo,
List<volumeType>& gapMode
) const;
//- Find first shell with a level lower or equal to minLevel. Update
// minLevel and shell.
void findLevel
(
const pointField& pt,
const label shellI,
labelList& minLevel,
labelList& shell
) const;
public: public:
// Constructors // Constructors
@ -125,16 +164,11 @@ public:
// Access // Access
//const List<scalarField>& distances() const //- Indices of surfaces that are shells
//{ const labelList& shells() const
// return distances_; {
//} return shells_;
// }
////- Per shell per distance the refinement level
//const labelListList& levels() const
//{
// return levels_;
//}
// Query // Query
@ -142,6 +176,9 @@ public:
//- Highest shell level //- Highest shell level
label maxLevel() const; label maxLevel() const;
//- Highest shell gap level
labelList maxGapLevel() const;
//- Find shell level higher than ptLevel //- Find shell level higher than ptLevel
void findHigherLevel void findHigherLevel
( (
@ -150,6 +187,33 @@ public:
labelList& maxLevel labelList& maxLevel
) const; ) const;
//- Find a shell whose minimum gap level is >= ptLevel
void findHigherGapLevel
(
const pointField& pt,
const labelList& ptLevel,
labelList& gapShell,
List<FixedList<label, 3> >& gapInfo,
List<volumeType>& gapMode
) const;
//- Find a shell whose minimum gap level is >= ptLevel. gapInfo
// is (0 0 0) if no shell found
void findHigherGapLevel
(
const pointField& pt,
const labelList& ptLevel,
List<FixedList<label, 3> >& gapInfo,
List<volumeType>& gapMode
) const;
//- Find first shell (or -1) with level equal or lower than ptLevel.
void findLevel
(
const pointField& pt,
const labelList& ptLevel,
labelList& shell
) const;
}; };

View File

@ -63,7 +63,9 @@ indexedOctree/treeDataTriSurface.C
searchableSurface = searchableSurface searchableSurface = searchableSurface
$(searchableSurface)/searchableBox.C $(searchableSurface)/searchableBox.C
$(searchableSurface)/searchableRotatedBox.C
$(searchableSurface)/searchableCylinder.C $(searchableSurface)/searchableCylinder.C
$(searchableSurface)/searchableCone.C
$(searchableSurface)/searchableDisk.C $(searchableSurface)/searchableDisk.C
$(searchableSurface)/searchablePlane.C $(searchableSurface)/searchablePlane.C
$(searchableSurface)/searchablePlate.C $(searchableSurface)/searchablePlate.C
@ -75,6 +77,7 @@ $(searchableSurface)/searchableSurfacesQueries.C
$(searchableSurface)/searchableSurfaceWithGaps.C $(searchableSurface)/searchableSurfaceWithGaps.C
$(searchableSurface)/triSurfaceMesh.C $(searchableSurface)/triSurfaceMesh.C
$(searchableSurface)/closedTriSurfaceMesh.C $(searchableSurface)/closedTriSurfaceMesh.C
$(searchableSurface)/subTriSurfaceMesh.C
topoSets = sets/topoSets topoSets = sets/topoSets
$(topoSets)/cellSet.C $(topoSets)/cellSet.C

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,296 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::searchableCone
Description
Searching on (optionally hollow) cone.
\heading Function object usage
\table
Property | Description | Required | Default value
point1 | coordinate of endpoint | yes |
radius1 | radius at point1 | yes | yes
innerRadius1 | inner radius at point1 | no |
point2 | coordinate of endpoint | yes |
radius2 | radius at point2 | yes | yes
innerRadius2 | inner radius at point2 | no |
\endtable
Note
Initial implementation, might suffer from robustness (e.g. radius1==radius2)
SourceFiles
searchableCone.C
\*---------------------------------------------------------------------------*/
#ifndef searchableCone_H
#define searchableCone_H
#include "searchableSurface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class searchableCone Declaration
\*---------------------------------------------------------------------------*/
class searchableCone
:
public searchableSurface
{
// Private Member Data
//- 'Left' point
const point point1_;
//- Outer radius at point1
const scalar radius1_;
//- Inner radius at point1
const scalar innerRadius1_;
//- 'Right' point
const point point2_;
//- Outer radius at point2
const scalar radius2_;
//- Inner radius at point2
const scalar innerRadius2_;
//- Length of vector point2-point1
const scalar magDir_;
//- Normalised vector point2-point1
const vector unitDir_;
//- Names of regions
mutable wordList regions_;
// Private Member Functions
//- Find nearest point on cylinder.
void findNearestAndNormal
(
const point& sample,
const scalar nearestDistSqr,
pointIndexHit & nearInfo,
vector& normal
) const;
//- Determine radial coordinate (squared)
static scalar radius2(const searchableCone& cone, const point& pt);
//- Find both intersections with cone. innerRadii supplied externally.
void findLineAll
(
const searchableCone& cone,
const scalar innerRadius1,
const scalar innerRadius2,
const point& start,
const point& end,
pointIndexHit& near,
pointIndexHit& far
) const;
//- Insert a hit if it differs (by a tolerance) from the existing ones
void insertHit
(
const point& start,
const point& end,
List<pointIndexHit>& info,
const pointIndexHit& hit
) const;
//- Return the boundBox of the cylinder
boundBox calcBounds() const;
//- Disallow default bitwise copy construct
searchableCone(const searchableCone&);
//- Disallow default bitwise assignment
void operator=(const searchableCone&);
public:
//- Runtime type information
TypeName("searchableCone");
// Constructors
//- Construct from components
searchableCone
(
const IOobject& io,
const point& point1,
const scalar radius1,
const scalar innerRadius1,
const point& point2,
const scalar radius2,
const scalar innerRadius2
);
//- Construct from dictionary (used by searchableSurface)
searchableCone
(
const IOobject& io,
const dictionary& dict
);
//- Destructor
virtual ~searchableCone();
// Member Functions
virtual const wordList& regions() const;
//- Whether supports volume type below
virtual bool hasVolumeType() const
{
return true;
}
//- Range of local indices that can be returned.
virtual label size() const
{
return 1;
}
//- Get representative set of element coordinates
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const;
//- Does any part of the surface overlap the supplied bound box?
virtual bool overlaps(const boundBox& bb) const
{
notImplemented
(
"searchableCone::overlaps(const boundBox&) const"
);
return false;
}
// Multiple point queries.
//- Find nearest point on cylinder
virtual void findNearest
(
const pointField& sample,
const scalarField& nearestDistSqr,
List<pointIndexHit>&
) const;
//- Find nearest intersection on line from start to end
virtual void findLine
(
const pointField& start,
const pointField& end,
List<pointIndexHit>&
) const;
//- Find all intersections in order from start to end
virtual void findLineAll
(
const pointField& start,
const pointField& end,
List<List<pointIndexHit> >&
) const;
//- Find any intersection on line from start to end
virtual void findLineAny
(
const pointField& start,
const pointField& end,
List<pointIndexHit>&
) const;
//- From a set of points and indices get the region
virtual void getRegion
(
const List<pointIndexHit>&,
labelList& region
) const;
//- From a set of points and indices get the normal
virtual void getNormal
(
const List<pointIndexHit>&,
vectorField& normal
) const;
//- Determine type (inside/outside/mixed) for point. unknown if
// cannot be determined (e.g. non-manifold surface)
virtual void getVolumeType
(
const pointField&,
List<volumeType>&
) const;
// regIOobject implementation
virtual bool writeData(Ostream&) const
{
notImplemented("searchableCone::writeData(Ostream&) const");
return false;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -43,8 +43,6 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class searchableCylinder Declaration Class searchableCylinder Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/

View File

@ -55,8 +55,7 @@ Foam::searchableRotatedBox::searchableRotatedBox
io.db(), io.db(),
io.readOpt(), io.readOpt(),
io.writeOpt(), io.writeOpt(),
false, //io.registerObject(), false //io.registerObject(),
io.globalObject()
), ),
treeBoundBox(point::zero, dict.lookup("span")) treeBoundBox(point::zero, dict.lookup("span"))
), ),

View File

@ -56,8 +56,6 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class searchableRotatedBox Declaration Class searchableRotatedBox Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -145,6 +143,9 @@ public:
// Single point queries. // Single point queries.
//- Inherit findNearest from searchableSurface
using searchableSurface::findNearest;
//- Calculate nearest point on surface. //- Calculate nearest point on surface.
// Returns // Returns
// - bool : any point found nearer than nearestDistSqr // - bool : any point found nearer than nearestDistSqr

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "subTriSurfaceMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(subTriSurfaceMesh, 0);
addToRunTimeSelectionTable(searchableSurface, subTriSurfaceMesh, dict);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::wordList Foam::subTriSurfaceMesh::patchNames(const triSurface& s)
{
const geometricSurfacePatchList& patches = s.patches();
wordList names(patches.size());
forAll(patches, patchI)
{
names[patchI] = patches[patchI].name();
}
return names;
}
Foam::labelList Foam::subTriSurfaceMesh::selectedRegions
(
const triSurface& s,
const wordReList& regionNames
)
{
const wordList names(patchNames(s));
labelList regions(names.size());
label compactI = 0;
forAll(names, regionI)
{
const word& name = names[regionI];
forAll(regionNames, i)
{
if (regionNames[i].match(name))
{
regions[compactI++] = regionI;
}
}
}
regions.setSize(compactI);
return regions;
}
Foam::triSurface Foam::subTriSurfaceMesh::subset
(
const IOobject& io,
const dictionary& dict
)
{
const word subGeomName(dict.lookup("surface"));
const triSurfaceMesh& s =
io.db().lookupObject<triSurfaceMesh>(subGeomName);
const wordReList regionNames(dict.lookup("patches"));
labelList regionMap(selectedRegions(s, regionNames));
if (regionMap.size() == 0)
{
FatalIOErrorIn
(
"subTriSurfaceMesh::subset"
"(\n"
" const IOobject&,\n"
" const dictionary&\n"
")",
dict
) << "Found no regions in triSurface matching " << regionNames
<< ". Valid regions are " << patchNames(s)
<< exit(FatalIOError);
}
labelList reverseRegionMap(s.patches().size(), -1);
forAll(regionMap, i)
{
reverseRegionMap[regionMap[i]] = i;
}
boolList isSelected(s.size(), false);
forAll(s, triI)
{
if (reverseRegionMap[s.triSurface::operator[](triI).region()] != -1)
{
isSelected[triI] = true;
}
}
labelList pointMap;
labelList faceMap;
return s.subsetMesh(isSelected, pointMap, faceMap);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::subTriSurfaceMesh::subTriSurfaceMesh
(
const IOobject& io,
const dictionary& dict
)
:
triSurfaceMesh(io, subset(io, dict))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::subTriSurfaceMesh::~subTriSurfaceMesh()
{}
// ************************************************************************* //

View File

@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::subTriSurfaceMesh
Description
On-the-fly subset of triSurfaceMesh (based on selected patches)
Note
Example usage:
\verbatim
spheres.stl
{
type subTriSurfaceMesh;
// Surface to operate on. Avoid duplicate loading
surface spheres.stl;
// Regions to operate on (regular expressions allowed)
patches (solid1);
}
\endverbatim
SourceFiles
subTriSurfaceMesh.C
\*---------------------------------------------------------------------------*/
#ifndef subTriSurfaceMesh_H
#define subTriSurfaceMesh_H
#include "triSurfaceMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class subTriSurfaceMesh Declaration
\*---------------------------------------------------------------------------*/
class subTriSurfaceMesh
:
public triSurfaceMesh
{
// Private member functions
//- Extract patch names of triSurface
static wordList patchNames(const triSurface& s);
//- Select regions by name
static labelList selectedRegions
(
const triSurface& s,
const wordReList& regionNames
);
//- Subset triSurface based on regions
static triSurface subset(const IOobject&, const dictionary&);
public:
//- Runtime type information
TypeName("subTriSurfaceMesh");
// Constructors
//- Construct from IO and dictionary.
subTriSurfaceMesh
(
const IOobject& io,
const dictionary& dict
);
//- Destructor
virtual ~subTriSurfaceMesh();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -408,9 +408,16 @@ void Foam::hierarchGeomDecomp::sortComponent
{ {
// No need for binary searching of bin size // No need for binary searching of bin size
localSize = label(current.size()/n_[compI]); localSize = label(current.size()/n_[compI]);
if (leftIndex+localSize < sortedCoord.size())
{
rightCoord = sortedCoord[leftIndex+localSize]; rightCoord = sortedCoord[leftIndex+localSize];
} }
else else
{
rightCoord = maxCoord;
}
}
else
{ {
// For the current bin (starting at leftCoord) we want a rightCoord // For the current bin (starting at leftCoord) we want a rightCoord
// such that the sum of all sizes are globalCurrentSize/n_[compI]. // such that the sum of all sizes are globalCurrentSize/n_[compI].

View File

@ -12,6 +12,11 @@ cd ${0%/*} || exit 1 # Run from this directory
./Allrun ./Allrun
) )
(
cd gap_detection || exit
./Allrun
)
exit 0 exit 0
# These cases are links to solver test cases and are run when the Allrun # These cases are links to solver test cases and are run when the Allrun

View File

@ -0,0 +1,7 @@
#!/bin/sh
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
\rm -f constant/polyMesh/boundary > /dev/null 2>&1
cleanCase

View File

@ -0,0 +1,15 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication decomposePar
runParallel snappyHexMesh 8 -overwrite
runApplication reconstructParMesh -constant
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,7 @@
Testcase for automatic gap refinement. The geometry is two nested boxes
with a single small pipe between them.
- 1 cell initial mesh
- consistent normal orientation of surface so
specify a 'gapMode' to limit refinement only to
gaps on the 'outside' of the surface

View File

@ -0,0 +1,102 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
vertices
(
(-400 -100 -400)
( 400 -100 -400)
( 400 700 -400)
(-400 700 -400)
(-400 -100 400)
( 400 -100 400)
( 400 700 400)
(-400 700 400)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (1 1 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
maxY
{
type patch;
faces
(
(3 7 6 2)
);
}
minX
{
type patch;
faces
(
(0 4 7 3)
);
}
maxX
{
type patch;
faces
(
(2 6 5 1)
);
}
minY
{
type patch;
faces
(
(1 5 4 0)
);
}
ground
{
type patch;
faces
(
(0 3 2 1)
);
}
maxZ
{
type patch;
faces
(
(4 5 6 7)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,124 @@
# Wavefront OBJ file
# Regions:
# 0 patch0
#
# points : 40
# triangles : 76
#
v 80 20 -20
v -80 20 -20
v 100 0 0
v -100 0 0
v 80 20 -280
v -80 20 -280
v 80 280 -100
v -80 280 -100
v 100 0 -300
v -100 0 -300
v 100 300 -120
v -100 300 -120
v 80 280 -280
v -80 280 -280
v 100 300 -300
v -100 300 -300
v 0 445 0
v 0 445 -20
v 3.53538 446.464 0
v -3.53538 446.464 0
v -3.53538 446.464 -20
v 3.53538 446.464 -20
v 5 450 0
v -5 450 0
v -5 450 -20
v 5 450 -20
v -3.53538 453.536 0
v 3.53538 453.536 0
v -3.53538 453.536 -20
v 3.53538 453.536 -20
v 0 455 0
v 0 455 -20
v 80 580 -20
v -80 580 -20
v 80 580 -100
v -80 580 -100
v 100 600 0
v -100 600 0
v 100 600 -120
v -100 600 -120
g patch0
f 39 37 3
f 4 3 37
f 11 39 3
f 15 11 3
f 9 15 3
f 10 9 3
f 10 3 4
f 40 37 39
f 19 4 37
f 38 37 40
f 27 37 38
f 23 19 37
f 28 23 37
f 31 28 37
f 27 31 37
f 40 39 11
f 16 11 15
f 12 11 16
f 40 11 12
f 16 15 9
f 16 9 10
f 12 10 4
f 38 12 4
f 24 38 4
f 20 24 4
f 17 20 4
f 19 17 4
f 12 16 10
f 38 40 12
f 27 38 24
f 25 24 20
f 29 27 24
f 29 24 25
f 21 20 17
f 21 25 20
f 18 17 19
f 21 17 18
f 22 19 23
f 18 19 22
f 26 23 28
f 22 23 26
f 30 28 31
f 26 28 30
f 32 31 27
f 30 31 32
f 32 27 29
f 7 5 1
f 2 1 5
f 33 7 1
f 26 33 1
f 34 1 2
f 21 1 34
f 22 26 1
f 18 22 1
f 21 18 1
f 7 13 5
f 6 5 13
f 6 2 5
f 14 13 7
f 6 13 14
f 33 35 7
f 8 7 35
f 14 7 8
f 34 35 33
f 36 35 34
f 8 35 36
f 30 34 33
f 26 30 33
f 36 34 2
f 8 36 2
f 14 8 2
f 6 14 2
f 29 25 34
f 21 34 25
f 32 29 34
f 30 32 34

View File

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev s |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application snappyHexMesh;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 2000;
deltaT 1;
writeControl timeStep;
writeInterval 100;
purgeWrite 0;
writeFormat binary;
writePrecision 6;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable true;
// ************************************************************************* //

View File

@ -0,0 +1,41 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 8;
method hierarchical;
simpleCoeffs
{
n ( 4 1 1 );
delta 0.001;
}
hierarchicalCoeffs
{
n ( 2 2 2 );
delta 0.001;
order xyz;
}
manualCoeffs
{
dataFile "cellDecomposition";
}
// ************************************************************************* //

View File

@ -0,0 +1,63 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default steadyState;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
div(phi,U) bounded Gauss upwind;
div(phi,T) bounded Gauss upwind;
div(phi,k) bounded Gauss upwind;
div(phi,epsilon) bounded Gauss upwind;
div(phi,R) bounded Gauss upwind;
div(R) Gauss linear;
div((nuEff*dev(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear limited corrected 0.333;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default limited corrected 0.333;
}
fluxRequired
{
default no;
p_rgh ;
}
// ************************************************************************* //

View File

@ -0,0 +1,69 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
p_rgh
{
solver PCG;
preconditioner DIC;
tolerance 1e-08;
relTol 0.01;
}
"(U|T|k|epsilon)"
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-07;
relTol 0.1;
}
}
SIMPLE
{
nNonOrthogonalCorrectors 2;
pRefCell 0;
pRefValue 0;
residualControl
{
p_rgh 1e-2;
U 1e-4;
T 1e-3;
// possibly check turbulence fields
"(k|epsilon|omega)" 1e-3;
}
}
relaxationFactors
{
fields
{
p_rgh 0.7;
}
equations
{
U 0.2;
T 0.5;
"(k|epsilon)" 0.7;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object meshQualityDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Include defaults parameters from master dictionary
#include "$WM_PROJECT_DIR/etc/caseDicts/meshQualityDict"
// ************************************************************************* //

View File

@ -0,0 +1,297 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object snappyHexMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Which of the steps to run
castellatedMesh true;
snap false;
addLayers false;
// Geometry. Definition of all surfaces. All surfaces are of class
// searchableSurface.
// Surfaces are used
// - to specify refinement for any mesh cell intersecting it
// - to specify refinement for any mesh cell inside/outside/near
// - to 'snap' the mesh boundary to the surface
geometry
{
mech_test.obj
{
type triSurfaceMesh;
}
all
{
type searchableBox;
min (-1000 -1000 -1000);
max (1000 1000 1000);
}
};
// Settings for the castellatedMesh generation.
castellatedMeshControls
{
// Refinement parameters
// ~~~~~~~~~~~~~~~~~~~~~
// If local number of cells is >= maxLocalCells on any processor
// switches from from refinement followed by balancing
// (current method) to (weighted) balancing before refinement.
maxLocalCells 100000;
// Overall cell limit (approximately). Refinement will stop immediately
// upon reaching this number so a refinement level might not complete.
// Note that this is the number of cells before removing the part which
// is not 'visible' from the keepPoint. The final number of cells might
// actually be a lot less.
maxGlobalCells 2000000;
// The surface refinement loop might spend lots of iterations refining just a
// few cells. This setting will cause refinement to stop if <= minimumRefine
// are selected for refinement. Note: it will at least do one iteration
// (unless the number of cells to refine is 0)
minRefinementCells 0;
// Number of buffer layers between different levels.
// 1 means normal 2:1 refinement restriction, larger means slower
// refinement.
nCellsBetweenLevels 1;
// Explicit feature edge refinement
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Specifies a level for any cell intersected by its edges.
// This is a featureEdgeMesh, read from constant/triSurface for now.
features
(
);
// Surface based refinement
// ~~~~~~~~~~~~~~~~~~~~~~~~
// Specifies two levels for every surface. The first is the minimum level,
// every cell intersecting a surface gets refined up to the minimum level.
// The second level is the maximum level. Cells that 'see' multiple
// intersections where the intersections make an
// angle > resolveFeatureAngle get refined up to the maximum level.
refinementSurfaces
{
mech_test.obj
{
// Surface-wise min and max refinement level
level (0 0);
}
}
// Resolve sharp angles
resolveFeatureAngle 60;
// Region-wise refinement
// ~~~~~~~~~~~~~~~~~~~~~~
// Specifies refinement level for cells in relation to a surface. One of
// three modes
// - distance. 'levels' specifies per distance to the surface the
// wanted refinement level. The distances need to be specified in
// descending order.
// - inside. 'levels' is only one entry and only the level is used. All
// cells inside the surface get refined up to the level. The surface
// needs to be closed for this to be possible.
// - outside. Same but cells outside.
refinementRegions
{
all
{
mode inside;
// Dummy base level
levels ((10000 0));
// If cells
// - have level 0..9
// - and are in a gap < 3 cell sizes across
// - with the gap on the inside ('inside'), outside ('outside')
// or both ('mixed') of the surface
// refine them
gapLevel (4 0 10);
gapMode outside;
}
}
// Mesh selection
// ~~~~~~~~~~~~~~
// After refinement patches get added for all refinementSurfaces and
// all cells intersecting the surfaces get put into these patches. The
// section reachable from the locationInMesh is kept.
// NOTE: This point should never be on a face, always inside a cell, even
// after refinement.
locationInMesh (-100 -5 -300);
// Whether any faceZones (as specified in the refinementSurfaces)
// are only on the boundary of corresponding cellZones or also allow
// free-standing zone faces. Not used if there are no faceZones.
allowFreeStandingZoneFaces false;
}
// Settings for the snapping.
snapControls
{
//- Number of patch smoothing iterations before finding correspondence
// to surface
nSmoothPatch 3;
//- Relative distance for points to be attracted by surface feature point
// or edge. True distance is this factor times local
// maximum edge length.
tolerance 2.0;
//- Number of mesh displacement relaxation iterations.
nSolveIter 30;
//- Maximum number of snapping relaxation iterations. Should stop
// before upon reaching a correct mesh.
nRelaxIter 5;
// Feature snapping
//- Number of feature edge snapping iterations.
// Leave out altogether to disable.
nFeatureSnapIter 10;
//- Detect (geometric) features by sampling the surface (default=false)
implicitFeatureSnap true;
//- Use castellatedMeshControls::features (default = true)
explicitFeatureSnap false;
}
// Settings for the layer addition.
addLayersControls
{
// Are the thickness parameters below relative to the undistorted
// size of the refined cell outside layer (true) or absolute sizes (false).
relativeSizes true;
// Per final patch (so not geometry!) the layer information
layers
{
}
// Expansion factor for layer mesh
expansionRatio 1.0;
// Wanted thickness of final added cell layer. If multiple layers
// is the thickness of the layer furthest away from the wall.
// Relative to undistorted size of cell outside layer.
// is the thickness of the layer furthest away from the wall.
// See relativeSizes parameter.
finalLayerThickness 0.5;
// Minimum thickness of cell layer. If for any reason layer
// cannot be above minThickness do not add layer.
// Relative to undistorted size of cell outside layer.
// See relativeSizes parameter.
minThickness 0.25;
// If points get not extruded do nGrow layers of connected faces that are
// also not grown. This helps convergence of the layer addition process
// close to features.
// Note: changed(corrected) w.r.t 17x! (didn't do anything in 17x)
nGrow 0;
// Advanced settings
// When not to extrude surface. 0 is flat surface, 90 is when two faces
// are perpendicular
featureAngle 60;
// Maximum number of snapping relaxation iterations. Should stop
// before upon reaching a correct mesh.
nRelaxIter 5;
// Number of smoothing iterations of surface normals
nSmoothSurfaceNormals 1;
// Number of smoothing iterations of interior mesh movement direction
nSmoothNormals 3;
// Smooth layer thickness over surface patches
nSmoothThickness 10;
// Stop layer growth on highly warped cells
maxFaceThicknessRatio 0.5;
// Reduce layer growth where ratio thickness to medial
// distance is large
maxThicknessToMedialRatio 0.3;
// Angle used to pick up medial axis points
// Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x.
minMedianAxisAngle 90;
// Create buffer region for new layer terminations
nBufferCellsNoExtrude 0;
// Overall max number of layer addition iterations. The mesher will exit
// if it reaches this number of iterations; possibly with an illegal
// mesh.
nLayerIter 50;
}
// Generic mesh quality settings. At any undoable phase these determine
// where to undo.
meshQualityControls
{
#include "meshQualityDict"
// Advanced
//- Number of error distribution iterations
nSmoothScale 4;
//- amount to scale back displacement at error points
errorReduction 0.75;
}
// Advanced
// Merge tolerance. Is fraction of overall bounding box of initial mesh.
// Note: the write tolerance needs to be higher than this.
mergeTolerance 1e-6;
// ************************************************************************* //