mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
changed dictionary
This commit is contained in:
@ -34,9 +34,6 @@ Description
|
||||
#include "Time.H"
|
||||
#include "fvMesh.H"
|
||||
#include "autoHexMeshDriver.H"
|
||||
#include "pointMesh.H"
|
||||
#include "motionSmoother.H"
|
||||
#include "mapDistributePolyMesh.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -52,6 +49,18 @@ int main(int argc, char *argv[])
|
||||
Info<< "Read mesh in = "
|
||||
<< runTime.cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
// Read decomposePar dictionary
|
||||
IOdictionary decomposeDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"decomposeParDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
// Read meshing dictionary
|
||||
IOdictionary meshDict
|
||||
@ -66,24 +75,46 @@ int main(int argc, char *argv[])
|
||||
)
|
||||
);
|
||||
|
||||
// Read decomposePar dictionary
|
||||
IOdictionary decomposeDict
|
||||
// refinement parameters
|
||||
const dictionary& refineDict = meshDict.subDict("refineDict");
|
||||
|
||||
// snap-to-surface parameters
|
||||
const dictionary& snapDict = meshDict.subDict("snapDict");
|
||||
|
||||
// mesh motion and mesh quality parameters
|
||||
const dictionary& motionDict = meshDict.subDict("motionDict");
|
||||
|
||||
// layer addition parameters
|
||||
const dictionary& layerDict = meshDict.subDict("layerDict");
|
||||
|
||||
|
||||
// Main meshing driver. Read surfaces. Determine initial intersections.
|
||||
autoHexMeshDriver meshEngine
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"decomposeParDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
meshDict, // global control parameters
|
||||
refineDict, // refinement parameters
|
||||
decomposeDict
|
||||
);
|
||||
|
||||
// Main meshing driver. Read surfaces. Determine intersections.
|
||||
autoHexMeshDriver meshEngine(mesh, meshDict, decomposeDict);
|
||||
Switch wantRefine(meshDict.lookup("doRefine"));
|
||||
Switch wantSnap(meshDict.lookup("doSnap"));
|
||||
Switch wantLayers(meshDict.lookup("doLayers"));
|
||||
|
||||
// Do all: refine, snap, add layers
|
||||
meshEngine.doMesh();
|
||||
if (wantRefine)
|
||||
{
|
||||
meshEngine.doRefine(refineDict, wantSnap);
|
||||
}
|
||||
|
||||
if (wantSnap)
|
||||
{
|
||||
meshEngine.doSnap(snapDict, motionDict);
|
||||
}
|
||||
|
||||
if (wantLayers)
|
||||
{
|
||||
meshEngine.doLayers(layerDict, motionDict);
|
||||
}
|
||||
|
||||
Info<< "Finished meshing in = "
|
||||
<< runTime.elapsedCpuTime() << " s." << endl;
|
||||
|
||||
@ -0,0 +1,314 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: 1.0 |
|
||||
| \\ / A nd | Web: http://www.openfoam.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
|
||||
root "/home/penfold/mattijs/foam/mattijs2.1/run/icoFoam";
|
||||
case "cavity";
|
||||
instance "system";
|
||||
local "";
|
||||
|
||||
class dictionary;
|
||||
object autoHexMeshDict;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Which phases to run.
|
||||
doRefine true;
|
||||
doSnap true;
|
||||
doLayers true; // includes autoMergeFaces
|
||||
|
||||
|
||||
// Whether to dump intermediate meshes and print lots
|
||||
// 1 : write mesh
|
||||
// 2 : write volScalarField with cellLevel for postprocessing
|
||||
// 4 : write current intersections as .obj files
|
||||
debug 0;
|
||||
|
||||
refineDict
|
||||
{
|
||||
// Which part to keep.
|
||||
// NOTE: This point should never be on a face, always inside a cell, even
|
||||
// after refinement.
|
||||
keepPoints ((3 0.28 0.43));
|
||||
|
||||
// Whether to remove/split cells likely to give problems when snapping
|
||||
handleSnapProblems on;
|
||||
|
||||
// Merge tolerance. Is fraction of overall bounding box of initial mesh
|
||||
mergeTolerance 1E-6;
|
||||
|
||||
// While refining maximum number of cells per processor. This is basically
|
||||
// the number of cells that fit on a processor. If you choose this too small
|
||||
// it will do just more refinement iterations to obtain a similar mesh.
|
||||
procCellLimit 1000000;
|
||||
|
||||
|
||||
// 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.
|
||||
cellLimit 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)
|
||||
minimumRefine 0;
|
||||
|
||||
|
||||
|
||||
|
||||
// Number of buffer layers between different levels.
|
||||
// 1 means normal 2:1 refinement restriction, larger means slower
|
||||
// refinement.
|
||||
nBufferLayers 1;
|
||||
|
||||
|
||||
// Feature Edge Refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// External feature file. Read from constant/triSurface for now.
|
||||
// Limitations:
|
||||
// - either start or edge of any feature line has to be inside domain
|
||||
// and be visible from keepPoint on starting mesh.
|
||||
// - refining cells containing features is separate phase before refining
|
||||
// based on surface.
|
||||
// - no load balancing, no check for cellLimit is done while doing this.
|
||||
features
|
||||
(
|
||||
// {
|
||||
// file "someLine.eMesh";
|
||||
// level 2;
|
||||
// }
|
||||
);
|
||||
|
||||
|
||||
// Internal Mesh Refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies the areas where the refinement has to be a certain level.
|
||||
// These surfaces have to be closed. Refinement is either inside
|
||||
// (refineInside = true) or outside. (note:insideness or outsideness
|
||||
// is with respect to far away)
|
||||
// Note:that even using these the transition can never be faster than
|
||||
// nBufferLayers!
|
||||
// Note:the refinement level can never be higher than any of the surfaces
|
||||
// they overlap with. See below for the surface refinement level specification.
|
||||
refinementShells
|
||||
(
|
||||
{
|
||||
//type triSurfaceMesh;
|
||||
//name cube1x1x1.stl;
|
||||
type searchableBox;
|
||||
name box1x1x1;
|
||||
min (2.5 -0.5 -0.5);
|
||||
max (3.5 0.5 0.5);
|
||||
|
||||
level 4;
|
||||
refineInside true;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Surface based refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Curvature. Cosine of angle between two neighbouring surface intersections.
|
||||
// Only used if cell level > minLevel and < maxLevel.
|
||||
curvature 0.5;
|
||||
|
||||
|
||||
// Overall the refinement is according to the following rules:
|
||||
// - if the cell-cell vector intersects a surface any cell that
|
||||
// is less refined than the minRefinementLevel of the surface gets refined.
|
||||
// - else if the refinement level of the cell is between the
|
||||
// minRefinementLevel and maxRefinementLevel the cell gets refined if
|
||||
// - the normal of neighbouring surface intersections differ by more
|
||||
// than above curvature
|
||||
// - or if neighbouring surface intersections are on different surfaces or
|
||||
// different surface regions.
|
||||
|
||||
|
||||
// surfaces
|
||||
surfaces
|
||||
(
|
||||
{
|
||||
name sphere;
|
||||
file "sphere.stl";
|
||||
|
||||
// Surface wide refinement level
|
||||
minRefinementLevel 1;
|
||||
maxRefinementLevel 1;
|
||||
|
||||
// Layers
|
||||
surfaceLayers 1;
|
||||
|
||||
// Region specific refinement level
|
||||
regions
|
||||
(
|
||||
{
|
||||
name firstSolid;
|
||||
minRefinementLevel 3;
|
||||
maxRefinementLevel 3;
|
||||
surfaceLayers 2;
|
||||
}
|
||||
{
|
||||
name secondSolid;
|
||||
minRefinementLevel 1;
|
||||
maxRefinementLevel 1;
|
||||
surfaceLayers 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// For snapping
|
||||
snapDict
|
||||
{
|
||||
//- 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.
|
||||
snapTol 4.0;
|
||||
|
||||
//- Whether to move internal mesh as well as boundary
|
||||
smoothMesh true;
|
||||
|
||||
//- Number of mesh displacement smoothing iterations.
|
||||
nSmoothDispl 30;
|
||||
|
||||
//- Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nSnap 5;
|
||||
}
|
||||
|
||||
|
||||
// For cell layers
|
||||
layerDict
|
||||
{
|
||||
//- When not to extrude surface. 0 is flat surface, 90 is when two faces
|
||||
// make straight angle.
|
||||
featureAngle 60;
|
||||
|
||||
//- Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nSnap 5;
|
||||
|
||||
|
||||
//- Minimum thickness of cell layer. If for any reason layer cannot be
|
||||
// above minThickness do not add layer if thickness below minThickNess.
|
||||
// Relative to undistorted cell size
|
||||
minThickness 0.25;
|
||||
|
||||
//- If points get not extruded do nGrow layers of connected faces that are
|
||||
// not grown. Is used to not do layers at all close to features.
|
||||
nGrow 1;
|
||||
|
||||
// Expansion factor for layer mesh
|
||||
expansionRatio 1.3;
|
||||
|
||||
// Ratio of cell size in final added cell layer to cell size
|
||||
// outside layer
|
||||
finalLayerRatio 0.3;
|
||||
|
||||
// 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
|
||||
minMedianAxisAngle 130;
|
||||
|
||||
// Create buffer region for new layer terminations
|
||||
nBufferCellsNoExtrude 0;
|
||||
|
||||
thickness 0.5;
|
||||
nSmoothDispl 4;
|
||||
}
|
||||
|
||||
|
||||
// For mesh motion
|
||||
motionDict
|
||||
{
|
||||
//
|
||||
// Mesh Quality Parameters. Decide when mesh is good enough to stop
|
||||
// smoothing.
|
||||
//
|
||||
|
||||
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||
maxNonOrtho 65;
|
||||
|
||||
//- Max skewness allowed. Set to <0 to disable.
|
||||
maxBoundarySkewness 20;
|
||||
maxInternalSkewness 4;
|
||||
|
||||
//- Max concaveness allowed. Is angle (in degrees) below which concavity
|
||||
// is allowed. 0 is straight face, <0 would be convex face.
|
||||
// Set to 180 to disable.
|
||||
maxConcave 80;
|
||||
|
||||
//- Minimum projected area v.s. actual area. Set to -1 to disable.
|
||||
minFlatness 0.5;
|
||||
|
||||
//- Minimum pyramid volume. Is absolute volume of cell pyramid.
|
||||
// Set to very negative number (e.g. -1E30) to disable.
|
||||
minVol 1e-13;
|
||||
|
||||
//- Minimum face area. Set to <0 to disable.
|
||||
minArea -1;
|
||||
|
||||
//- Minimum face twist. Set to <-1 to disable. dot product of face normal
|
||||
//- and face centre triangles normal
|
||||
minTwist 0.05;
|
||||
|
||||
//- minimum normalised cell determinant
|
||||
//- 1 = hex, <= 0 = folded or flattened illegal cell
|
||||
minDeterminant 0.001;
|
||||
|
||||
//- minFaceWeight (0 -> 0.5)
|
||||
minFaceWeight 0.05;
|
||||
|
||||
//- minVolRatio (0 -> 1)
|
||||
minVolRatio 0.01;
|
||||
|
||||
|
||||
//must be >0 for Fluent compatibility
|
||||
minTriangleTwist -1;
|
||||
|
||||
// Advanced
|
||||
|
||||
//- Number of error distribution iterations
|
||||
nSmoothScale 4;
|
||||
//- amount to scale back displacement at error points
|
||||
errorReduction 0.75;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -52,9 +52,9 @@ defineTypeNameAndDebug(autoHexMeshDriver, 0);
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Check writing tolerance before doing any serious work
|
||||
Foam::scalar Foam::autoHexMeshDriver::getMergeDistance() const
|
||||
Foam::scalar Foam::autoHexMeshDriver::getMergeDistance(const scalar mergeTol)
|
||||
const
|
||||
{
|
||||
const scalar mergeTol = readScalar(dict_.lookup("mergeTolerance"));
|
||||
const boundBox& meshBb = mesh_.bounds();
|
||||
scalar mergeDist = mergeTol*mag(meshBb.max() - meshBb.min());
|
||||
scalar writeTol = std::pow
|
||||
@ -70,7 +70,7 @@ Foam::scalar Foam::autoHexMeshDriver::getMergeDistance() const
|
||||
|
||||
if (mesh_.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol)
|
||||
{
|
||||
FatalErrorIn("autoHexMeshDriver::getMergeDistance() const")
|
||||
FatalErrorIn("autoHexMeshDriver::getMergeDistance(const scalar) const")
|
||||
<< "Your current settings specify ASCII writing with "
|
||||
<< IOstream::defaultPrecision() << " digits precision." << endl
|
||||
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
|
||||
@ -306,9 +306,8 @@ Foam::autoHexMeshDriver::autoHexMeshDriver
|
||||
curvature_(readScalar(dict_.lookup("curvature"))),
|
||||
nBufferLayers_(readLabel(dict_.lookup("nBufferLayers"))),
|
||||
keepPoints_(dict_.lookup("keepPoints")),
|
||||
mergeDist_(getMergeDistance())
|
||||
mergeDist_(getMergeDistance(readScalar(dict_.lookup("mergeTolerance"))))
|
||||
{
|
||||
|
||||
if (debug_ > 0)
|
||||
{
|
||||
meshRefinement::debug = debug_;
|
||||
@ -471,17 +470,34 @@ Foam::autoHexMeshDriver::autoHexMeshDriver
|
||||
{
|
||||
if (nTrisPerRegion[i] > 0)
|
||||
{
|
||||
label globalRegionI = surfaces().globalRegion(surfI, i);
|
||||
|
||||
// Use optionally specified patch type and name
|
||||
word patchType = surfaces().patchType()[globalRegionI];
|
||||
if (patchType == "")
|
||||
{
|
||||
patchType = wallPolyPatch::typeName;
|
||||
}
|
||||
|
||||
word patchName = surfaces().patchName()[globalRegionI];
|
||||
if (patchName == "")
|
||||
{
|
||||
patchName =
|
||||
surfaces().names()[surfI]
|
||||
+ '_'
|
||||
+ regions[i].name();
|
||||
}
|
||||
|
||||
label patchI = meshRefinement::addPatch
|
||||
(
|
||||
mesh,
|
||||
//s.searchableSurface::name() + '_' + regions[i].name(),
|
||||
surfaces().names()[surfI] + '_' + regions[i].name(),
|
||||
wallPolyPatch::typeName
|
||||
patchName,
|
||||
patchType
|
||||
);
|
||||
|
||||
Info<< patchI << '\t' << regions[i].name() << nl;
|
||||
|
||||
globalToPatch_[surfaces().globalRegion(surfI, i)] = patchI;
|
||||
globalToPatch_[globalRegionI] = patchI;
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,15 +609,283 @@ Foam::autoHexMeshDriver::autoHexMeshDriver
|
||||
}
|
||||
|
||||
|
||||
// Construct from separate dictionaries.
|
||||
Foam::autoHexMeshDriver::autoHexMeshDriver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& controlDict,
|
||||
const dictionary& refineDict,
|
||||
const dictionary& decomposeDict
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
dict_(controlDict),
|
||||
debug_(readLabel(controlDict.lookup("debug"))),
|
||||
maxGlobalCells_(readLabel(refineDict.lookup("cellLimit"))),
|
||||
maxLocalCells_(readLabel(refineDict.lookup("procCellLimit"))),
|
||||
minRefineCells_(readLabel(refineDict.lookup("minimumRefine"))),
|
||||
curvature_(readScalar(refineDict.lookup("curvature"))),
|
||||
nBufferLayers_(readLabel(refineDict.lookup("nBufferLayers"))),
|
||||
keepPoints_(refineDict.lookup("keepPoints")),
|
||||
mergeDist_
|
||||
(
|
||||
getMergeDistance(readScalar(refineDict.lookup("mergeTolerance")))
|
||||
)
|
||||
{
|
||||
if (debug_ > 0)
|
||||
{
|
||||
meshRefinement::debug = debug_;
|
||||
autoHexMeshDriver::debug = debug_;
|
||||
}
|
||||
|
||||
Info<< "Overall cell limit : " << maxGlobalCells_
|
||||
<< endl;
|
||||
Info<< "Per processor cell limit : " << maxLocalCells_
|
||||
<< endl;
|
||||
Info<< "Minimum number of cells to refine : " << minRefineCells_
|
||||
<< endl;
|
||||
Info<< "Curvature : " << curvature_
|
||||
<< nl << endl;
|
||||
Info<< "Layers between different refinement levels : " << nBufferLayers_
|
||||
<< endl;
|
||||
|
||||
// Check keepPoints are sensible
|
||||
findCells(keepPoints_);
|
||||
|
||||
|
||||
// Read refinement shells
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
{
|
||||
Info<< "Reading refinement shells." << endl;
|
||||
|
||||
PtrList<dictionary> shellDicts(refineDict.lookup("refinementShells"));
|
||||
|
||||
shells_.setSize(shellDicts.size());
|
||||
shellLevels_.setSize(shellDicts.size());
|
||||
shellRefineInside_.setSize(shellDicts.size());
|
||||
|
||||
forAll(shellDicts, i)
|
||||
{
|
||||
const dictionary& dict = shellDicts[i];
|
||||
|
||||
shells_.set
|
||||
(
|
||||
i,
|
||||
searchableSurface::New
|
||||
(
|
||||
dict.lookup("type"),
|
||||
dict.lookup("name"),
|
||||
mesh_.time(),
|
||||
dict
|
||||
)
|
||||
);
|
||||
shellLevels_[i] = readLabel(dict.lookup("level"));
|
||||
shellRefineInside_[i] = Switch(dict.lookup("refineInside"));
|
||||
|
||||
if (shellRefineInside_[i])
|
||||
{
|
||||
Info<< "Refinement level " << shellLevels_[i]
|
||||
<< " for all cells inside " << shells_[i].name() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Refinement level " << shellLevels_[i]
|
||||
<< " for all cells outside " << shells_[i].name() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Read refinement shells in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
// Orient shell surfaces before any searching is done.
|
||||
Info<< "Orienting triSurface shells so point far away is outside."
|
||||
<< endl;
|
||||
orientOutside(shells_);
|
||||
Info<< "Oriented shells in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
}
|
||||
|
||||
|
||||
// Read refinement surfaces
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
{
|
||||
Info<< "Reading surfaces and constructing search trees." << endl;
|
||||
|
||||
surfacesPtr_.reset
|
||||
(
|
||||
new refinementSurfaces
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"", // dummy name
|
||||
mesh_.time().constant(), // directory
|
||||
"triSurface", // instance
|
||||
mesh_.time(), // registry
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
refineDict.lookup("surfaces")
|
||||
)
|
||||
);
|
||||
Info<< "Read surfaces in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
// Orient surfaces (if they're closed) before any searching is done.
|
||||
Info<< "Orienting (closed) surfaces so keepPoint is outside." << endl;
|
||||
forAll(surfaces(), i)
|
||||
{
|
||||
if (refinementSurfaces::isSurfaceClosed(surfaces()[i]))
|
||||
{
|
||||
refinementSurfaces::orientSurface
|
||||
(
|
||||
keepPoints_[0],
|
||||
surfacesPtr_()[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
Info<< "Oriented closed surfaces in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
Info<< "Setting refinement level of surface to be consistent"
|
||||
<< " with shells." << endl;
|
||||
surfacesPtr_().setMinLevelFields
|
||||
(
|
||||
shells_,
|
||||
shellLevels_,
|
||||
shellRefineInside_
|
||||
);
|
||||
Info<< "Checked shell refinement in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
}
|
||||
|
||||
// Check faceZones are synchronised
|
||||
checkCoupledFaceZones();
|
||||
|
||||
|
||||
// Add all the surface regions as patches
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
{
|
||||
Info<< nl
|
||||
<< "Adding patches for surface regions" << nl
|
||||
<< "----------------------------------" << nl
|
||||
<< endl;
|
||||
|
||||
// From global region number to mesh patch.
|
||||
globalToPatch_.setSize(surfaces().nRegions(), -1);
|
||||
|
||||
Info<< "Patch\tRegion" << nl
|
||||
<< "-----\t------"
|
||||
<< endl;
|
||||
|
||||
forAll(surfaces(), surfI)
|
||||
{
|
||||
const triSurfaceMesh& s = surfaces()[surfI];
|
||||
|
||||
Info<< surfaces().names()[surfI] << ':' << nl << nl;
|
||||
|
||||
const geometricSurfacePatchList& regions = s.patches();
|
||||
|
||||
labelList nTrisPerRegion(surfaces().countRegions(s));
|
||||
|
||||
forAll(regions, i)
|
||||
{
|
||||
if (nTrisPerRegion[i] > 0)
|
||||
{
|
||||
label patchI = meshRefinement::addPatch
|
||||
(
|
||||
mesh,
|
||||
//s.searchableSurface::name() + '_' + regions[i].name(),
|
||||
surfaces().names()[surfI] + '_' + regions[i].name(),
|
||||
wallPolyPatch::typeName
|
||||
);
|
||||
|
||||
Info<< patchI << '\t' << regions[i].name() << nl;
|
||||
|
||||
globalToPatch_[surfaces().globalRegion(surfI, i)] = patchI;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< nl;
|
||||
}
|
||||
Info<< "Added patches in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
}
|
||||
|
||||
// Parallel
|
||||
// ~~~~~~~~
|
||||
|
||||
{
|
||||
// Decomposition
|
||||
decomposerPtr_ = decompositionMethod::New
|
||||
(
|
||||
decomposeDict,
|
||||
mesh_
|
||||
);
|
||||
decompositionMethod& decomposer = decomposerPtr_();
|
||||
|
||||
|
||||
if (Pstream::parRun() && !decomposer.parallelAware())
|
||||
{
|
||||
FatalErrorIn("autoHexMeshDriver::autoHexMeshDriver(const IOobject&, fvMesh&)")
|
||||
<< "You have selected decomposition method "
|
||||
<< decomposer.typeName
|
||||
<< " which is not parallel aware." << endl
|
||||
<< "Please select one that is (parMetis, hierarchical)"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Mesh distribution engine (uses tolerance to reconstruct meshes)
|
||||
distributorPtr_.reset(new fvMeshDistribute(mesh_, mergeDist_));
|
||||
}
|
||||
|
||||
|
||||
// Refinement engine
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
|
||||
{
|
||||
Info<< nl
|
||||
<< "Determining initial surface intersections" << nl
|
||||
<< "-----------------------------------------" << nl
|
||||
<< endl;
|
||||
|
||||
// Main refinement engine
|
||||
meshRefinerPtr_.reset
|
||||
(
|
||||
new meshRefinement
|
||||
(
|
||||
mesh,
|
||||
mergeDist_, // tolerance used in sorting coordinates
|
||||
surfaces()
|
||||
)
|
||||
);
|
||||
Info<< "Calculated surface intersections in = "
|
||||
<< mesh_.time().cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
// Some stats
|
||||
meshRefinerPtr_().printMeshInfo(debug_, "Initial mesh");
|
||||
|
||||
meshRefinerPtr_().write
|
||||
(
|
||||
debug_&meshRefinement::OBJINTERSECTIONS,
|
||||
mesh_.time().path()/mesh_.time().timeName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Read explicit feature edges
|
||||
Foam::label Foam::autoHexMeshDriver::readFeatureEdges()
|
||||
Foam::label Foam::autoHexMeshDriver::readFeatureEdges
|
||||
(
|
||||
const PtrList<dictionary>& featDicts
|
||||
)
|
||||
{
|
||||
Info<< "Reading external feature lines." << endl;
|
||||
|
||||
PtrList<dictionary> featDicts(dict_.lookup("features"));
|
||||
|
||||
featureMeshes_.setSize(featDicts.size());
|
||||
featureLevels_.setSize(featDicts.size());
|
||||
|
||||
@ -647,13 +931,13 @@ Foam::label Foam::autoHexMeshDriver::readFeatureEdges()
|
||||
|
||||
Foam::label Foam::autoHexMeshDriver::featureEdgeRefine
|
||||
(
|
||||
const PtrList<dictionary>& featDicts,
|
||||
const label maxIter,
|
||||
const label minRefine
|
||||
)
|
||||
{
|
||||
// Read explicit feature edges
|
||||
readFeatureEdges();
|
||||
|
||||
readFeatureEdges(featDicts);
|
||||
|
||||
meshRefinement& meshRefiner = meshRefinerPtr_();
|
||||
|
||||
@ -1359,19 +1643,14 @@ void Foam::autoHexMeshDriver::writeMesh(const string& msg) const
|
||||
}
|
||||
|
||||
|
||||
void Foam::autoHexMeshDriver::doMesh()
|
||||
|
||||
|
||||
void Foam::autoHexMeshDriver::doRefine
|
||||
(
|
||||
const dictionary& refineDict,
|
||||
const bool prepareForSnapping
|
||||
)
|
||||
{
|
||||
Switch doRefine(dict_.lookup("doRefine"));
|
||||
Switch doSnap(dict_.lookup("doSnap"));
|
||||
Switch doLayers(dict_.lookup("doLayers"));
|
||||
|
||||
Info<< "Do refinement : " << doRefine << nl
|
||||
<< "Do snapping : " << doSnap << nl
|
||||
<< "Do layers : " << doLayers << nl
|
||||
<< endl;
|
||||
|
||||
if (doRefine)
|
||||
{
|
||||
Info<< nl
|
||||
<< "Refinement phase" << nl
|
||||
<< "----------------" << nl
|
||||
@ -1379,9 +1658,12 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
|
||||
const_cast<Time&>(mesh_.time())++;
|
||||
|
||||
PtrList<dictionary> featDicts(refineDict.lookup("features"));
|
||||
|
||||
// Refine around feature edges
|
||||
featureEdgeRefine
|
||||
(
|
||||
featDicts,
|
||||
100, // maxIter
|
||||
0 // min cells to refine
|
||||
);
|
||||
@ -1405,16 +1687,16 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
);
|
||||
|
||||
// Introduce baffles at surface intersections
|
||||
baffleAndSplitMesh(doSnap);
|
||||
baffleAndSplitMesh(prepareForSnapping);
|
||||
|
||||
// Mesh is at its finest. Do optional zoning.
|
||||
zonify();
|
||||
|
||||
// Pull baffles apart
|
||||
splitAndMergeBaffles(doSnap);
|
||||
splitAndMergeBaffles(prepareForSnapping);
|
||||
|
||||
// Do something about cells with refined faces on the boundary
|
||||
if (doSnap)
|
||||
if (prepareForSnapping)
|
||||
{
|
||||
mergePatchFaces();
|
||||
}
|
||||
@ -1424,11 +1706,15 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
|
||||
// Write mesh
|
||||
writeMesh("Refined mesh");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (doSnap)
|
||||
{
|
||||
void Foam::autoHexMeshDriver::doSnap
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const dictionary& motionDict
|
||||
)
|
||||
{
|
||||
Info<< nl
|
||||
<< "Morphing phase" << nl
|
||||
<< "--------------" << nl
|
||||
@ -1456,12 +1742,11 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
indirectPrimitivePatch& pp = ppPtr();
|
||||
|
||||
// Distance to attact to nearest feature on surface
|
||||
const scalarField snapDist(calcSnapDistance(pp));
|
||||
const scalarField snapDist(calcSnapDistance(snapDict, pp));
|
||||
|
||||
|
||||
// Construct iterative mesh mover.
|
||||
Info<< "Constructing mesh displacer ..." << endl;
|
||||
const dictionary& motionDict = dict_.subDict("motionDict");
|
||||
Info<< "Using mesh parameters " << motionDict << nl << endl;
|
||||
|
||||
pointMesh pMesh(mesh_);
|
||||
@ -1495,17 +1780,17 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||
|
||||
// Pre-smooth patch vertices (so before determining nearest)
|
||||
preSmoothPatch(nInitErrors, baffles, meshMover);
|
||||
preSmoothPatch(snapDict, nInitErrors, baffles, meshMover);
|
||||
|
||||
// Calculate displacement at every patch point. Insert into
|
||||
// meshMover.
|
||||
calcNearestSurface(snapDist, meshMover);
|
||||
|
||||
// Get smoothly varying internal displacement field.
|
||||
smoothDisplacement(meshMover);
|
||||
smoothDisplacement(snapDict, meshMover);
|
||||
|
||||
// Apply internal displacement to mesh.
|
||||
scaleMesh(nInitErrors, baffles, meshMover);
|
||||
scaleMesh(snapDict, nInitErrors, baffles, meshMover);
|
||||
}
|
||||
|
||||
// Merge any introduced baffles.
|
||||
@ -1513,11 +1798,15 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
|
||||
// Write mesh.
|
||||
writeMesh("Snapped mesh");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (doLayers)
|
||||
{
|
||||
void Foam::autoHexMeshDriver::doLayers
|
||||
(
|
||||
const dictionary& shrinkDict,
|
||||
const dictionary& motionDict
|
||||
)
|
||||
{
|
||||
Info<< nl
|
||||
<< "Shrinking and layer addition phase" << nl
|
||||
<< "----------------------------------" << nl
|
||||
@ -1525,18 +1814,20 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
|
||||
const_cast<Time&>(mesh_.time())++;
|
||||
|
||||
Info<< "Using mesh parameters " << motionDict << nl << endl;
|
||||
|
||||
// Merge coplanar boundary faces
|
||||
mergePatchFacesUndo();
|
||||
mergePatchFacesUndo(shrinkDict, motionDict);
|
||||
|
||||
// Per global region the number of layers (0 if no layer)
|
||||
labelList nLayers(readNumLayers());
|
||||
const labelList& numLayers = surfaces().numLayers();
|
||||
|
||||
// Patches that need to get a layer
|
||||
DynamicList<label> patchIDs(nLayers.size());
|
||||
DynamicList<label> patchIDs(numLayers.size());
|
||||
label nFacesWithLayers = 0;
|
||||
forAll(nLayers, region)
|
||||
forAll(numLayers, region)
|
||||
{
|
||||
if (nLayers[region] > 0 && globalToPatch()[region] != -1)
|
||||
if (numLayers[region] > 0 && globalToPatch()[region] != -1)
|
||||
{
|
||||
label patchI = globalToPatch()[region];
|
||||
patchIDs.append(patchI);
|
||||
@ -1563,8 +1854,6 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
|
||||
// Construct iterative mesh mover.
|
||||
Info<< "Constructing mesh displacer ..." << endl;
|
||||
const dictionary& motionDict = dict_.subDict("motionDict");
|
||||
Info<< "Using mesh parameters " << motionDict << nl << endl;
|
||||
|
||||
{
|
||||
pointMesh pMesh(mesh_);
|
||||
@ -1595,14 +1884,46 @@ void Foam::autoHexMeshDriver::doMesh()
|
||||
<< " (concave, zero area or negative cell pyramid volume)"
|
||||
<< endl;
|
||||
|
||||
|
||||
// Do all topo changes
|
||||
addLayers(nInitErrors, meshMover);
|
||||
addLayers(shrinkDict, motionDict, nInitErrors, meshMover);
|
||||
}
|
||||
|
||||
// Write mesh.
|
||||
writeMesh("Layer mesh");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::autoHexMeshDriver::doMesh()
|
||||
{
|
||||
Switch wantRefine(dict_.lookup("doRefine"));
|
||||
Switch wantSnap(dict_.lookup("doSnap"));
|
||||
Switch wantLayers(dict_.lookup("doLayers"));
|
||||
|
||||
Info<< "Do refinement : " << wantRefine << nl
|
||||
<< "Do snapping : " << wantSnap << nl
|
||||
<< "Do layers : " << wantLayers << nl
|
||||
<< endl;
|
||||
|
||||
if (wantRefine)
|
||||
{
|
||||
doRefine(dict_, wantSnap);
|
||||
}
|
||||
|
||||
if (wantSnap)
|
||||
{
|
||||
const dictionary& snapDict = dict_.subDict("snapDict");
|
||||
const dictionary& motionDict = dict_.subDict("motionDict");
|
||||
|
||||
doSnap(snapDict, motionDict);
|
||||
}
|
||||
|
||||
if (wantLayers)
|
||||
{
|
||||
const dictionary& motionDict = dict_.subDict("motionDict");
|
||||
const dictionary& shrinkDict = dict_.subDict("shrinkDict");
|
||||
|
||||
doLayers(shrinkDict, motionDict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ class autoHexMeshDriver
|
||||
//- Reference to mesh
|
||||
fvMesh& mesh_;
|
||||
|
||||
//- Input dictionarys
|
||||
//- Input dictionary
|
||||
const dictionary dict_;
|
||||
|
||||
//- Debug level
|
||||
@ -164,7 +164,6 @@ class autoHexMeshDriver
|
||||
|
||||
|
||||
|
||||
|
||||
//- Explicit features
|
||||
PtrList<featureEdgeMesh> featureMeshes_;
|
||||
//- Per feature the refinement level
|
||||
@ -183,10 +182,6 @@ class autoHexMeshDriver
|
||||
//- Per refinement surface region the patch
|
||||
labelList globalToPatch_;
|
||||
|
||||
////- Per refinement surface with a valid faceZone the cyclicpatch
|
||||
//// (or -1)
|
||||
//labelList surfaceToCyclicPatch_;
|
||||
|
||||
//- Mesh refinement engine
|
||||
autoPtr<meshRefinement> meshRefinerPtr_;
|
||||
|
||||
@ -197,12 +192,13 @@ class autoHexMeshDriver
|
||||
autoPtr<fvMeshDistribute> distributorPtr_;
|
||||
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
// Refinement
|
||||
|
||||
//- Get merge tolerance. Check against writing tolerance.
|
||||
scalar getMergeDistance() const;
|
||||
//- Calculate merge distance. Check against writing tolerance.
|
||||
scalar getMergeDistance(const scalar mergeTol) const;
|
||||
|
||||
// Return per keeppoint -1 or the local cell label the point is in.
|
||||
// Guaranteed to be only on one processor.
|
||||
@ -211,7 +207,7 @@ class autoHexMeshDriver
|
||||
static void orientOutside(PtrList<searchableSurface>&);
|
||||
|
||||
//- Read feature edges
|
||||
label readFeatureEdges();
|
||||
label readFeatureEdges(const PtrList<dictionary>&);
|
||||
|
||||
// Snapping
|
||||
|
||||
@ -375,7 +371,6 @@ class autoHexMeshDriver
|
||||
// layers per surface.
|
||||
void setNumLayers
|
||||
(
|
||||
const labelList& nLayers,
|
||||
const labelList& patchIDs,
|
||||
const indirectPrimitivePatch& pp,
|
||||
pointField& patchDisp,
|
||||
@ -651,6 +646,16 @@ public:
|
||||
const dictionary& decomposeDict
|
||||
);
|
||||
|
||||
//- Alternative constructor from top-level controldictionary and
|
||||
// refinement specific dictionary
|
||||
autoHexMeshDriver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& controlDict,
|
||||
const dictionary& refineDict,
|
||||
const dictionary& decomposeDict
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -684,6 +689,7 @@ public:
|
||||
//- Refine around explicit feature edges
|
||||
label featureEdgeRefine
|
||||
(
|
||||
const PtrList<dictionary>& featDicts,
|
||||
const label maxIter,
|
||||
const label minRefine
|
||||
);
|
||||
@ -734,7 +740,11 @@ public:
|
||||
autoPtr<mapPolyMesh> mergeZoneBaffles(const List<labelPair>&);
|
||||
|
||||
//- Calculate edge length per patch point.
|
||||
scalarField calcSnapDistance(const indirectPrimitivePatch&) const;
|
||||
scalarField calcSnapDistance
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const indirectPrimitivePatch&
|
||||
) const;
|
||||
|
||||
//- Get patches generated for surfaces.
|
||||
labelList getSurfacePatches() const;
|
||||
@ -743,6 +753,7 @@ public:
|
||||
// of surface points (on castellated mesh) w.r.t. surface.
|
||||
void preSmoothPatch
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const label nInitErrors,
|
||||
const List<labelPair>& baffles,
|
||||
motionSmoother&
|
||||
@ -758,12 +769,17 @@ public:
|
||||
) const;
|
||||
|
||||
//- Smooth the displacement field to the internal.
|
||||
void smoothDisplacement(motionSmoother&) const;
|
||||
void smoothDisplacement
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
motionSmoother&
|
||||
) const;
|
||||
|
||||
//- Do the hard work: move the mesh according to displacement,
|
||||
// locally relax the displacement.
|
||||
void scaleMesh
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const label nInitErrors,
|
||||
const List<labelPair>& baffles,
|
||||
motionSmoother&
|
||||
@ -773,23 +789,50 @@ public:
|
||||
// Layers
|
||||
|
||||
//- Merge patch faces on same cell.
|
||||
void mergePatchFacesUndo();
|
||||
|
||||
//- Read layer per region
|
||||
labelList readNumLayers() const;
|
||||
void mergePatchFacesUndo
|
||||
(
|
||||
const dictionary& shrinkDict,
|
||||
const dictionary& motionDict
|
||||
);
|
||||
|
||||
//- Check that mesh outside is not multiply connected.
|
||||
void checkMeshManifold() const;
|
||||
|
||||
//- Add cell layers
|
||||
void addLayers(const scalar nAllowableErrors, motionSmoother&);
|
||||
void addLayers
|
||||
(
|
||||
const dictionary& shrinkDict,
|
||||
const dictionary& motionDict,
|
||||
const scalar nAllowableErrors,
|
||||
motionSmoother&
|
||||
);
|
||||
|
||||
|
||||
// Other
|
||||
|
||||
//- Do all refinement.
|
||||
void doRefine
|
||||
(
|
||||
const dictionary& refineDict,
|
||||
const bool prepareForSnapping
|
||||
);
|
||||
|
||||
//- Do all snapping.
|
||||
void doSnap
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const dictionary& motionDict
|
||||
);
|
||||
|
||||
//- Do alllayer addition.
|
||||
void doLayers
|
||||
(
|
||||
const dictionary& shrinkDict,
|
||||
const dictionary& motionDict
|
||||
);
|
||||
|
||||
//- Do all : refine, snap, layers
|
||||
void doMesh();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -61,6 +61,30 @@ Foam::label Foam::autoHexMeshDriver::mergePatchFacesUndo
|
||||
// Patch face merging engine
|
||||
combineFaces faceCombiner(mesh_, true);
|
||||
|
||||
// Pick up all candidate cells on boundary
|
||||
labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
|
||||
|
||||
{
|
||||
labelList patchIDs(meshRefinement::addedPatches(globalToPatch_));
|
||||
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
forAll(patchIDs, i)
|
||||
{
|
||||
label patchI = patchIDs[i];
|
||||
|
||||
const polyPatch& patch = patches[patchI];
|
||||
|
||||
if (!patch.coupled())
|
||||
{
|
||||
forAll(patch, i)
|
||||
{
|
||||
boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all sets of faces that can be merged
|
||||
labelListList allFaceSets
|
||||
(
|
||||
@ -68,7 +92,7 @@ Foam::label Foam::autoHexMeshDriver::mergePatchFacesUndo
|
||||
(
|
||||
minCos,
|
||||
concaveCos,
|
||||
meshRefinement::addedPatches(globalToPatch_)
|
||||
boundaryCells
|
||||
)
|
||||
);
|
||||
|
||||
@ -1164,91 +1188,9 @@ void Foam::autoHexMeshDriver::handleWarpedFaces
|
||||
//}
|
||||
|
||||
|
||||
Foam::labelList Foam::autoHexMeshDriver::readNumLayers() const
|
||||
{
|
||||
// Read dictionary information
|
||||
// (could already be extracted in refinementSurfaces?)
|
||||
|
||||
const PtrList<dictionary>& surfaceDicts = dict_.lookup("surfaces");
|
||||
|
||||
labelList globalSurfLayers(surfaceDicts.size());
|
||||
List<HashTable<label> > regionSurfLayers(surfaceDicts.size());
|
||||
|
||||
forAll(surfaceDicts, surfI)
|
||||
{
|
||||
const dictionary& dict = surfaceDicts[surfI];
|
||||
|
||||
globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
|
||||
|
||||
if (dict.found("regions"))
|
||||
{
|
||||
// Per-region layer information
|
||||
|
||||
PtrList<dictionary> regionDicts(dict.lookup("regions"));
|
||||
|
||||
forAll(regionDicts, dictI)
|
||||
{
|
||||
const dictionary& regionDict = regionDicts[dictI];
|
||||
|
||||
const word regionName(regionDict.lookup("name"));
|
||||
|
||||
label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
|
||||
|
||||
Info<< " region " << regionName << ':'<< nl
|
||||
<< " surface layers:" << nLayers << nl;
|
||||
|
||||
regionSurfLayers[surfI].insert(regionName, nLayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Transfer per surface/region information into global region info
|
||||
|
||||
labelList nLayers(surfaces().minLevel().size(), 0);
|
||||
|
||||
forAll(surfaces(), surfI)
|
||||
{
|
||||
const geometricSurfacePatchList& regions = surfaces()[surfI].patches();
|
||||
|
||||
forAll(regions, regionI)
|
||||
{
|
||||
label global = surfaces().globalRegion(surfI, regionI);
|
||||
|
||||
// Initialise to surface-wise layers
|
||||
nLayers[global] = globalSurfLayers[surfI];
|
||||
|
||||
// Override with region specific data if available
|
||||
HashTable<label>::const_iterator iter =
|
||||
regionSurfLayers[surfI].find(regions[regionI].name());
|
||||
|
||||
if (iter != regionSurfLayers[surfI].end())
|
||||
{
|
||||
nLayers[global] = iter();
|
||||
}
|
||||
|
||||
// Check
|
||||
if (nLayers[global] < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"autoHexMeshDriver::readNumLayers()"
|
||||
) << "Illegal number of layers " << nLayers[global]
|
||||
<< " for surface "
|
||||
<< surfaces().names()[surfI]
|
||||
<< " region " << regions[regionI].name() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nLayers;
|
||||
}
|
||||
|
||||
|
||||
// No extrusion on faces with differing number of layers for points
|
||||
void Foam::autoHexMeshDriver::setNumLayers
|
||||
(
|
||||
const labelList& nLayers,
|
||||
const labelList& patchIDs,
|
||||
const indirectPrimitivePatch& pp,
|
||||
pointField& patchDisp,
|
||||
@ -1259,13 +1201,15 @@ void Foam::autoHexMeshDriver::setNumLayers
|
||||
Info<< nl << "Handling points with inconsistent layer specification ..."
|
||||
<< endl;
|
||||
|
||||
const labelList& nSurfLayers = surfaces().numLayers();
|
||||
|
||||
// Build map from patch to layers
|
||||
Map<label> patchToNLayers(nLayers.size());
|
||||
forAll(nLayers, region)
|
||||
Map<label> patchToNLayers(nSurfLayers.size());
|
||||
forAll(nSurfLayers, region)
|
||||
{
|
||||
if (globalToPatch_[region] != -1)
|
||||
{
|
||||
patchToNLayers.insert(globalToPatch_[region], nLayers[region]);
|
||||
patchToNLayers.insert(globalToPatch_[region], nSurfLayers[region]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2363,10 +2307,12 @@ void Foam::autoHexMeshDriver::getLayerCellsFaces
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::autoHexMeshDriver::mergePatchFacesUndo()
|
||||
void Foam::autoHexMeshDriver::mergePatchFacesUndo
|
||||
(
|
||||
const dictionary& shrinkDict,
|
||||
const dictionary& motionDict
|
||||
)
|
||||
{
|
||||
const dictionary& shrinkDict = dict_.subDict("shrinkDict");
|
||||
|
||||
const scalar featureAngle(readScalar(shrinkDict.lookup("featureAngle")));
|
||||
scalar minCos = Foam::cos(featureAngle*mathematicalConstant::pi/180.0);
|
||||
|
||||
@ -2390,9 +2336,6 @@ void Foam::autoHexMeshDriver::mergePatchFacesUndo()
|
||||
<< concaveAngle << " degrees (0=straight, 180=fully concave)" << nl
|
||||
<< endl;
|
||||
|
||||
|
||||
const dictionary& motionDict = dict_.subDict("motionDict");
|
||||
|
||||
label nChanged = mergePatchFacesUndo(minCos, concaveCos, motionDict);
|
||||
|
||||
nChanged += mergeEdgesUndo(minCos, motionDict);
|
||||
@ -2401,6 +2344,8 @@ void Foam::autoHexMeshDriver::mergePatchFacesUndo()
|
||||
|
||||
void Foam::autoHexMeshDriver::addLayers
|
||||
(
|
||||
const dictionary& shrinkDict,
|
||||
const dictionary& motionDict,
|
||||
const scalar nAllowableErrors,
|
||||
motionSmoother& meshMover
|
||||
)
|
||||
@ -2408,8 +2353,6 @@ void Foam::autoHexMeshDriver::addLayers
|
||||
// Read some more dictionary settings
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const dictionary& shrinkDict = dict_.subDict("shrinkDict");
|
||||
|
||||
// Min thickness per cell
|
||||
const scalar relMinThickness(readScalar(shrinkDict.lookup("minThickness")));
|
||||
|
||||
@ -2506,7 +2449,6 @@ void Foam::autoHexMeshDriver::addLayers
|
||||
|
||||
setNumLayers
|
||||
(
|
||||
readNumLayers(),
|
||||
meshMover.adaptPatchIDs(),
|
||||
pp,
|
||||
|
||||
@ -2923,7 +2865,7 @@ void Foam::autoHexMeshDriver::addLayers
|
||||
label nTotChanged = checkAndUnmark
|
||||
(
|
||||
addLayer,
|
||||
dict_.subDict("motionDict"),
|
||||
motionDict,
|
||||
pp,
|
||||
newMesh,
|
||||
|
||||
|
||||
@ -755,10 +755,10 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::mergeZoneBaffles
|
||||
|
||||
Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const indirectPrimitivePatch& pp
|
||||
) const
|
||||
{
|
||||
const dictionary& snapDict = dict_.subDict("snapDict");
|
||||
// When to snap
|
||||
scalar snapTol(readScalar(snapDict.lookup("snapTol")));
|
||||
|
||||
@ -826,12 +826,12 @@ Foam::labelList Foam::autoHexMeshDriver::getSurfacePatches() const
|
||||
|
||||
void Foam::autoHexMeshDriver::preSmoothPatch
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const label nInitErrors,
|
||||
const List<labelPair>& baffles,
|
||||
motionSmoother& meshMover
|
||||
) const
|
||||
{
|
||||
const dictionary& snapDict = dict_.subDict("snapDict");
|
||||
// Smoothing iterations
|
||||
label nSmoothPatch(readLabel(snapDict.lookup("nSmoothPatch")));
|
||||
// Snapping iterations
|
||||
@ -1076,15 +1076,17 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
||||
}
|
||||
|
||||
|
||||
void Foam::autoHexMeshDriver::smoothDisplacement(motionSmoother& meshMover)
|
||||
const
|
||||
void Foam::autoHexMeshDriver::smoothDisplacement
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
motionSmoother& meshMover
|
||||
) const
|
||||
{
|
||||
const pointMesh& pMesh = meshMover.pMesh();
|
||||
const indirectPrimitivePatch& pp = meshMover.patch();
|
||||
|
||||
Info<< "Smoothing displacement ..." << endl;
|
||||
|
||||
const dictionary& snapDict = dict_.subDict("snapDict");
|
||||
// Smoothing iterations
|
||||
label nSmoothDisp(readLabel(snapDict.lookup("nSmoothDispl")));
|
||||
|
||||
@ -1138,12 +1140,12 @@ void Foam::autoHexMeshDriver::smoothDisplacement(motionSmoother& meshMover)
|
||||
|
||||
void Foam::autoHexMeshDriver::scaleMesh
|
||||
(
|
||||
const dictionary& snapDict,
|
||||
const label nInitErrors,
|
||||
const List<labelPair>& baffles,
|
||||
motionSmoother& meshMover
|
||||
)
|
||||
{
|
||||
const dictionary& snapDict = dict_.subDict("snapDict");
|
||||
// Snapping iterations
|
||||
label nSnap(readLabel(snapDict.lookup("nSnap")));
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ Foam::label Foam::meshRefinement::mergePatchFaces
|
||||
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
// Pick up all cells on boundary
|
||||
// Pick up all candidate cells on boundary
|
||||
labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
|
||||
|
||||
forAll(patchIDs, i)
|
||||
|
||||
@ -73,38 +73,41 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
List<HashTable<label> > regionMinLevel(surfaceDicts.size());
|
||||
List<HashTable<label> > regionMaxLevel(surfaceDicts.size());
|
||||
|
||||
forAll(surfaceDicts, i)
|
||||
labelList globalSurfLayers(surfaceDicts.size());
|
||||
List<HashTable<label> > regionSurfLayers(surfaceDicts.size());
|
||||
|
||||
wordList globalPatchType(surfaceDicts.size());
|
||||
List<HashTable<word> > regionPatchType(surfaceDicts.size());
|
||||
List<HashTable<word> > regionPatchName(surfaceDicts.size());
|
||||
|
||||
forAll(surfaceDicts, surfI)
|
||||
{
|
||||
const dictionary& dict = surfaceDicts[i];
|
||||
const dictionary& dict = surfaceDicts[surfI];
|
||||
|
||||
names_[i] = word(dict.lookup("name"));
|
||||
names_[surfI] = word(dict.lookup("name"));
|
||||
|
||||
globalMinLevel[i] = readLabel(dict.lookup("minRefinementLevel"));
|
||||
globalMaxLevel[i] = readLabel(dict.lookup("maxRefinementLevel"));
|
||||
// Global refinement level
|
||||
globalMinLevel[surfI] = readLabel(dict.lookup("minRefinementLevel"));
|
||||
globalMaxLevel[surfI] = readLabel(dict.lookup("maxRefinementLevel"));
|
||||
|
||||
if
|
||||
(
|
||||
globalMinLevel[i] < 0
|
||||
|| globalMaxLevel[i] < globalMinLevel[i]
|
||||
)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"refinementSurfaces::refinementSurfaces"
|
||||
"(const IOobject&, const PtrList<dictionary>&)"
|
||||
) << "Illegal level specification for surface " << names_[i]
|
||||
<< " : minLevel:" << globalMinLevel[i]
|
||||
<< " maxLevel:" << globalMaxLevel[i]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
// Global number of layers
|
||||
globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
|
||||
|
||||
// Global zone names per surface
|
||||
if (dict.found("faceZone"))
|
||||
{
|
||||
dict.lookup("faceZone") >> faceZoneNames_[i];
|
||||
dict.lookup("cellZone") >> cellZoneNames_[i];
|
||||
dict.lookup("zoneInside") >> zoneInside_[i];
|
||||
dict.lookup("faceZone") >> faceZoneNames_[surfI];
|
||||
dict.lookup("cellZone") >> cellZoneNames_[surfI];
|
||||
dict.lookup("zoneInside") >> zoneInside_[surfI];
|
||||
}
|
||||
|
||||
// Global patch name per surface
|
||||
if (dict.found("patchType"))
|
||||
{
|
||||
dict.lookup("patchType") >> globalPatchType[surfI];
|
||||
}
|
||||
|
||||
|
||||
if (dict.found("regions"))
|
||||
{
|
||||
PtrList<dictionary> regionDicts(dict.lookup("regions"));
|
||||
@ -117,11 +120,71 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
label min = readLabel(regionDict.lookup("minRefinementLevel"));
|
||||
label max = readLabel(regionDict.lookup("maxRefinementLevel"));
|
||||
|
||||
regionMinLevel[i].insert(regionName, min);
|
||||
regionMaxLevel[i].insert(regionName, max);
|
||||
regionMinLevel[surfI].insert(regionName, min);
|
||||
regionMaxLevel[surfI].insert(regionName, max);
|
||||
|
||||
label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
|
||||
regionSurfLayers[surfI].insert(regionName, nLayers);
|
||||
|
||||
if (regionDict.found("patchType"))
|
||||
{
|
||||
regionPatchType[surfI].insert
|
||||
(
|
||||
regionName,
|
||||
regionDict.lookup("patchType")
|
||||
);
|
||||
regionPatchName[surfI].insert
|
||||
(
|
||||
regionName,
|
||||
regionDict.lookup("patchName")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for duplicate surface or region names
|
||||
{
|
||||
HashTable<label> surfaceNames(names_.size());
|
||||
|
||||
forAll(names_, surfI)
|
||||
{
|
||||
if (!surfaceNames.insert(names_[surfI], surfI))
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"refinementSurfaces::refinementSurfaces"
|
||||
"(const IOobject&, const PtrList<dictionary>&)"
|
||||
) << "Duplicate surface name " << names_[surfI] << endl
|
||||
<< "Previous occurrence of name at surface "
|
||||
<< surfaceNames[names_[surfI]]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Check for duplicate region names
|
||||
const geometricSurfacePatchList& patches =
|
||||
operator[](surfI).patches();
|
||||
|
||||
HashTable<label> regionNames(patches.size());
|
||||
forAll(patches, i)
|
||||
{
|
||||
if (!regionNames.insert(patches[i].name(), i))
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"refinementSurfaces::refinementSurfaces"
|
||||
"(const IOobject&, const PtrList<dictionary>&)"
|
||||
) << "Duplicate region name " << patches[i].name()
|
||||
<< " on surface " << names_[surfI] << endl
|
||||
<< "Previous occurrence of region at index "
|
||||
<< regionNames[patches[i].name()]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate closedness
|
||||
forAll(closed_, surfI)
|
||||
@ -151,37 +214,89 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
nRegions += operator[](surfI).patches().size();
|
||||
}
|
||||
|
||||
// From global region number to refinement level
|
||||
// Rework surface specific information into information per global region
|
||||
minLevel_.setSize(nRegions);
|
||||
minLevel_ = 0;
|
||||
maxLevel_.setSize(nRegions);
|
||||
maxLevel_ = 0;
|
||||
numLayers_.setSize(nRegions);
|
||||
numLayers_ = 0;
|
||||
patchName_.setSize(nRegions);
|
||||
patchType_.setSize(nRegions);
|
||||
|
||||
forAll(surfaceDicts, surfI)
|
||||
{
|
||||
const geometricSurfacePatchList& regions = operator[](surfI).patches();
|
||||
|
||||
// Initialise to global (i.e. per surface)
|
||||
forAll(regions, i)
|
||||
{
|
||||
minLevel_[regionOffset_[surfI] + i] = globalMinLevel[surfI];
|
||||
maxLevel_[regionOffset_[surfI] + i] = globalMaxLevel[surfI];
|
||||
numLayers_[regionOffset_[surfI] + i] = globalSurfLayers[surfI];
|
||||
patchType_[regionOffset_[surfI] + i] = globalPatchType[surfI];
|
||||
}
|
||||
|
||||
forAllConstIter(HashTable<label>, regionMinLevel[surfI], iter)
|
||||
{
|
||||
// Find the patch
|
||||
// Get the region names
|
||||
wordList regionNames(regions.size());
|
||||
forAll(regions, regionI)
|
||||
{
|
||||
if (regions[regionI].name() == iter.key())
|
||||
regionNames[regionI] = regions[regionI].name();
|
||||
}
|
||||
|
||||
// Overwrite with region specific information
|
||||
forAllConstIter(HashTable<label>, regionMinLevel[surfI], iter)
|
||||
{
|
||||
// Find the local region number.
|
||||
label regionI = findIndex(regionNames, iter.key());
|
||||
|
||||
if (regionI == -1)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"refinementSurfaces::refinementSurfaces"
|
||||
"(const IOobject&, const PtrList<dictionary>&)"
|
||||
) << "Cannot find region " << iter.key()
|
||||
<< " in surface " << names_[surfI]
|
||||
<< " which has regions " << regionNames
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
label globalRegionI = regionOffset_[surfI] + regionI;
|
||||
|
||||
minLevel_[globalRegionI] = iter();
|
||||
maxLevel_[globalRegionI] =
|
||||
regionMaxLevel[surfI][iter.key()];
|
||||
break;
|
||||
maxLevel_[globalRegionI] = regionMaxLevel[surfI][iter.key()];
|
||||
numLayers_[globalRegionI] = regionSurfLayers[surfI][iter.key()];
|
||||
|
||||
// Check validity
|
||||
if
|
||||
(
|
||||
minLevel_[globalRegionI] < 0
|
||||
|| maxLevel_[globalRegionI] < minLevel_[globalRegionI]
|
||||
|| numLayers_[globalRegionI] < 0
|
||||
)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"refinementSurfaces::refinementSurfaces"
|
||||
"(const IOobject&, const PtrList<dictionary>&)"
|
||||
) << "Illegal level or layer specification for surface "
|
||||
<< names_[surfI]
|
||||
<< " : minLevel:" << minLevel_[globalRegionI]
|
||||
<< " maxLevel:" << maxLevel_[globalRegionI]
|
||||
<< " numLayers:" << numLayers_[globalRegionI]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Optional patch names and patch types
|
||||
forAllConstIter(HashTable<word>, regionPatchName[surfI], iter)
|
||||
{
|
||||
label regionI = findIndex(regionNames, iter.key());
|
||||
label globalRegionI = regionOffset_[surfI] + regionI;
|
||||
|
||||
patchName_[globalRegionI] = iter();
|
||||
patchType_[globalRegionI] = regionPatchType[surfI][iter.key()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ class refinementSurfaces
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Name (word)
|
||||
//- Surface name (word)
|
||||
wordList names_;
|
||||
|
||||
//- Per surface whether is closed
|
||||
@ -86,6 +86,16 @@ class refinementSurfaces
|
||||
//- From global region number to refinement level
|
||||
labelList maxLevel_;
|
||||
|
||||
//- From global region number to added layers
|
||||
labelList numLayers_;
|
||||
|
||||
//- From global region number to patch name
|
||||
wordList patchName_;
|
||||
|
||||
//- From global region number to patch name
|
||||
wordList patchType_;
|
||||
|
||||
|
||||
//- Per surface refinement level adapted for shells.
|
||||
PtrList<triSurfaceLabelField> minLevelFields_;
|
||||
|
||||
@ -169,6 +179,24 @@ public:
|
||||
return maxLevel_;
|
||||
}
|
||||
|
||||
//- From global region number to added layers
|
||||
const labelList& numLayers() const
|
||||
{
|
||||
return numLayers_;
|
||||
}
|
||||
|
||||
//- From global region number to patch name. Patchnames can be empty
|
||||
const wordList& patchName() const
|
||||
{
|
||||
return patchName_;
|
||||
}
|
||||
|
||||
//- From global region number to patch name
|
||||
const wordList& patchType() const
|
||||
{
|
||||
return patchType_;
|
||||
}
|
||||
|
||||
|
||||
// Helper
|
||||
|
||||
|
||||
Reference in New Issue
Block a user