mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: snappyHexMesh: various improvements. See below or the default snappyHexMeshDict.
Refinement:
-----------
// Optionally avoid patch merging - keeps hexahedral cells
// (to be used with automatic refinement/unrefinement)
//mergePatchFaces off;
// Optional multiple locationsInMesh with corresponding optional cellZone
// (automatically generates faceZones inbetween)
locationsInMesh
(
((-0.09 -0.039 -0.049) bottomAir) // cellZone bottomAir
((-0.09 0.009 -0.049) topAir) // cellZone topAir
);
// Optional faceType and patchType specification for these faceZones
faceZoneControls
{
bottomAir_to_topAir
{
faceType baffle;
}
}
/ Optional checking of 'bleeding' of mesh through a specifying a locations
// outside the mesh
locationsOutsideMesh ((0 0 0)(12.3 101.17 3.98));
// Improved refinement: refine all cells with all (or all but one) sides refined
// Improved refinement: refine all cells with opposing faces with different
// refinement level. These cells can happen on multiply curved surfaces.
// Default on, can be switched off with
//interfaceRefine false;
Snapping
--------
// Optional smoothing of points at refinement interfaces. This will reduce
// the non-orthogonality at refinement interfaces.
//nSmoothInternal $nSmoothPatch;
Layering
--------
// Layers can be added to patches or to any side of a faceZone.
// (Any faceZone internally gets represented as two patches)
// The angle to merge patch faces can be set independently of the
// featureAngle. This is especially useful for large feature angles
// Default is the same as the featureAngle.
//mergePatchFacesAngle 45;
// Optional mesh shrinking type 'displacementMotionSolver'. It uses any
// displacementMotionSolver, e.g. displacementSBRStress
// (default is the medial-axis algorithm, 'displacementMedialAxis')
//meshShrinker displacementMotionSolver;
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -493,21 +493,30 @@ int main(int argc, char *argv[])
|
||||
// new patchID to neighbour processor)
|
||||
// - number of new patches (nPatches)
|
||||
|
||||
labelList sidePatchID;
|
||||
labelList edgePatchID;
|
||||
labelList edgeZoneID;
|
||||
boolList edgeFlip;
|
||||
labelList inflateFaceID;
|
||||
label nPatches;
|
||||
Map<label> nbrProcToPatch;
|
||||
Map<label> patchToNbrProc;
|
||||
addPatchCellLayer::calcSidePatch
|
||||
addPatchCellLayer::calcExtrudeInfo
|
||||
(
|
||||
true, // for internal edges get zone info from any face
|
||||
|
||||
mesh,
|
||||
globalFaces,
|
||||
edgeGlobalFaces,
|
||||
extrudePatch,
|
||||
|
||||
sidePatchID,
|
||||
edgePatchID,
|
||||
nPatches,
|
||||
nbrProcToPatch,
|
||||
patchToNbrProc
|
||||
patchToNbrProc,
|
||||
|
||||
edgeZoneID,
|
||||
edgeFlip,
|
||||
inflateFaceID
|
||||
);
|
||||
|
||||
|
||||
@ -659,7 +668,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
ratio, // expansion ratio
|
||||
extrudePatch, // patch faces to extrude
|
||||
sidePatchID, // if boundary edge: patch to use
|
||||
|
||||
edgePatchID, // if boundary edge: patch for extruded face
|
||||
edgeZoneID, // optional zone for extruded face
|
||||
edgeFlip,
|
||||
inflateFaceID, // mesh face that zone/patch info is from
|
||||
|
||||
exposedPatchID, // if new mesh: patches for exposed faces
|
||||
nFaceLayers,
|
||||
nPointLayers,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -1121,6 +1121,38 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
|
||||
// Refinement parameters
|
||||
const refinementParameters refineParams(refineDict);
|
||||
|
||||
// Snap parameters
|
||||
const snapParameters snapParams(snapDict);
|
||||
|
||||
|
||||
|
||||
// Add all the cellZones and faceZones
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// 1. cellZones relating to surface (faceZones added later)
|
||||
|
||||
const labelList namedSurfaces
|
||||
(
|
||||
surfaceZonesInfo::getNamedSurfaces(surfaces.surfZones())
|
||||
);
|
||||
|
||||
labelList surfaceToCellZone = surfaceZonesInfo::addCellZonesToMesh
|
||||
(
|
||||
surfaces.surfZones(),
|
||||
namedSurfaces,
|
||||
mesh
|
||||
);
|
||||
|
||||
|
||||
// 2. cellZones relating to locations
|
||||
|
||||
refineParams.addCellZonesToMesh(mesh);
|
||||
|
||||
|
||||
|
||||
// Add all the surface regions as patches
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -1128,6 +1160,8 @@ int main(int argc, char *argv[])
|
||||
// (faceZone surfaces)
|
||||
labelList globalToMasterPatch;
|
||||
labelList globalToSlavePatch;
|
||||
|
||||
|
||||
{
|
||||
Info<< nl
|
||||
<< "Adding patches for surface regions" << nl
|
||||
@ -1148,6 +1182,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
const labelList& surfaceGeometry = surfaces.surfaces();
|
||||
const PtrList<dictionary>& surfacePatchInfo = surfaces.patchInfo();
|
||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||
|
||||
forAll(surfaceGeometry, surfI)
|
||||
{
|
||||
@ -1157,7 +1192,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< surfaces.names()[surfI] << ':' << nl << nl;
|
||||
|
||||
if (surfaces.surfZones()[surfI].faceZoneName().empty())
|
||||
const word& fzName = surfaces.surfZones()[surfI].faceZoneName();
|
||||
|
||||
if (fzName.empty())
|
||||
{
|
||||
// 'Normal' surface
|
||||
forAll(regNames, i)
|
||||
@ -1188,7 +1225,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< setf(ios_base::left)
|
||||
<< setw(6) << patchI
|
||||
<< setw(20) << mesh.boundaryMesh()[patchI].type()
|
||||
<< setw(20) << pbm[patchI].type()
|
||||
<< setw(30) << regNames[i] << nl;
|
||||
|
||||
globalToMasterPatch[globalRegionI] = patchI;
|
||||
@ -1228,7 +1265,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< setf(ios_base::left)
|
||||
<< setw(6) << patchI
|
||||
<< setw(20) << mesh.boundaryMesh()[patchI].type()
|
||||
<< setw(20) << pbm[patchI].type()
|
||||
<< setw(30) << regNames[i] << nl;
|
||||
|
||||
globalToMasterPatch[globalRegionI] = patchI;
|
||||
@ -1260,12 +1297,27 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< setf(ios_base::left)
|
||||
<< setw(6) << patchI
|
||||
<< setw(20) << mesh.boundaryMesh()[patchI].type()
|
||||
<< setw(20) << pbm[patchI].type()
|
||||
<< setw(30) << slaveName << nl;
|
||||
|
||||
globalToSlavePatch[globalRegionI] = patchI;
|
||||
}
|
||||
}
|
||||
|
||||
// For now: have single faceZone per surface. Use first
|
||||
// region in surface for patch for zoneing
|
||||
if (regNames.size())
|
||||
{
|
||||
label globalRegionI = surfaces.globalRegion(surfI, 0);
|
||||
|
||||
meshRefiner.addFaceZone
|
||||
(
|
||||
fzName,
|
||||
pbm[globalToMasterPatch[globalRegionI]].name(),
|
||||
pbm[globalToSlavePatch[globalRegionI]].name(),
|
||||
surfaces.surfZones()[surfI].faceType()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Info<< nl;
|
||||
@ -1275,10 +1327,85 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Add all information for all the remaining faceZones
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
HashTable<Pair<word> > faceZoneToPatches;
|
||||
forAll(mesh.faceZones(), zoneI)
|
||||
{
|
||||
const word& fzName = mesh.faceZones()[zoneI].name();
|
||||
|
||||
label mpI, spI;
|
||||
surfaceZonesInfo::faceZoneType fzType;
|
||||
bool hasInfo = meshRefiner.getFaceZoneInfo(fzName, mpI, spI, fzType);
|
||||
|
||||
if (!hasInfo)
|
||||
{
|
||||
// faceZone does not originate from a surface but presumably
|
||||
// from a cellZone pair instead
|
||||
string::size_type i = fzName.find("_to_");
|
||||
if (i != string::npos)
|
||||
{
|
||||
word cz0 = fzName.substr(0, i);
|
||||
word cz1 = fzName.substr(i+4, fzName.size()-i+4);
|
||||
word slaveName(cz1 + "_to_" + cz0);
|
||||
faceZoneToPatches.insert(fzName, Pair<word>(fzName, slaveName));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add as fzName + fzName_slave
|
||||
const word slaveName = fzName + "_slave";
|
||||
faceZoneToPatches.insert(fzName, Pair<word>(fzName, slaveName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (faceZoneToPatches.size())
|
||||
{
|
||||
autoRefineDriver::addFaceZones
|
||||
(
|
||||
meshRefiner,
|
||||
refineParams,
|
||||
faceZoneToPatches
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Re-do intersections on meshed boundaries since they use an extrapolated
|
||||
// other side
|
||||
{
|
||||
const labelList adaptPatchIDs(meshRefiner.meshedPatches());
|
||||
|
||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||
|
||||
label nFaces = 0;
|
||||
forAll(adaptPatchIDs, i)
|
||||
{
|
||||
nFaces += pbm[adaptPatchIDs[i]].size();
|
||||
}
|
||||
|
||||
labelList faceLabels(nFaces);
|
||||
nFaces = 0;
|
||||
forAll(adaptPatchIDs, i)
|
||||
{
|
||||
const polyPatch& pp = pbm[adaptPatchIDs[i]];
|
||||
forAll(pp, i)
|
||||
{
|
||||
faceLabels[nFaces++] = pp.start()+i;
|
||||
}
|
||||
}
|
||||
meshRefiner.updateIntersections(faceLabels);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Parallel
|
||||
// ~~~~~~~~
|
||||
|
||||
// Decomposition
|
||||
// Construct decomposition engine. Note: cannot use decompositionModel
|
||||
// MeshObject since we're clearing out the mesh inside the mesh generation.
|
||||
autoPtr<decompositionMethod> decomposerPtr
|
||||
(
|
||||
decompositionMethod::New
|
||||
@ -1312,14 +1439,17 @@ int main(int argc, char *argv[])
|
||||
const Switch wantSnap(meshDict.lookup("snap"));
|
||||
const Switch wantLayers(meshDict.lookup("addLayers"));
|
||||
|
||||
// Refinement parameters
|
||||
const refinementParameters refineParams(refineDict);
|
||||
const Switch mergePatchFaces
|
||||
(
|
||||
meshDict.lookupOrDefault("mergePatchFaces", true)
|
||||
);
|
||||
|
||||
// Snap parameters
|
||||
const snapParameters snapParams(snapDict);
|
||||
|
||||
// Layer addition parameters
|
||||
const layerParameters layerParams(layerDict, mesh.boundaryMesh());
|
||||
if (!mergePatchFaces)
|
||||
{
|
||||
Info<< "Not merging patch-faces of cell to preserve"
|
||||
<< " (split)hex cell shape."
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
|
||||
if (wantRefine)
|
||||
@ -1348,6 +1478,7 @@ int main(int argc, char *argv[])
|
||||
refineParams,
|
||||
snapParams,
|
||||
refineParams.handleSnapProblems(),
|
||||
mergePatchFaces, // merge co-planar faces
|
||||
motionDict
|
||||
);
|
||||
|
||||
@ -1387,6 +1518,7 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
snapDict,
|
||||
motionDict,
|
||||
mergePatchFaces,
|
||||
curvature,
|
||||
planarAngle,
|
||||
snapParams
|
||||
@ -1408,6 +1540,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
cpuTime timer;
|
||||
|
||||
// Layer addition parameters
|
||||
const layerParameters layerParams(layerDict, mesh.boundaryMesh());
|
||||
|
||||
autoLayerDriver layerDriver
|
||||
(
|
||||
meshRefiner,
|
||||
@ -1433,6 +1568,7 @@ int main(int argc, char *argv[])
|
||||
layerDict,
|
||||
motionDict,
|
||||
layerParams,
|
||||
mergePatchFaces,
|
||||
preBalance,
|
||||
decomposer,
|
||||
distributor
|
||||
|
||||
@ -71,6 +71,11 @@ geometry
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Optional: avoid patch-face merging. Allows mesh to be used for
|
||||
// refinement/unrefinement
|
||||
//mergePatchFaces off; // default on
|
||||
|
||||
// Settings for the castellatedMesh generation.
|
||||
castellatedMeshControls
|
||||
{
|
||||
@ -177,7 +182,7 @@ castellatedMeshControls
|
||||
// how to select the cells that are in the cellZone
|
||||
// (inside / outside / specified insidePoint)
|
||||
// The orientation of the faceZone is
|
||||
// - if on cellZone(s) : point out of (maximum) cellZone
|
||||
// - if on cellZone(s) : point out of (minimum) cellZone
|
||||
// - if freestanding : oriented according to surface
|
||||
|
||||
//faceZone sphere;
|
||||
@ -249,16 +254,70 @@ castellatedMeshControls
|
||||
|
||||
// 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.
|
||||
// section reachable from the location(s)InMesh is kept.
|
||||
// NOTE: This point should never be on a face, always inside a cell, even
|
||||
// after refinement.
|
||||
locationInMesh (5 0.28 0.43);
|
||||
//
|
||||
// There are two different ways of specifying the regions to keep:
|
||||
// 1. a single locationInMesh. All the 'zoned' surfaces are marked as such
|
||||
// in the refinementSurfaces with the faceZone and cellZone keywords.
|
||||
//
|
||||
// or
|
||||
//
|
||||
// 2. multiple locationsInMesh, with per location the name of the cellZone.
|
||||
// This uses walking to determine zones and automatically creates
|
||||
// faceZones on the outside of cellZones.
|
||||
|
||||
// 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 true;
|
||||
|
||||
// Ad 1. Specify a single location and how to treat faces inbetween
|
||||
// cellZones
|
||||
locationInMesh (5 0.28 0.43);
|
||||
|
||||
// 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 true;
|
||||
|
||||
|
||||
|
||||
// 2. Specify multiple locations with optional cellZones for the
|
||||
// regions. faceZones are automatically constructed from the
|
||||
// names of the cellZones: <cellZoneA> _to_ <cellZoneB>
|
||||
// where the cellZoneA is the lowest numbered cellZone (non-cellZone
|
||||
// cells are in a special region called "none" which is always
|
||||
// last).
|
||||
|
||||
locationsInMesh
|
||||
(
|
||||
((-0.09 -0.039 -0.049) bottomAir) // cellZone 0
|
||||
((-0.09 0.009 -0.049) topAir) // cellZone 1
|
||||
((-0.09 0.001 -0.049) leftSolid) // cellZone 2
|
||||
((0.02 0.001 -0.049) rightSolid) // cellZone 3
|
||||
((-0.001 -0.039 0.0015) heater) // cellZone 4
|
||||
);
|
||||
|
||||
// Per synthesised faceZone name the faceType and type of baffles to
|
||||
// create
|
||||
faceZoneControls
|
||||
{
|
||||
bottomAir_to_heater
|
||||
{
|
||||
// Optional specification of patch type (default is wall). No
|
||||
// constraint types (cyclic, symmetry) etc. are allowed.
|
||||
patchInfo
|
||||
{
|
||||
type patch;
|
||||
inGroups (patchPatches);
|
||||
}
|
||||
faceType baffle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Optional locations that should not be reachable from
|
||||
// location(s)InMesh
|
||||
locationsOutsideMesh ((100 100 100));
|
||||
|
||||
// Optional: do not remove cells likely to give snapping problems
|
||||
// handleSnapProblems false;
|
||||
@ -266,6 +325,10 @@ castellatedMeshControls
|
||||
// Optional: switch off topological test for cells to-be-squashed
|
||||
// and use geometric test instead
|
||||
//useTopologicalSnapDetection false;
|
||||
|
||||
// Optional: do not refine surface cells with opposite faces of
|
||||
// differing refinement levels
|
||||
//interfaceRefine false;
|
||||
}
|
||||
|
||||
// Settings for the snapping.
|
||||
@ -275,6 +338,11 @@ snapControls
|
||||
// to surface
|
||||
nSmoothPatch 3;
|
||||
|
||||
// Optional: number of smoothing iterations for internal points on
|
||||
// refinement interfaces. This will reduce non-orthogonality on
|
||||
// refinement interfaces.
|
||||
//nSmoothInternal $nSmoothPatch;
|
||||
|
||||
// Maximum relative distance for points to be attracted by surface.
|
||||
// True distance is this factor times local maximum edge length.
|
||||
// Note: changed(corrected) w.r.t 17x! (17x used 2* tolerance)
|
||||
@ -287,6 +355,11 @@ snapControls
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
// (wip) disable snapping to opposite near surfaces (revert to 22x
|
||||
// behaviour)
|
||||
// detectNearSurfacesSnap false;
|
||||
|
||||
|
||||
// Feature snapping
|
||||
|
||||
// Number of feature edge snapping iterations.
|
||||
@ -305,8 +378,28 @@ snapControls
|
||||
multiRegionFeatureSnap false;
|
||||
|
||||
|
||||
// wip: disable snapping to opposite near surfaces (revert to 22x behaviour)
|
||||
// detectNearSurfacesSnap false;
|
||||
//- When to run face splitting (never at first iteration, always
|
||||
// at last iteration). Is interval. Default -1 (disabled)
|
||||
//nFaceSplitInterval 5;
|
||||
|
||||
|
||||
// (wip) Optional for explicit feature snapping:
|
||||
//- Detect baffle edges. Default is true.
|
||||
//detectBaffles false;
|
||||
//- Erase attraction close to feature point. Default is false.
|
||||
//releasePoints true;
|
||||
//- Walk along feature edges, adding missing ones. Default is true.
|
||||
//stringFeatures false;
|
||||
//- If diagonal attraction also attract other face points. Default is
|
||||
// false
|
||||
//avoidDiagonal true;
|
||||
//- When splitting what concave faces to leave intact. Default is 45
|
||||
// degrees.
|
||||
//concaveAngle 30;
|
||||
//- When splitting the minimum area ratio of faces. If face split
|
||||
// causes ratio of area less than this do not split. Default is 0.3
|
||||
//minAreaRatio 0.3;
|
||||
|
||||
}
|
||||
|
||||
// Settings for the layer addition.
|
||||
@ -350,10 +443,10 @@ addLayersControls
|
||||
// cannot be above minThickness do not add layer.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer..
|
||||
minThickness 0.25;
|
||||
minThickness 0.1;
|
||||
|
||||
|
||||
// Per final patch (so not geometry!) the layer information
|
||||
// Per final patch or faceZone (so not geometry!) the layer information
|
||||
// Note: This behaviour changed after 21x. Any non-mentioned patches
|
||||
// now slide unless:
|
||||
// - nSurfaceLayers is explicitly mentioned to be 0.
|
||||
@ -397,6 +490,10 @@ addLayersControls
|
||||
// are perpendicular
|
||||
featureAngle 130;
|
||||
|
||||
// When to merge patch faces. Default is featureAngle. Useful when
|
||||
// featureAngle is large.
|
||||
//mergePatchFacesAngle 45;
|
||||
|
||||
// Stop layer growth on highly warped cells
|
||||
maxFaceThicknessRatio 0.5;
|
||||
|
||||
@ -433,8 +530,10 @@ addLayersControls
|
||||
// default is 0.
|
||||
//nSmoothDisplacement 90;
|
||||
|
||||
// (wip)Optional: do not extrude a point if none of the surrounding points is
|
||||
// not extruded. Default is false.
|
||||
// (wip)Optional: do not extrude any point where
|
||||
// (false) : all surrounding faces are not fully extruded
|
||||
// (true) : all surrounding points are not extruded
|
||||
// Default is false.
|
||||
//detectExtrusionIsland true;
|
||||
|
||||
|
||||
@ -449,7 +548,8 @@ addLayersControls
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
// Create buffer region for new layer terminations
|
||||
// Create buffer region for new layer terminations, i.e. gradually
|
||||
// step down number of layers. Set to <0 to terminate layer in one go.
|
||||
nBufferCellsNoExtrude 0;
|
||||
|
||||
// Overall max number of layer addition iterations. The mesher will
|
||||
|
||||
Reference in New Issue
Block a user