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:
mattijs
2015-10-14 14:49:37 +01:00
committed by Andrew Heather
parent c83c99b30e
commit 7b7967de76
46 changed files with 9814 additions and 4346 deletions

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.
@ -493,21 +493,30 @@ int main(int argc, char *argv[])
// new patchID to neighbour processor) // new patchID to neighbour processor)
// - number of new patches (nPatches) // - number of new patches (nPatches)
labelList sidePatchID; labelList edgePatchID;
labelList edgeZoneID;
boolList edgeFlip;
labelList inflateFaceID;
label nPatches; label nPatches;
Map<label> nbrProcToPatch; Map<label> nbrProcToPatch;
Map<label> patchToNbrProc; Map<label> patchToNbrProc;
addPatchCellLayer::calcSidePatch addPatchCellLayer::calcExtrudeInfo
( (
true, // for internal edges get zone info from any face
mesh, mesh,
globalFaces, globalFaces,
edgeGlobalFaces, edgeGlobalFaces,
extrudePatch, extrudePatch,
sidePatchID, edgePatchID,
nPatches, nPatches,
nbrProcToPatch, nbrProcToPatch,
patchToNbrProc patchToNbrProc,
edgeZoneID,
edgeFlip,
inflateFaceID
); );
@ -659,7 +668,12 @@ int main(int argc, char *argv[])
ratio, // expansion ratio ratio, // expansion ratio
extrudePatch, // patch faces to extrude 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 exposedPatchID, // if new mesh: patches for exposed faces
nFaceLayers, nFaceLayers,
nPointLayers, nPointLayers,

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.
@ -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 // Add all the surface regions as patches
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1128,6 +1160,8 @@ int main(int argc, char *argv[])
// (faceZone surfaces) // (faceZone surfaces)
labelList globalToMasterPatch; labelList globalToMasterPatch;
labelList globalToSlavePatch; labelList globalToSlavePatch;
{ {
Info<< nl Info<< nl
<< "Adding patches for surface regions" << nl << "Adding patches for surface regions" << nl
@ -1148,6 +1182,7 @@ int main(int argc, char *argv[])
const labelList& surfaceGeometry = surfaces.surfaces(); const labelList& surfaceGeometry = surfaces.surfaces();
const PtrList<dictionary>& surfacePatchInfo = surfaces.patchInfo(); const PtrList<dictionary>& surfacePatchInfo = surfaces.patchInfo();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(surfaceGeometry, surfI) forAll(surfaceGeometry, surfI)
{ {
@ -1157,7 +1192,9 @@ int main(int argc, char *argv[])
Info<< surfaces.names()[surfI] << ':' << nl << nl; Info<< surfaces.names()[surfI] << ':' << nl << nl;
if (surfaces.surfZones()[surfI].faceZoneName().empty()) const word& fzName = surfaces.surfZones()[surfI].faceZoneName();
if (fzName.empty())
{ {
// 'Normal' surface // 'Normal' surface
forAll(regNames, i) forAll(regNames, i)
@ -1188,7 +1225,7 @@ int main(int argc, char *argv[])
Info<< setf(ios_base::left) Info<< setf(ios_base::left)
<< setw(6) << patchI << setw(6) << patchI
<< setw(20) << mesh.boundaryMesh()[patchI].type() << setw(20) << pbm[patchI].type()
<< setw(30) << regNames[i] << nl; << setw(30) << regNames[i] << nl;
globalToMasterPatch[globalRegionI] = patchI; globalToMasterPatch[globalRegionI] = patchI;
@ -1228,7 +1265,7 @@ int main(int argc, char *argv[])
Info<< setf(ios_base::left) Info<< setf(ios_base::left)
<< setw(6) << patchI << setw(6) << patchI
<< setw(20) << mesh.boundaryMesh()[patchI].type() << setw(20) << pbm[patchI].type()
<< setw(30) << regNames[i] << nl; << setw(30) << regNames[i] << nl;
globalToMasterPatch[globalRegionI] = patchI; globalToMasterPatch[globalRegionI] = patchI;
@ -1260,12 +1297,27 @@ int main(int argc, char *argv[])
Info<< setf(ios_base::left) Info<< setf(ios_base::left)
<< setw(6) << patchI << setw(6) << patchI
<< setw(20) << mesh.boundaryMesh()[patchI].type() << setw(20) << pbm[patchI].type()
<< setw(30) << slaveName << nl; << setw(30) << slaveName << nl;
globalToSlavePatch[globalRegionI] = patchI; 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; 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 // Parallel
// ~~~~~~~~ // ~~~~~~~~
// Decomposition // Construct decomposition engine. Note: cannot use decompositionModel
// MeshObject since we're clearing out the mesh inside the mesh generation.
autoPtr<decompositionMethod> decomposerPtr autoPtr<decompositionMethod> decomposerPtr
( (
decompositionMethod::New decompositionMethod::New
@ -1312,14 +1439,17 @@ int main(int argc, char *argv[])
const Switch wantSnap(meshDict.lookup("snap")); const Switch wantSnap(meshDict.lookup("snap"));
const Switch wantLayers(meshDict.lookup("addLayers")); const Switch wantLayers(meshDict.lookup("addLayers"));
// Refinement parameters const Switch mergePatchFaces
const refinementParameters refineParams(refineDict); (
meshDict.lookupOrDefault("mergePatchFaces", true)
);
// Snap parameters if (!mergePatchFaces)
const snapParameters snapParams(snapDict); {
Info<< "Not merging patch-faces of cell to preserve"
// Layer addition parameters << " (split)hex cell shape."
const layerParameters layerParams(layerDict, mesh.boundaryMesh()); << nl << endl;
}
if (wantRefine) if (wantRefine)
@ -1348,6 +1478,7 @@ int main(int argc, char *argv[])
refineParams, refineParams,
snapParams, snapParams,
refineParams.handleSnapProblems(), refineParams.handleSnapProblems(),
mergePatchFaces, // merge co-planar faces
motionDict motionDict
); );
@ -1387,6 +1518,7 @@ int main(int argc, char *argv[])
( (
snapDict, snapDict,
motionDict, motionDict,
mergePatchFaces,
curvature, curvature,
planarAngle, planarAngle,
snapParams snapParams
@ -1408,6 +1540,9 @@ int main(int argc, char *argv[])
{ {
cpuTime timer; cpuTime timer;
// Layer addition parameters
const layerParameters layerParams(layerDict, mesh.boundaryMesh());
autoLayerDriver layerDriver autoLayerDriver layerDriver
( (
meshRefiner, meshRefiner,
@ -1433,6 +1568,7 @@ int main(int argc, char *argv[])
layerDict, layerDict,
motionDict, motionDict,
layerParams, layerParams,
mergePatchFaces,
preBalance, preBalance,
decomposer, decomposer,
distributor distributor

View File

@ -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. // Settings for the castellatedMesh generation.
castellatedMeshControls castellatedMeshControls
{ {
@ -177,7 +182,7 @@ castellatedMeshControls
// how to select the cells that are in the cellZone // how to select the cells that are in the cellZone
// (inside / outside / specified insidePoint) // (inside / outside / specified insidePoint)
// The orientation of the faceZone is // 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 // - if freestanding : oriented according to surface
//faceZone sphere; //faceZone sphere;
@ -249,9 +254,23 @@ castellatedMeshControls
// After refinement patches get added for all refinementSurfaces and // After refinement patches get added for all refinementSurfaces and
// all cells intersecting the surfaces get put into these patches. The // 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 // NOTE: This point should never be on a face, always inside a cell, even
// after refinement. // after refinement.
//
// 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.
// Ad 1. Specify a single location and how to treat faces inbetween
// cellZones
locationInMesh (5 0.28 0.43); locationInMesh (5 0.28 0.43);
// Whether any faceZones (as specified in the refinementSurfaces) // Whether any faceZones (as specified in the refinementSurfaces)
@ -260,12 +279,56 @@ castellatedMeshControls
allowFreeStandingZoneFaces true; 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 // Optional: do not remove cells likely to give snapping problems
// handleSnapProblems false; // handleSnapProblems false;
// Optional: switch off topological test for cells to-be-squashed // Optional: switch off topological test for cells to-be-squashed
// and use geometric test instead // and use geometric test instead
//useTopologicalSnapDetection false; //useTopologicalSnapDetection false;
// Optional: do not refine surface cells with opposite faces of
// differing refinement levels
//interfaceRefine false;
} }
// Settings for the snapping. // Settings for the snapping.
@ -275,6 +338,11 @@ snapControls
// to surface // to surface
nSmoothPatch 3; 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. // Maximum relative distance for points to be attracted by surface.
// True distance is this factor times local maximum edge length. // True distance is this factor times local maximum edge length.
// Note: changed(corrected) w.r.t 17x! (17x used 2* tolerance) // Note: changed(corrected) w.r.t 17x! (17x used 2* tolerance)
@ -287,6 +355,11 @@ snapControls
// before upon reaching a correct mesh. // before upon reaching a correct mesh.
nRelaxIter 5; nRelaxIter 5;
// (wip) disable snapping to opposite near surfaces (revert to 22x
// behaviour)
// detectNearSurfacesSnap false;
// Feature snapping // Feature snapping
// Number of feature edge snapping iterations. // Number of feature edge snapping iterations.
@ -305,8 +378,28 @@ snapControls
multiRegionFeatureSnap false; multiRegionFeatureSnap false;
// wip: disable snapping to opposite near surfaces (revert to 22x behaviour) //- When to run face splitting (never at first iteration, always
// detectNearSurfacesSnap false; // 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. // Settings for the layer addition.
@ -350,10 +443,10 @@ addLayersControls
// cannot be above minThickness do not add layer. // cannot be above minThickness do not add layer.
// If relativeSizes this is relative to undistorted size of cell // If relativeSizes this is relative to undistorted size of cell
// outside layer.. // 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 // Note: This behaviour changed after 21x. Any non-mentioned patches
// now slide unless: // now slide unless:
// - nSurfaceLayers is explicitly mentioned to be 0. // - nSurfaceLayers is explicitly mentioned to be 0.
@ -397,6 +490,10 @@ addLayersControls
// are perpendicular // are perpendicular
featureAngle 130; featureAngle 130;
// When to merge patch faces. Default is featureAngle. Useful when
// featureAngle is large.
//mergePatchFacesAngle 45;
// Stop layer growth on highly warped cells // Stop layer growth on highly warped cells
maxFaceThicknessRatio 0.5; maxFaceThicknessRatio 0.5;
@ -433,8 +530,10 @@ addLayersControls
// default is 0. // default is 0.
//nSmoothDisplacement 90; //nSmoothDisplacement 90;
// (wip)Optional: do not extrude a point if none of the surrounding points is // (wip)Optional: do not extrude any point where
// not extruded. Default is false. // (false) : all surrounding faces are not fully extruded
// (true) : all surrounding points are not extruded
// Default is false.
//detectExtrusionIsland true; //detectExtrusionIsland true;
@ -449,7 +548,8 @@ addLayersControls
// before upon reaching a correct mesh. // before upon reaching a correct mesh.
nRelaxIter 5; 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; nBufferCellsNoExtrude 0;
// Overall max number of layer addition iterations. The mesher will // Overall max number of layer addition iterations. The mesher will

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-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.
@ -34,6 +34,8 @@ License
#include "polyModifyFace.H" #include "polyModifyFace.H"
#include "polyAddCell.H" #include "polyAddCell.H"
#include "globalIndex.H" #include "globalIndex.H"
#include "PatchTools.H"
#include "dummyTransform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -221,13 +223,15 @@ Foam::labelPair Foam::addPatchCellLayer::getEdgeString
} }
// Adds a side face i.e. extrudes a patch edge.
Foam::label Foam::addPatchCellLayer::addSideFace Foam::label Foam::addPatchCellLayer::addSideFace
( (
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelListList& addedCells, // per pp face the new extruded cell const labelListList& addedCells, // per pp face the new extruded cell
const face& newFace, const face& newFace,
const label newPatchID, const label newPatchID,
const label zoneI,
const bool edgeFlip,
const label inflateFaceI,
const label ownFaceI, // pp face that provides owner const label ownFaceI, // pp face that provides owner
const label nbrFaceI, const label nbrFaceI,
@ -238,68 +242,14 @@ Foam::label Foam::addPatchCellLayer::addSideFace
polyTopoChange& meshMod polyTopoChange& meshMod
) const ) const
{ {
// Face or edge to 'inflate' from
label inflateEdgeI = -1;
label inflateFaceI = -1;
// Check mesh faces using edge
if (addToMesh_)
{
forAll(meshFaces, i)
{
if (mesh_.isInternalFace(meshFaces[i]))
{
// meshEdge uses internal faces so ok to inflate from it
inflateEdgeI = meshEdgeI;
break;
}
}
}
// Zone info comes from any side patch face. Otherwise -1 since we
// don't know what to put it in - inherit from the extruded faces?
label zoneI = -1; //mesh_.faceZones().whichZone(meshFaceI);
bool flip = false;
label addedFaceI = -1; label addedFaceI = -1;
// Is patch edge external edge of indirectPrimitivePatch? // Is patch edge external edge of indirectPrimitivePatch?
if (nbrFaceI == -1) if (nbrFaceI == -1)
{ {
// External edge so external face. // External edge so external face.
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Loop over all faces connected to edge to inflate and
// see if we can find a face that is otherPatchID
// Get my mesh face and its zone.
label meshFaceI = pp.addressing()[ownFaceI];
forAll(meshFaces, k)
{
label faceI = meshFaces[k];
if
(
(faceI != meshFaceI)
&& (patches.whichPatch(faceI) == newPatchID)
)
{
// Found the patch face. Use it to inflate from
inflateEdgeI = -1;
inflateFaceI = faceI;
zoneI = mesh_.faceZones().whichZone(faceI);
if (zoneI != -1)
{
label index = mesh_.faceZones()[zoneI].whichFace(faceI);
flip = mesh_.faceZones()[zoneI].flipMap()[index];
}
break;
}
}
// Determine if different number of layer on owner and neighbour side // Determine if different number of layer on owner and neighbour side
// (relevant only for coupled faces). See section for internal edge // (relevant only for coupled faces). See section for internal edge
// below. // below.
@ -337,12 +287,12 @@ Foam::label Foam::addPatchCellLayer::addSideFace
addedCells[ownFaceI][layerOwn], // owner addedCells[ownFaceI][layerOwn], // owner
-1, // neighbour -1, // neighbour
-1, // master point -1, // master point
inflateEdgeI, // master edge -1, // master edge
inflateFaceI, // master face inflateFaceI, // master face
false, // flux flip false, // flux flip
newPatchID, // patch for face newPatchID, // patch for face
zoneI, // zone for face zoneI, // zone for face
flip // face zone flip edgeFlip // face zone flip
) )
); );
} }
@ -395,6 +345,23 @@ Foam::label Foam::addPatchCellLayer::addSideFace
layerOwn = layerI; layerOwn = layerI;
} }
// Check mesh internal faces using edge to initialise
label inflateEdgeI = -1;
if (addToMesh_)
{
forAll(meshFaces, i)
{
if (mesh_.isInternalFace(meshFaces[i]))
{
// meshEdge uses internal faces so ok to inflate from it
inflateEdgeI = meshEdgeI;
break;
}
}
}
addedFaceI = meshMod.setAction addedFaceI = meshMod.setAction
( (
polyAddFace polyAddFace
@ -408,7 +375,7 @@ Foam::label Foam::addPatchCellLayer::addSideFace
false, // flux flip false, // flux flip
-1, // patch for face -1, // patch for face
zoneI, // zone for face zoneI, // zone for face
flip // face zone flip edgeFlip // face zone flip
) )
); );
@ -467,6 +434,134 @@ void Foam::addPatchCellLayer::setFaceProps
} }
void Foam::addPatchCellLayer::setFaceProps
(
const polyMesh& mesh,
const indirectPrimitivePatch& pp,
const label ppEdgeI,
const label faceI,
label& patchI,
label& zoneI,
bool& zoneFlip,
label& inflateFaceI
)
{
setFaceProps
(
mesh,
faceI,
patchI,
zoneI,
zoneFlip
);
if (patchI != -1 || zoneI != -1)
{
inflateFaceI = faceI;
}
if (zoneI != -1)
{
// Correct flip for patch edge ordering
const edge& ppEdge = pp.edges()[ppEdgeI];
const edge patchEdge
(
pp.meshPoints()[ppEdge[0]],
pp.meshPoints()[ppEdge[1]]
);
const face& f = mesh.faces()[faceI];
bool found = false;
forAll(f, fp)
{
const edge e(f[fp], f.nextLabel(fp));
int stat = edge::compare(e, patchEdge);
if (stat == 1)
{
found = true;
break;
}
else if (stat == -1)
{
found = true;
zoneFlip = !zoneFlip;
break;
}
}
if (!found)
{
FatalErrorIn("addPatchCellLayer::setFaceProps(..)")
<< "Problem: cannot find patch edge " << ppEdgeI
<< " with mesh vertices " << patchEdge
<< " at " << patchEdge.line(mesh.points())
<< " is not in face " << faceI << " with mesh vertices "
<< f
<< exit(FatalError);
}
}
}
void Foam::addPatchCellLayer::findZoneFace
(
const bool useInternalFaces,
const bool useBoundaryFaces,
const polyMesh& mesh,
const indirectPrimitivePatch& pp,
const label ppEdgeI,
const UIndirectList<label>& excludeFaces,
const labelList& meshFaces,
label& inflateFaceI,
label& patchI,
label& zoneI,
bool& zoneFlip
)
{
inflateFaceI = -1;
patchI = -1;
zoneI = -1;
zoneFlip = false;
forAll(meshFaces, k)
{
label faceI = meshFaces[k];
if
(
(findIndex(excludeFaces, faceI) == -1)
&& (
(mesh.isInternalFace(faceI) && useInternalFaces)
|| (!mesh.isInternalFace(faceI) && useBoundaryFaces)
)
)
{
setFaceProps
(
mesh,
pp,
ppEdgeI,
faceI,
patchI,
zoneI,
zoneFlip,
inflateFaceI
);
if (zoneI != -1 || patchI != -1)
{
break;
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from mesh // Construct from mesh
@ -564,38 +659,61 @@ Foam::labelListList Foam::addPatchCellLayer::globalEdgeFaces
} }
void Foam::addPatchCellLayer::calcSidePatch void Foam::addPatchCellLayer::calcExtrudeInfo
( (
const bool zoneFromAnyFace,
const polyMesh& mesh, const polyMesh& mesh,
const globalIndex& globalFaces, const globalIndex& globalFaces,
const labelListList& globalEdgeFaces, const labelListList& globalEdgeFaces,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
labelList& sidePatchID, labelList& edgePatchID,
label& nPatches, label& nPatches,
Map<label>& nbrProcToPatch, Map<label>& nbrProcToPatch,
Map<label>& patchToNbrProc Map<label>& patchToNbrProc,
labelList& edgeZoneID,
boolList& edgeFlip,
labelList& inflateFaceID
) )
{ {
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
const globalMeshData& gd = mesh.globalData();
// Precalculate mesh edges for pp.edges. // Precalculate mesh edges for pp.edges.
const labelList meshEdges(pp.meshEdges(mesh.edges(), mesh.pointEdges())); const labelList meshEdges(pp.meshEdges(mesh.edges(), mesh.pointEdges()));
sidePatchID.setSize(pp.nEdges()); edgePatchID.setSize(pp.nEdges());
sidePatchID = -1; edgePatchID = -1;
edgeZoneID.setSize(pp.nEdges());
edgeZoneID = -1;
edgeFlip.setSize(pp.nEdges());
edgeFlip = false;
// Determine properties for faces extruded from edges
// - edge inbetween two different processors:
// - extrude as patch face on correct processor
// - edge at end of patch (so edgeFaces.size() == 1):
// - use mesh face that is a boundary face
// - edge internal to patch (so edgeFaces.size() == 2):
// These also get determined but not (yet) exported: // These also get determined but not (yet) exported:
// - whether face is created from other face or edge // - whether face is created from other face or edge
// - what zone&orientation face should have
labelList inflateEdgeI(pp.nEdges(), -1); inflateFaceID.setSize(pp.nEdges(), -1);
labelList inflateFaceI(pp.nEdges(), -1);
labelList sideZoneID(pp.nEdges(), -1);
boolList sideFlip(pp.nEdges(), false);
nPatches = patches.size(); nPatches = patches.size();
// Pass1:
// For all edges inbetween two processors: see if matches to existing
// processor patch or create interprocessor-patch if necessary.
// Sets edgePatchID[edgeI] but none of the other quantities
forAll(globalEdgeFaces, edgeI) forAll(globalEdgeFaces, edgeI)
{ {
const labelList& eGlobalFaces = globalEdgeFaces[edgeI]; const labelList& eGlobalFaces = globalEdgeFaces[edgeI];
@ -606,8 +724,7 @@ void Foam::addPatchCellLayer::calcSidePatch
) )
{ {
// Locally but not globally a boundary edge. Hence a coupled // Locally but not globally a boundary edge. Hence a coupled
// edge. Find the patch to use if on different // edge. Find the patch to use if on different processors.
// processors.
label f0 = eGlobalFaces[0]; label f0 = eGlobalFaces[0];
label f1 = eGlobalFaces[1]; label f1 = eGlobalFaces[1];
@ -625,18 +742,25 @@ void Foam::addPatchCellLayer::calcSidePatch
if (otherProcI != -1) if (otherProcI != -1)
{ {
sidePatchID[edgeI] = findProcPatch(mesh, otherProcI); if (findIndex(gd[Pstream::myProcNo()], otherProcI) != -1)
if (sidePatchID[edgeI] == -1) {
// There is already a processorPolyPatch to otherProcI.
// Use it. Note that we can only index procPatchMap
// if the processor actually is a neighbour processor
// so that is why we first check.
edgePatchID[edgeI] = gd.procPatchMap()[otherProcI];
}
else
{ {
// Cannot find a patch to processor. See if already // Cannot find a patch to processor. See if already
// marked for addition // marked for addition
if (nbrProcToPatch.found(otherProcI)) if (nbrProcToPatch.found(otherProcI))
{ {
sidePatchID[edgeI] = nbrProcToPatch[otherProcI]; edgePatchID[edgeI] = nbrProcToPatch[otherProcI];
} }
else else
{ {
sidePatchID[edgeI] = nPatches; edgePatchID[edgeI] = nPatches;
nbrProcToPatch.insert(otherProcI, nPatches); nbrProcToPatch.insert(otherProcI, nPatches);
patchToNbrProc.insert(nPatches, otherProcI); patchToNbrProc.insert(nPatches, otherProcI);
nPatches++; nPatches++;
@ -647,9 +771,8 @@ void Foam::addPatchCellLayer::calcSidePatch
} }
// Pass2: determine face properties for all other edges
// Determine face properties for all other boundary edges // ----------------------------------------------------
// ------------------------------------------------------
const labelListList& edgeFaces = pp.edgeFaces(); const labelListList& edgeFaces = pp.edgeFaces();
@ -657,13 +780,10 @@ void Foam::addPatchCellLayer::calcSidePatch
forAll(edgeFaces, edgeI) forAll(edgeFaces, edgeI)
{ {
if (edgeFaces[edgeI].size() == 1 && sidePatchID[edgeI] == -1) if (edgePatchID[edgeI] == -1)
{ {
// Proper, uncoupled patch edge. UIndirectList<label> ppFaces(pp.addressing(), edgeFaces[edgeI]);
label myFaceI = pp.addressing()[edgeFaces[edgeI][0]];
// Pick up any boundary face on this edge and use its properties
label meshEdgeI = meshEdges[edgeI]; label meshEdgeI = meshEdges[edgeI];
const labelList& meshFaces = mesh.edgeFaces const labelList& meshFaces = mesh.edgeFaces
( (
@ -671,43 +791,71 @@ void Foam::addPatchCellLayer::calcSidePatch
dynMeshEdgeFaces dynMeshEdgeFaces
); );
forAll(meshFaces, k) if (edgeFaces[edgeI].size() == 2)
{ {
label faceI = meshFaces[k]; // Internal edge. Look at any face (internal or boundary) to
// determine extrusion properties. First one that has zone
// info wins
if (faceI != myFaceI && !mesh.isInternalFace(faceI)) label dummyPatchI = -1;
{ findZoneFace
setFaceProps
( (
true, // useInternalFaces,
zoneFromAnyFace, // useBoundaryFaces,
mesh, mesh,
faceI, pp,
edgeI,
sidePatchID[edgeI],
sideZoneID[edgeI], ppFaces, // excludeFaces,
sideFlip[edgeI] meshFaces, // meshFaces,
inflateFaceID[edgeI],
dummyPatchI, // do not use patch info
edgeZoneID[edgeI],
edgeFlip[edgeI]
); );
inflateFaceI[edgeI] = faceI;
inflateEdgeI[edgeI] = -1;
break;
} }
else
{
// Proper, uncoupled patch edge
findZoneFace
(
false, // useInternalFaces,
true, // useBoundaryFaces,
mesh,
pp,
edgeI,
ppFaces, // excludeFaces,
meshFaces, // meshFaces,
inflateFaceID[edgeI],
edgePatchID[edgeI],
edgeZoneID[edgeI],
edgeFlip[edgeI]
);
} }
} }
} }
// Now hopefully every boundary edge has a side patch. Check // Now hopefully every boundary edge has a edge patch. Check
if (debug) if (debug)
{ {
forAll(edgeFaces, edgeI) forAll(edgeFaces, edgeI)
{ {
if (edgeFaces[edgeI].size() == 1 && sidePatchID[edgeI] == -1) if (edgeFaces[edgeI].size() == 1 && edgePatchID[edgeI] == -1)
{ {
const edge& e = pp.edges()[edgeI]; const edge& e = pp.edges()[edgeI];
//FatalErrorIn("addPatchCellLayer::calcSidePatch(..)") //FatalErrorIn("addPatchCellLayer::calcExtrudeInfo(..)")
WarningIn("addPatchCellLayer::calcSidePatch(..)") WarningIn("addPatchCellLayer::calcExtrudeInfo(..)")
<< "Have no sidePatchID for edge " << edgeI << " points " << "Have no edgePatchID for edge " << edgeI << " points "
<< pp.points()[pp.meshPoints()[e[0]]] << pp.points()[pp.meshPoints()[e[0]]]
<< pp.points()[pp.meshPoints()[e[1]]] << pp.points()[pp.meshPoints()[e[1]]]
//<< abort(FatalError); //<< abort(FatalError);
@ -718,15 +866,15 @@ void Foam::addPatchCellLayer::calcSidePatch
// Now we have sidepatch see if we have patchface or edge to inflate // Pass3: for any faces set in pass1 see if we can find a processor face
// from. // to inherit from (we only have a patch, not a patch face)
forAll(edgeFaces, edgeI) forAll(edgeFaces, edgeI)
{ {
if if
( (
edgeFaces[edgeI].size() == 1 edgeFaces[edgeI].size() == 1
&& sidePatchID[edgeI] != -1 && edgePatchID[edgeI] != -1
&& inflateFaceI[edgeI] == -1 && inflateFaceID[edgeI] == -1
) )
{ {
// 1. Do we have a boundary face to inflate from // 1. Do we have a boundary face to inflate from
@ -745,34 +893,115 @@ void Foam::addPatchCellLayer::calcSidePatch
{ {
label faceI = meshFaces[k]; label faceI = meshFaces[k];
if (faceI != myFaceI) if (faceI != myFaceI && !mesh.isInternalFace(faceI))
{ {
if (mesh.isInternalFace(faceI)) if (patches.whichPatch(faceI) == edgePatchID[edgeI])
{
inflateEdgeI[edgeI] = meshEdgeI;
}
else
{
if (patches.whichPatch(faceI) == sidePatchID[edgeI])
{ {
setFaceProps setFaceProps
( (
mesh, mesh,
pp,
edgeI,
faceI, faceI,
sidePatchID[edgeI], edgePatchID[edgeI],
sideZoneID[edgeI], edgeZoneID[edgeI],
sideFlip[edgeI] edgeFlip[edgeI],
inflateFaceID[edgeI]
); );
inflateFaceI[edgeI] = faceI;
inflateEdgeI[edgeI] = -1;
break; break;
} }
} }
} }
} }
} }
// Sync all data:
// - edgePatchID : might be local in case of processor patch. Do not
// sync for now
// - inflateFaceID: local. Do not sync
// - edgeZoneID : global. sync.
// - edgeFlip : global. sync.
if (Pstream::parRun())
{
const globalMeshData& gd = mesh.globalData();
const indirectPrimitivePatch& cpp = gd.coupledPatch();
labelList patchEdges;
labelList coupledEdges;
PackedBoolList sameEdgeOrientation;
PatchTools::matchEdges
(
pp,
cpp,
patchEdges,
coupledEdges,
sameEdgeOrientation
);
// Convert data on pp edges to data on coupled patch
labelList cppEdgeZoneID(cpp.nEdges(), -1);
boolList cppEdgeFlip(cpp.nEdges(), false);
forAll(coupledEdges, i)
{
label cppEdgeI = coupledEdges[i];
label ppEdgeI = patchEdges[i];
cppEdgeZoneID[cppEdgeI] = edgeZoneID[ppEdgeI];
if (sameEdgeOrientation[i])
{
cppEdgeFlip[cppEdgeI] = edgeFlip[ppEdgeI];
}
else
{
cppEdgeFlip[cppEdgeI] = !edgeFlip[ppEdgeI];
}
}
// Sync
const globalIndexAndTransform& git = gd.globalTransforms();
const mapDistribute& edgeMap = gd.globalEdgeSlavesMap();
globalMeshData::syncData
(
cppEdgeZoneID,
gd.globalEdgeSlaves(),
gd.globalEdgeTransformedSlaves(),
edgeMap,
git,
maxEqOp<label>(),
dummyTransform()
);
globalMeshData::syncData
(
cppEdgeFlip,
gd.globalEdgeSlaves(),
gd.globalEdgeTransformedSlaves(),
edgeMap,
git,
andEqOp<bool>(),
dummyTransform()
);
// Convert data on coupled edges to pp edges
forAll(coupledEdges, i)
{
label cppEdgeI = coupledEdges[i];
label ppEdgeI = patchEdges[i];
edgeZoneID[ppEdgeI] = cppEdgeZoneID[cppEdgeI];
if (sameEdgeOrientation[i])
{
edgeFlip[ppEdgeI] = cppEdgeFlip[cppEdgeI];
}
else
{
edgeFlip[ppEdgeI] = !cppEdgeFlip[cppEdgeI];
}
}
} }
} }
@ -783,7 +1012,12 @@ void Foam::addPatchCellLayer::setRefinement
const labelListList& globalEdgeFaces, const labelListList& globalEdgeFaces,
const scalarField& expansionRatio, const scalarField& expansionRatio,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& sidePatchID,
const labelList& edgePatchID,
const labelList& edgeZoneID,
const boolList& edgeFlip,
const labelList& inflateFaceID,
const labelList& exposedPatchID, const labelList& exposedPatchID,
const labelList& nFaceLayers, const labelList& nFaceLayers,
const labelList& nPointLayers, const labelList& nPointLayers,
@ -865,7 +1099,10 @@ void Foam::addPatchCellLayer::setRefinement
<< e.line(pp.localPoints()) << e.line(pp.localPoints())
<< " which is non-manifold (has " << " which is non-manifold (has "
<< globalEdgeFaces[edgeI].size() << globalEdgeFaces[edgeI].size()
<< " faces using it)" << " local or coupled faces using it)"
<< " of which "
<< pp.edgeFaces()[edgeI].size()
<< " local"
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -1741,13 +1978,25 @@ void Foam::addPatchCellLayer::setRefinement
ef ef
); );
// Because we walk in order of patch face and in order
// of face edges so face orientation will be opposite
// that of the patch edge
bool zoneFlip = false;
if (edgeZoneID[startEdgeI] != -1)
{
zoneFlip = !edgeFlip[startEdgeI];
}
addSideFace addSideFace
( (
pp, pp,
addedCells, addedCells,
newFace, // vertices of new face newFace, // vertices of new face
sidePatchID[startEdgeI],// -1 or patch for face edgePatchID[startEdgeI],// -1 or patch for face
edgeZoneID[startEdgeI],
zoneFlip,
inflateFaceID[startEdgeI],
patchFaceI, patchFaceI,
nbrFaceI, nbrFaceI,

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.
@ -220,6 +220,9 @@ class addPatchCellLayer
const face& newFace, const face& newFace,
const label newPatchID, const label newPatchID,
const label newZoneI,
const bool newFlip,
const label inflateFaceI,
const label ownFaceI, const label ownFaceI,
const label nbrFaceI, const label nbrFaceI,
@ -243,6 +246,39 @@ class addPatchCellLayer
bool& bool&
); );
//- Extract properties from mesh face in pp edge ordering
static void setFaceProps
(
const polyMesh& mesh,
const indirectPrimitivePatch& pp,
const label ppEdgeI,
const label faceI,
label& patchI,
label& zoneI,
bool& zoneFlip,
label& inflateFaceI
);
//- Find internal or boundary face to get extrude properties
// from. zoneFlip consistent with ppEdge ordering
static void findZoneFace
(
const bool useInternalFaces,
const bool useBoundaryFaces,
const polyMesh& mesh,
const indirectPrimitivePatch& pp,
const label ppEdgeI,
const UIndirectList<label>& excludeFaces,
const labelList& meshFaces,
label& inflateFaceI,
label& patchI,
label& zoneI,
bool& zoneFlip
);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
addPatchCellLayer(const addPatchCellLayer&); addPatchCellLayer(const addPatchCellLayer&);
@ -303,22 +339,37 @@ public:
const indirectPrimitivePatch& pp const indirectPrimitivePatch& pp
); );
//- Boundary edges get extruded into boundary faces. Determine patch //- Determine extrude information per patch edge:
// for these faces. This might be a to-be-created processor patch // - zoneID, zoneFlip :
// picks one of the faces that connects to
// the edge. For boundary edge only looks
// at boundary faces. For internal edge it looks at internal
// faces only (zoneFromAnyFace = false) or at any face
// (zoneFromAnyFace = true). zoneFlip is consistent with
// ordering of pp edge.
// Face selected gets stored in inflateFaceID
// - patchID :
// get patch from any boundary face connected to the
// edge. The patch might be a to-be-created processor patch
// (patchI >= mesh.boundaryMesh().size()) in which case the // (patchI >= mesh.boundaryMesh().size()) in which case the
// nbrProcToPatch, patchToNbrProc give the correspondence. nPatches // nbrProcToPatch, patchToNbrProc give the correspondence.
// is the new number of patches. // nPatches is the new number of patches.
static void calcSidePatch static void calcExtrudeInfo
( (
const bool zoneFromAnyFace,
const polyMesh&, const polyMesh&,
const globalIndex& globalFaces, const globalIndex& globalFaces,
const labelListList& globalEdgeFaces, const labelListList& globalEdgeFaces,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
labelList& sidePatchID, labelList& edgePatchID, // if extruding a patch edge
label& nPatches, label& nPatches,
Map<label>& nbrProcToPatch, Map<label>& nbrProcToPatch,
Map<label>& patchToNbrProc Map<label>& patchToNbrProc,
labelList& edgeZoneID,
boolList& edgeFlip,
labelList& inflateFaceID
); );
//- Play commands into polyTopoChange to create layers on top //- Play commands into polyTopoChange to create layers on top
@ -347,7 +398,12 @@ public:
const labelListList& globalEdgeFaces, const labelListList& globalEdgeFaces,
const scalarField& expansionRatio, const scalarField& expansionRatio,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& sidePatchID, const labelList& sidePatchID,
const labelList& sideZoneID,
const boolList& sideFlip,
const labelList& inflateFaceID,
const labelList& exposedPatchID, const labelList& exposedPatchID,
const labelList& nFaceLayers, const labelList& nFaceLayers,
const labelList& nPointLayers, const labelList& nPointLayers,
@ -374,7 +430,12 @@ public:
globalEdgeFaces, globalEdgeFaces,
scalarField(pp.nPoints(), 1.0), // expansion ration scalarField(pp.nPoints(), 1.0), // expansion ration
pp, pp,
sidePatchID, sidePatchID,
labelList(pp.nEdges(), -1), // zoneID
boolList(pp.nEdges(), false), // zoneFlip
labelList(pp.nEdges(), -1), // inflateFaceID
labelList(0), labelList(0),
labelList(pp.size(), nLayers), // nFaceLayers labelList(pp.size(), nLayers), // nFaceLayers
labelList(pp.nPoints(), nLayers), // nPointLayers labelList(pp.nPoints(), nLayers), // nPointLayers

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.
@ -795,7 +795,7 @@ Foam::label Foam::hexRef8::findLevel
// Gets cell level such that the face has four points <= level. // Gets cell level such that the face has four points <= level.
Foam::label Foam::hexRef8::getAnchorLevel(const label faceI) const Foam::label Foam::hexRef8::faceLevel(const label faceI) const
{ {
const face& f = mesh_.faces()[faceI]; const face& f = mesh_.faces()[faceI];
@ -3519,7 +3519,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
for (label faceI = 0; faceI < mesh_.nFaces(); faceI++) for (label faceI = 0; faceI < mesh_.nFaces(); faceI++)
{ {
faceAnchorLevel[faceI] = getAnchorLevel(faceI); faceAnchorLevel[faceI] = faceLevel(faceI);
} }
// -1 : no need to split face // -1 : no need to split face

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.
@ -411,7 +411,7 @@ public:
// Refinement // Refinement
//- Gets level such that the face has four points <= level. //- Gets level such that the face has four points <= level.
label getAnchorLevel(const label faceI) const; label faceLevel(const label faceI) const;
//- Given valid mesh and current cell level and proposed //- Given valid mesh and current cell level and proposed
// cells to refine calculate any clashes (due to 2:1) and return // cells to refine calculate any clashes (due to 2:1) and return

View File

@ -2,7 +2,6 @@ autoHexMesh = autoHexMesh
autoHexMeshDriver = $(autoHexMesh)/autoHexMeshDriver autoHexMeshDriver = $(autoHexMesh)/autoHexMeshDriver
$(autoHexMeshDriver)/autoLayerDriver.C $(autoHexMeshDriver)/autoLayerDriver.C
/* $(autoHexMeshDriver)/autoLayerDriverShrink.C */
$(autoHexMeshDriver)/autoSnapDriver.C $(autoHexMeshDriver)/autoSnapDriver.C
$(autoHexMeshDriver)/autoSnapDriverFeature.C $(autoHexMeshDriver)/autoSnapDriverFeature.C
$(autoHexMeshDriver)/autoRefineDriver.C $(autoHexMeshDriver)/autoRefineDriver.C
@ -10,7 +9,6 @@ $(autoHexMeshDriver)/autoRefineDriver.C
$(autoHexMeshDriver)/layerParameters/layerParameters.C $(autoHexMeshDriver)/layerParameters/layerParameters.C
$(autoHexMeshDriver)/refinementParameters/refinementParameters.C $(autoHexMeshDriver)/refinementParameters/refinementParameters.C
$(autoHexMeshDriver)/snapParameters/snapParameters.C $(autoHexMeshDriver)/snapParameters/snapParameters.C
$(autoHexMeshDriver)/pointData/pointData.C
$(autoHexMesh)/meshRefinement/meshRefinementBaffles.C $(autoHexMesh)/meshRefinement/meshRefinementBaffles.C
$(autoHexMesh)/meshRefinement/meshRefinement.C $(autoHexMesh)/meshRefinement/meshRefinement.C
@ -30,7 +28,10 @@ meshMover = $(autoHexMesh)/externalDisplacementMeshMover
$(meshMover)/displacementMeshMoverMotionSolver.C $(meshMover)/displacementMeshMoverMotionSolver.C
$(meshMover)/externalDisplacementMeshMover.C $(meshMover)/externalDisplacementMeshMover.C
$(meshMover)/medialAxisMeshMover.C $(meshMover)/medialAxisMeshMover.C
$(meshMover)/displacementMotionSolverMeshMover.C
/* $(meshMover)/pointSmoothingMeshMover.C */
$(meshMover)/zeroFixedValue/zeroFixedValuePointPatchFields.C $(meshMover)/zeroFixedValue/zeroFixedValuePointPatchFields.C
$(meshMover)/fieldSmoother/fieldSmoother.C
LIB = $(FOAM_LIBBIN)/libautoMesh LIB = $(FOAM_LIBBIN)/libautoMesh

View File

@ -18,4 +18,5 @@ LIB_LIBS = \
-ledgeMesh \ -ledgeMesh \
-lsurfMesh \ -lsurfMesh \
-ltriSurface \ -ltriSurface \
-lfvMotionSolvers \
-ldistributed -ldistributed

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.
@ -47,7 +47,6 @@ class removePoints;
class pointSet; class pointSet;
class motionSmoother; class motionSmoother;
class addPatchCellLayer; class addPatchCellLayer;
class pointData;
class faceSet; class faceSet;
class layerParameters; class layerParameters;
@ -108,7 +107,6 @@ private:
const labelList globalToSlavePatch_; const labelList globalToSlavePatch_;
// Private Member Functions // Private Member Functions
// Layers // Layers
@ -231,14 +229,17 @@ private:
List<extrudeMode>& extrudeStatus List<extrudeMode>& extrudeStatus
) const; ) const;
//- See what patches boundaryedges should be extruded into //- See what zones and patches edges should be extruded into
void determineSidePatches void determineSidePatches
( (
const globalIndex& globalFaces, const globalIndex& globalFaces,
const labelListList& edgeGlobalFaces, const labelListList& edgeGlobalFaces,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
labelList& sidePatchID labelList& edgePatchID,
labelList& edgeZoneID,
boolList& edgeFlip,
labelList& inflateFaceID
); );
//- Calculate pointwise wanted and minimum thickness. //- Calculate pointwise wanted and minimum thickness.
@ -370,6 +371,14 @@ private:
const List<extrudeMode>& extrudeStatus const List<extrudeMode>& extrudeStatus
); );
//- After adding to mesh get the new baffles
static List<labelPair> getBafflesOnAddedMesh
(
const polyMesh& mesh,
const labelList& newToOldFaces,
const List<labelPair>& baffles
);
//- Collect layer faces and layer cells into bools //- Collect layer faces and layer cells into bools
// for ease of handling // for ease of handling
static void getLayerCellsFaces static void getLayerCellsFaces
@ -393,6 +402,15 @@ private:
) const; ) const;
//- Write cellSet,faceSet for layers //- Write cellSet,faceSet for layers
bool writeLayerSets
(
const fvMesh& mesh,
const labelList& cellNLayers,
const scalarField& faceRealThickness
) const;
//- Write volFields,cellSet,faceSet for layers depending
// on write level
bool writeLayerData bool writeLayerData
( (
const fvMesh& mesh, const fvMesh& mesh,
@ -464,13 +482,6 @@ private:
pointVectorField& normals pointVectorField& normals
) const; ) const;
bool isMaxEdge
(
const List<pointData>&,
const label edgeI,
const scalar minCos
) const;
//- Stop layer growth where mesh wraps around edge with a //- Stop layer growth where mesh wraps around edge with a
// large feature angle // large feature angle
void handleFeatureAngleLayerTerminations void handleFeatureAngleLayerTerminations
@ -595,6 +606,7 @@ public:
const dictionary& shrinkDict, const dictionary& shrinkDict,
const dictionary& motionDict, const dictionary& motionDict,
const layerParameters& layerParams, const layerParameters& layerParams,
const bool mergePatchFaces, // merging patch faces
const bool preBalance, // balance before adding? const bool preBalance, // balance before adding?
decompositionMethod& decomposer, decompositionMethod& decomposer,
fvMeshDistribute& distributor fvMeshDistribute& distributor

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-2014 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.
@ -37,6 +37,8 @@ License
#include "unitConversion.H" #include "unitConversion.H"
#include "snapParameters.H" #include "snapParameters.H"
#include "localPointRegion.H" #include "localPointRegion.H"
#include "IOmanip.H"
#include "labelVector.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -94,7 +96,7 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
( (
meshRefiner_.refineCandidates meshRefiner_.refineCandidates
( (
refineParams.keepPoints(), refineParams.locationsInMesh(),
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(), refineParams.planarAngle(),
@ -207,7 +209,7 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
( (
meshRefiner_.refineCandidates meshRefiner_.refineCandidates
( (
refineParams.keepPoints(), refineParams.locationsInMesh(),
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(), refineParams.planarAngle(),
@ -341,7 +343,7 @@ Foam::label Foam::autoRefineDriver::gapOnlyRefine
( (
meshRefiner_.refineCandidates meshRefiner_.refineCandidates
( (
refineParams.keepPoints(), refineParams.locationsInMesh(),
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(), refineParams.planarAngle(),
@ -669,6 +671,348 @@ Foam::label Foam::autoRefineDriver::danglingCellRefine
} }
// Detect cells with opposing intersected faces of differing refinement
// level and refine them.
Foam::label Foam::autoRefineDriver::refinementInterfaceRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter = 0;
if (refineParams.interfaceRefine())
{
for (;iter < maxIter; iter++)
{
Info<< nl
<< "Refinement transition refinement iteration " << iter << nl
<< "--------------------------------------------" << nl
<< endl;
const labelList& surfaceIndex = meshRefiner_.surfaceIndex();
const hexRef8& cutter = meshRefiner_.meshCutter();
const vectorField& fA = mesh.faceAreas();
const labelList& faceOwner = mesh.faceOwner();
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
const cellList& cells = mesh.cells();
labelList candidateCells;
{
// Pass1: pick up cells with differing face level
cellSet transitionCells
(
mesh,
"transitionCells",
cells.size()/100
);
forAll(cells, cellI)
{
const cell& cFaces = cells[cellI];
label cLevel = cutter.cellLevel()[cellI];
forAll(cFaces, cFaceI)
{
label faceI = cFaces[cFaceI];
if (surfaceIndex[faceI] != -1)
{
label fLevel = cutter.faceLevel(faceI);
if (fLevel != cLevel)
{
transitionCells.insert(cellI);
}
}
}
}
cellSet candidateCellSet
(
mesh,
"candidateCells",
cells.size()/1000
);
// Pass2: check for oppositeness
//forAllConstIter(cellSet, transitionCells, iter)
//{
// label cellI = iter.key();
// const cell& cFaces = cells[cellI];
// const point& cc = cellCentres[cellI];
// const scalar rCVol = pow(cellVolumes[cellI], -5.0/3.0);
//
// // Determine principal axes of cell
// symmTensor R(symmTensor::zero);
//
// forAll(cFaces, i)
// {
// label faceI = cFaces[i];
//
// const point& fc = faceCentres[faceI];
//
// // Calculate face-pyramid volume
// scalar pyrVol = 1.0/3.0 * fA[faceI] & (fc-cc);
//
// if (faceOwner[faceI] != cellI)
// {
// pyrVol = -pyrVol;
// }
//
// // Calculate face-pyramid centre
// vector pc = (3.0/4.0)*fc + (1.0/4.0)*cc;
//
// R += pyrVol*sqr(pc-cc)*rCVol;
// }
//
// //- MEJ: Problem: truncation errors cause complex evs
// vector lambdas(eigenValues(R));
// const tensor axes(eigenVectors(R, lambdas));
//
//
// // Check if this cell has
// // - opposing sides intersected
// // - which are of different refinement level
// // - plus the inbetween face
//
// labelVector plusFaceLevel(labelVector(-1, -1, -1));
// labelVector minFaceLevel(labelVector(-1, -1, -1));
//
// forAll(cFaces, cFaceI)
// {
// label faceI = cFaces[cFaceI];
//
// if (surfaceIndex[faceI] != -1)
// {
// label fLevel = cutter.faceLevel(faceI);
//
// // Get outwards pointing normal
// vector n = fA[faceI]/mag(fA[faceI]);
// if (faceOwner[faceI] != cellI)
// {
// n = -n;
// }
//
// // What is major direction and sign
// direction cmpt = vector::X;
// scalar maxComp = (n&axes.x());
//
// scalar yComp = (n&axes.y());
// scalar zComp = (n&axes.z());
//
// if (mag(yComp) > mag(maxComp))
// {
// maxComp = yComp;
// cmpt = vector::Y;
// }
//
// if (mag(zComp) > mag(maxComp))
// {
// maxComp = zComp;
// cmpt = vector::Z;
// }
//
// if (maxComp > 0)
// {
// plusFaceLevel[cmpt] = max
// (
// plusFaceLevel[cmpt],
// fLevel
// );
// }
// else
// {
// minFaceLevel[cmpt] = max
// (
// minFaceLevel[cmpt],
// fLevel
// );
// }
// }
// }
//
// // Check if we picked up any opposite differing level
// for (direction dir = 0; dir < vector::nComponents; dir++)
// {
// if
// (
// plusFaceLevel[dir] != -1
// && minFaceLevel[dir] != -1
// && plusFaceLevel[dir] != minFaceLevel[dir]
// )
// {
// candidateCellSet.insert(cellI);
// }
// }
//}
const scalar oppositeCos = Foam::cos(Foam::degToRad(135));
forAllConstIter(cellSet, transitionCells, iter)
{
label cellI = iter.key();
const cell& cFaces = cells[cellI];
label cLevel = cutter.cellLevel()[cellI];
// Detect opposite intersection
bool foundOpposite = false;
forAll(cFaces, cFaceI)
{
label faceI = cFaces[cFaceI];
if
(
surfaceIndex[faceI] != -1
&& cutter.faceLevel(faceI) > cLevel
)
{
// Get outwards pointing normal
vector n = fA[faceI]/mag(fA[faceI]);
if (faceOwner[faceI] != cellI)
{
n = -n;
}
// Check for any opposite intersection
forAll(cFaces, cFaceI2)
{
label face2I = cFaces[cFaceI2];
if
(
face2I != faceI
&& surfaceIndex[face2I] != -1
)
{
// Get outwards pointing normal
vector n2 = fA[face2I]/mag(fA[face2I]);
if (faceOwner[face2I] != cellI)
{
n2 = -n2;
}
if ((n&n2) < oppositeCos)
{
foundOpposite = true;
break;
}
}
}
if (foundOpposite)
{
break;
}
}
}
if (foundOpposite)
{
candidateCellSet.insert(cellI);
}
}
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCellSet.size()
<< " cells to cellSet candidateCellSet." << endl;
candidateCellSet.instance() = meshRefiner_.timeName();
candidateCellSet.write();
}
candidateCells = candidateCellSet.toc();
}
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. After a few iterations check if too
// few cells
if
(
nCellsToRefine == 0
|| (
iter >= 1
&& 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
(
"interface cell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"interface cell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
}
return iter;
}
void Foam::autoRefineDriver::removeInsideCells void Foam::autoRefineDriver::removeInsideCells
( (
const refinementParameters& refineParams, const refinementParameters& refineParams,
@ -692,13 +1036,15 @@ void Foam::autoRefineDriver::removeInsideCells
nBufferLayers, // nBufferLayers nBufferLayers, // nBufferLayers
globalToMasterPatch_, globalToMasterPatch_,
globalToSlavePatch_, globalToSlavePatch_,
refineParams.keepPoints()[0] refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh()
); );
if (debug&meshRefinement::MESH) if (debug&meshRefinement::MESH)
{ {
Pout<< "Writing subsetted mesh to time " Pout<< "Writing subsetted mesh to time "
<< meshRefiner_.timeName() << '.' << endl; << meshRefiner_.timeName() << endl;
meshRefiner_.write meshRefiner_.write
( (
meshRefinement::debugType(debug), meshRefinement::debugType(debug),
@ -753,7 +1099,7 @@ Foam::label Foam::autoRefineDriver::shellRefine
( (
meshRefiner_.refineCandidates meshRefiner_.refineCandidates
( (
refineParams.keepPoints(), refineParams.locationsInMesh(),
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(), refineParams.planarAngle(),
@ -913,22 +1259,40 @@ void Foam::autoRefineDriver::baffleAndSplitMesh
false, // perpendicular edge connected cells false, // perpendicular edge connected cells
scalarField(0), // per region perpendicular angle scalarField(0), // per region perpendicular angle
// Free standing baffles
!handleSnapProblems, // merge free standing baffles?
refineParams.planarAngle(),
motionDict, motionDict,
const_cast<Time&>(mesh.time()), const_cast<Time&>(mesh.time()),
globalToMasterPatch_, globalToMasterPatch_,
globalToSlavePatch_, globalToSlavePatch_,
refineParams.keepPoints()[0] refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh()
); );
if (!handleSnapProblems) // merge free standing baffles?
{
meshRefiner_.mergeFreeStandingBaffles
(
snapParams,
refineParams.useTopologicalSnapDetection(),
false, // perpendicular edge connected cells
scalarField(0), // per region perpendicular angle
refineParams.planarAngle(),
motionDict,
const_cast<Time&>(mesh.time()),
globalToMasterPatch_,
globalToSlavePatch_,
refineParams.locationsInMesh(),
refineParams.locationsOutsideMesh()
);
}
} }
void Foam::autoRefineDriver::zonify void Foam::autoRefineDriver::zonify
( (
const refinementParameters& refineParams const refinementParameters& refineParams,
wordPairHashTable& zonesToFaceZone
) )
{ {
// Mesh is at its finest. Do zoning // Mesh is at its finest. Do zoning
@ -940,7 +1304,11 @@ void Foam::autoRefineDriver::zonify
const labelList namedSurfaces = const labelList namedSurfaces =
surfaceZonesInfo::getNamedSurfaces(meshRefiner_.surfaces().surfZones()); surfaceZonesInfo::getNamedSurfaces(meshRefiner_.surfaces().surfZones());
if (namedSurfaces.size()) if
(
namedSurfaces.size()
|| refineParams.zonesInMesh().size()
)
{ {
Info<< nl Info<< nl
<< "Introducing zones for interfaces" << nl << "Introducing zones for interfaces" << nl
@ -956,14 +1324,16 @@ void Foam::autoRefineDriver::zonify
meshRefiner_.zonify meshRefiner_.zonify
( (
refineParams.keepPoints()[0], refineParams.allowFreeStandingZoneFaces(),
refineParams.allowFreeStandingZoneFaces() refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
zonesToFaceZone
); );
if (debug&meshRefinement::MESH) if (debug&meshRefinement::MESH)
{ {
Pout<< "Writing zoned mesh to time " Pout<< "Writing zoned mesh to time "
<< meshRefiner_.timeName() << '.' << endl; << meshRefiner_.timeName() << endl;
meshRefiner_.write meshRefiner_.write
( (
meshRefinement::debugType(debug), meshRefinement::debugType(debug),
@ -1015,15 +1385,29 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
handleSnapProblems, // remove perp edge connected cells handleSnapProblems, // remove perp edge connected cells
perpAngle, // perp angle perpAngle, // perp angle
// Free standing baffles
true, // merge free standing baffles?
refineParams.planarAngle(), // planar angle
motionDict, motionDict,
const_cast<Time&>(mesh.time()), const_cast<Time&>(mesh.time()),
globalToMasterPatch_, globalToMasterPatch_,
globalToSlavePatch_, globalToSlavePatch_,
refineParams.keepPoints()[0] refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh()
);
// Merge free-standing baffles always
meshRefiner_.mergeFreeStandingBaffles
(
snapParams,
refineParams.useTopologicalSnapDetection(),
handleSnapProblems,
perpAngle,
refineParams.planarAngle(),
motionDict,
const_cast<Time&>(mesh.time()),
globalToMasterPatch_,
globalToSlavePatch_,
refineParams.locationsInMesh(),
refineParams.locationsOutsideMesh()
); );
if (debug) if (debug)
@ -1048,7 +1432,7 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
// Actually merge baffles. Note: not exactly parallellized. Should // Actually merge baffles. Note: not exactly parallellized. Should
// convert baffle faces into processor faces if they resulted // convert baffle faces into processor faces if they resulted
// from them. // from them.
meshRefiner_.mergeBaffles(couples); meshRefiner_.mergeBaffles(couples, Map<label>(0));
if (debug) if (debug)
{ {
@ -1061,7 +1445,8 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
( (
globalToMasterPatch_, globalToMasterPatch_,
globalToSlavePatch_, globalToSlavePatch_,
refineParams.keepPoints()[0] refineParams.locationsInMesh(),
refineParams.locationsOutsideMesh()
); );
if (debug) if (debug)
@ -1077,7 +1462,7 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
if (debug&meshRefinement::MESH) if (debug&meshRefinement::MESH)
{ {
Pout<< "Writing handleProblemCells mesh to time " Pout<< "Writing handleProblemCells mesh to time "
<< meshRefiner_.timeName() << '.' << endl; << meshRefiner_.timeName() << endl;
meshRefiner_.write meshRefiner_.write
( (
meshRefinement::debugType(debug), meshRefinement::debugType(debug),
@ -1092,8 +1477,83 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
} }
void Foam::autoRefineDriver::addFaceZones
(
meshRefinement& meshRefiner,
const refinementParameters& refineParams,
const HashTable<Pair<word> >& faceZoneToPatches
)
{
if (faceZoneToPatches.size())
{
Info<< nl
<< "Adding patches for face zones" << nl
<< "-----------------------------" << nl
<< endl;
Info<< setf(ios_base::left)
<< setw(6) << "Patch"
<< setw(20) << "Type"
<< setw(30) << "Name"
<< setw(30) << "FaceZone"
<< setw(10) << "FaceType"
<< nl
<< setw(6) << "-----"
<< setw(20) << "----"
<< setw(30) << "----"
<< setw(30) << "--------"
<< setw(10) << "--------"
<< endl;
const polyMesh& mesh = meshRefiner.mesh();
// Add patches for added inter-region faceZones
forAllConstIter(HashTable<Pair<word> >, faceZoneToPatches, iter)
{
const word& fzName = iter.key();
const Pair<word>& patchNames = iter();
// Get any user-defined faceZone data
surfaceZonesInfo::faceZoneType fzType;
dictionary patchInfo = refineParams.getZoneInfo(fzName, fzType);
const word& masterName = fzName;
//const word slaveName = fzName + "_slave";
//const word slaveName = czNames.second()+"_to_"+czNames.first();
const word& slaveName = patchNames.second();
label mpI = meshRefiner.addMeshedPatch(masterName, patchInfo);
Info<< setf(ios_base::left)
<< setw(6) << mpI
<< setw(20) << mesh.boundaryMesh()[mpI].type()
<< setw(30) << masterName
<< setw(30) << fzName
<< setw(10) << surfaceZonesInfo::faceZoneTypeNames[fzType]
<< nl;
label slI = meshRefiner.addMeshedPatch(slaveName, patchInfo);
Info<< setf(ios_base::left)
<< setw(6) << slI
<< setw(20) << mesh.boundaryMesh()[slI].type()
<< setw(30) << slaveName
<< setw(30) << fzName
<< setw(10) << surfaceZonesInfo::faceZoneTypeNames[fzType]
<< nl;
meshRefiner.addFaceZone(fzName, masterName, slaveName, fzType);
}
Info<< endl;
}
}
void Foam::autoRefineDriver::mergePatchFaces void Foam::autoRefineDriver::mergePatchFaces
( (
const bool geometricMerge,
const refinementParameters& refineParams, const refinementParameters& refineParams,
const dictionary& motionDict const dictionary& motionDict
) )
@ -1105,6 +1565,8 @@ void Foam::autoRefineDriver::mergePatchFaces
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
if (geometricMerge)
{
meshRefiner_.mergePatchFacesUndo meshRefiner_.mergePatchFacesUndo
( (
Foam::cos(degToRad(45.0)), Foam::cos(degToRad(45.0)),
@ -1113,6 +1575,18 @@ void Foam::autoRefineDriver::mergePatchFaces
motionDict, motionDict,
labelList(mesh.nFaces(), -1) labelList(mesh.nFaces(), -1)
); );
}
else
{
// Still merge refined boundary faces if all four are on same patch
meshRefiner_.mergePatchFaces
(
Foam::cos(degToRad(45.0)),
Foam::cos(degToRad(45.0)),
4, // only merge faces split into 4
meshRefiner_.meshedPatches()
);
}
if (debug) if (debug)
{ {
@ -1134,6 +1608,7 @@ void Foam::autoRefineDriver::doRefine
const refinementParameters& refineParams, const refinementParameters& refineParams,
const snapParameters& snapParams, const snapParameters& snapParams,
const bool prepareForSnapping, const bool prepareForSnapping,
const bool doMergePatchFaces,
const dictionary& motionDict const dictionary& motionDict
) )
{ {
@ -1145,7 +1620,7 @@ void Foam::autoRefineDriver::doRefine
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
// Check that all the keep points are inside the mesh. // Check that all the keep points are inside the mesh.
refineParams.findCells(mesh); refineParams.findCells(true, mesh, refineParams.locationsInMesh());
// Refine around feature edges // Refine around feature edges
featureEdgeRefine featureEdgeRefine
@ -1196,6 +1671,13 @@ void Foam::autoRefineDriver::doRefine
100 // maxIter 100 // maxIter
); );
// Refine any cells with differing refinement level on either side
refinementInterfaceRefine
(
refineParams,
10 // maxIter
);
// Introduce baffles at surface intersections. Remove sections unreachable // Introduce baffles at surface intersections. Remove sections unreachable
// from keepPoint. // from keepPoint.
baffleAndSplitMesh baffleAndSplitMesh
@ -1206,8 +1688,31 @@ void Foam::autoRefineDriver::doRefine
motionDict motionDict
); );
// Mesh is at its finest. Do optional zoning. // Mesh is at its finest. Do optional zoning (cellZones and faceZones)
zonify(refineParams); wordPairHashTable zonesToFaceZone;
zonify(refineParams, zonesToFaceZone);
// Create pairs of patches for faceZones
{
HashTable<Pair<word> > faceZoneToPatches(zonesToFaceZone.size());
// Note: zonesToFaceZone contains the same data on different
// processors but in different order. We could sort the
// contents but instead just loop in sortedToc order.
List<Pair<word> > czs(zonesToFaceZone.sortedToc());
forAll(czs, i)
{
const Pair<word>& czNames = czs[i];
const word& fzName = zonesToFaceZone[czNames];
const word& masterName = fzName;
const word slaveName = czNames.second() + "_to_" + czNames.first();
Pair<word> patches(masterName, slaveName);
faceZoneToPatches.insert(fzName, patches);
}
addFaceZones(meshRefiner_, refineParams, faceZoneToPatches);
}
// Pull baffles apart // Pull baffles apart
splitAndMergeBaffles splitAndMergeBaffles
@ -1221,7 +1726,7 @@ void Foam::autoRefineDriver::doRefine
// Do something about cells with refined faces on the boundary // Do something about cells with refined faces on the boundary
if (prepareForSnapping) if (prepareForSnapping)
{ {
mergePatchFaces(refineParams, motionDict); mergePatchFaces(doMergePatchFaces, refineParams, motionDict);
} }
@ -1232,28 +1737,17 @@ void Foam::autoRefineDriver::doRefine
<< "---------------------" << nl << "---------------------" << nl
<< endl; << endl;
//if (debug)
//{
// const_cast<Time&>(mesh.time())++;
//}
// Do final balancing. Keep zoned faces on one processor since the // Do final balancing. Keep zoned faces on one processor since the
// snap phase will convert them to baffles and this only works for // snap phase will convert them to baffles and this only works for
// internal faces. // internal faces.
meshRefiner_.balance meshRefiner_.balance
( (
true, true, // keepZoneFaces
false, false, // keepBaffles
scalarField(mesh.nCells(), 1), // dummy weights scalarField(mesh.nCells(), 1), // cellWeights
decomposer_, decomposer_,
distributor_ distributor_
); );
if (debug)
{
meshRefiner_.checkZoneFaces();
}
} }
} }

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.
@ -34,7 +34,8 @@ SourceFiles
#ifndef autoRefineDriver_H #ifndef autoRefineDriver_H
#define autoRefineDriver_H #define autoRefineDriver_H
#include "treeBoundBox.H" #include "wordPairHashTable.H"
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -105,6 +106,13 @@ class autoRefineDriver
const label maxIter const label maxIter
); );
//- Refine cells with opposite faces with differing refinement level
label refinementInterfaceRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Remove all cells within intersected region //- Remove all cells within intersected region
void removeInsideCells void removeInsideCells
( (
@ -129,7 +137,11 @@ class autoRefineDriver
); );
//- Add zones //- Add zones
void zonify(const refinementParameters& refineParams); void zonify
(
const refinementParameters& refineParams,
wordPairHashTable& zonesToFaceZone
);
void splitAndMergeBaffles void splitAndMergeBaffles
( (
@ -142,11 +154,11 @@ class autoRefineDriver
//- Merge refined boundary faces (from exposing coarser cell) //- Merge refined boundary faces (from exposing coarser cell)
void mergePatchFaces void mergePatchFaces
( (
const bool geometricMerge,
const refinementParameters& refineParams, const refinementParameters& refineParams,
const dictionary& motionDict const dictionary& motionDict
); );
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
autoRefineDriver(const autoRefineDriver&); autoRefineDriver(const autoRefineDriver&);
@ -182,8 +194,18 @@ public:
const refinementParameters& refineParams, const refinementParameters& refineParams,
const snapParameters& snapParams, const snapParameters& snapParams,
const bool prepareForSnapping, const bool prepareForSnapping,
const bool mergePatchFaces,
const dictionary& motionDict const dictionary& motionDict
); );
//- Helper: add faceZones and patches
static void addFaceZones
(
meshRefinement& meshRefiner,
const refinementParameters& refineParams,
const HashTable<Pair<word> >& faceZoneToPatches
);
}; };

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-2014 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.
@ -37,6 +37,7 @@ SourceFiles
#define autoSnapDriver_H #define autoSnapDriver_H
#include "meshRefinement.H" #include "meshRefinement.H"
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -45,6 +46,7 @@ namespace Foam
// Forward declaration of classes // Forward declaration of classes
class motionSmoother; class motionSmoother;
class refinementParameters;
class snapParameters; class snapParameters;
class pointConstraint; class pointConstraint;
@ -79,26 +81,34 @@ class autoSnapDriver
PackedBoolList& PackedBoolList&
); );
//- Calculate displacement (over all mesh points) to move points
// to average of connected cell centres
static tmp<pointField> smoothInternalDisplacement
(
const meshRefinement& meshRefiner,
const motionSmoother&
);
//- Calculate displacement per patch point to smooth out patch. //- Calculate displacement per patch point to smooth out patch.
// Quite complicated in determining which points to move where. // Quite complicated in determining which points to move where.
static pointField smoothPatchDisplacement static tmp<pointField> smoothPatchDisplacement
( (
const motionSmoother&, const motionSmoother&,
const List<labelPair>& const List<labelPair>&
); );
//static tmp<pointField> avg static tmp<pointField> avg
//( (
// const indirectPrimitivePatch&, const indirectPrimitivePatch&,
// const pointField& const pointField&
//); );
//- Calculate displacement per patch point. Wip. //- Calculate displacement per patch point. Wip.
//static tmp<pointField> smoothLambdaMuPatchDisplacement static pointField smoothLambdaMuPatchDisplacement
//( (
// const motionSmoother& meshMover, const motionSmoother& meshMover,
// const List<labelPair>& baffles const List<labelPair>& baffles
//); );
//- Check that face zones are synced //- Check that face zones are synced
@ -136,6 +146,48 @@ class autoSnapDriver
DynamicList<labelPair>& splits DynamicList<labelPair>& splits
) const; ) const;
//- Get per face -1 or label of opposite face if on internal/baffle
// faceZone
labelList getInternalOrBaffleDuplicateFace() const;
//- Get points both on patch and facezone.
static labelList getZoneSurfacePoints
(
const fvMesh& mesh,
const indirectPrimitivePatch&,
const word& zoneName
);
//- Get points both on patch and facezone.
template<class FaceList>
static labelList getFacePoints
(
const indirectPrimitivePatch& pp,
const FaceList& faces
);
//- Per patch point calculate point on nearest surface.
// Return displacement of patch points.
static void calcNearestSurface
(
const refinementSurfaces& surfaces,
const labelList& surfacesToTest,
const labelListList& regionsToTest,
const pointField& localPoints,
const labelList& zonePointIndices,
scalarField& minSnapDist,
labelList& snapSurf,
vectorField& patchDisp,
// Optional: nearest point, normal
pointField& nearestPoint,
vectorField& nearestNormal
);
// Feature line snapping // Feature line snapping
//- Is point on two feature edges that make a largish angle? //- Is point on two feature edges that make a largish angle?
@ -177,8 +229,8 @@ class autoSnapDriver
const scalarField& faceSnapDist, const scalarField& faceSnapDist,
vectorField& faceDisp, vectorField& faceDisp,
vectorField& faceSurfaceNormal, vectorField& faceSurfaceNormal,
labelList& faceSurfaceRegion, labelList& faceSurfaceRegion
vectorField& faceRotation //vectorField& faceRotation
) const; ) const;
void calcNearestFacePointProperties void calcNearestFacePointProperties
( (
@ -253,6 +305,86 @@ class autoSnapDriver
const label faceI const label faceI
) const; ) const;
scalar pyrVol
(
const indirectPrimitivePatch& pp,
const vectorField& featureAttraction,
const face& localF,
const point& cc
) const;
void facePoints
(
const indirectPrimitivePatch& pp,
const vectorField& featureAttraction,
const vectorField& nearestAttraction,
const face& f,
DynamicField<point>& points
) const;
scalar pyrVol
(
const indirectPrimitivePatch& pp,
const vectorField& featureAttraction,
const vectorField& nearestAttraction,
const face& localF,
const point& cc
) const;
Tuple2<point, vector> centreAndNormal
(
const indirectPrimitivePatch& pp,
const vectorField& featureAttraction,
const vectorField& nearestAttraction,
const face& localF
) const;
bool isSplitAlignedWithFeature
(
const scalar featureCos,
const point& newPt0,
const pointConstraint& pc0,
const point& newPt1,
const pointConstraint& pc1
) const;
bool isConcave
(
const point& c0,
const vector& area0,
const point& c1,
const vector& area1,
const scalar concaveCos
) const;
labelPair findDiagonalAttraction
(
const scalar featureCos,
const scalar concaveCos,
const scalar minAreaFraction,
const indirectPrimitivePatch& pp,
const vectorField& patchAttraction,
const List<pointConstraint>& patchConstraints,
const vectorField& nearestAttraction,
const vectorField& nearestNormal,
const label faceI,
DynamicField<point>& points0,
DynamicField<point>& points1
) const;
//- Do all logic on whether to add face cut to diagonal
// attraction
void splitDiagonals
(
const scalar featureCos,
const scalar concaveCos,
const scalar minAreaFraction,
const indirectPrimitivePatch& pp,
const vectorField& nearestAttraction,
const vectorField& nearestNormal,
vectorField& patchAttraction,
List<pointConstraint>& patchConstraints,
DynamicList<label>& splitFaces,
DynamicList<labelPair>& splits
) const;
//- Avoid attraction across face diagonal since would //- Avoid attraction across face diagonal since would
// cause face squeeze // cause face squeeze
void avoidDiagonalAttraction void avoidDiagonalAttraction
@ -264,6 +396,14 @@ class autoSnapDriver
List<pointConstraint>& patchConstraints List<pointConstraint>& patchConstraints
) const; ) const;
//- Write some stats about constraints
void writeStats
(
const indirectPrimitivePatch& pp,
const PackedBoolList& isMasterPoint,
const List<pointConstraint>& patchConstraints
) const;
//- Return hit if on multiple points //- Return hit if on multiple points
pointIndexHit findMultiPatchPoint pointIndexHit findMultiPatchPoint
( (
@ -320,7 +460,6 @@ class autoSnapDriver
void featureAttractionUsingReconstruction void featureAttractionUsingReconstruction
( (
const label iter, const label iter,
const bool avoidSnapProblems,
const scalar featureCos, const scalar featureCos,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const scalarField& snapDist, const scalarField& snapDist,
@ -366,6 +505,7 @@ class autoSnapDriver
void determineBaffleFeatures void determineBaffleFeatures
( (
const label iter, const label iter,
const bool baffleFeaturePoints,
const scalar featureCos, const scalar featureCos,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
@ -450,12 +590,20 @@ class autoSnapDriver
void featureAttractionUsingFeatureEdges void featureAttractionUsingFeatureEdges
( (
const label iter, const label iter,
const bool avoidSnapProblems,
const scalar featureCos,
const bool multiRegionFeatureSnap, const bool multiRegionFeatureSnap,
const bool detectBaffles,
const bool baffleFeaturePoints,
const bool releasePoints,
const bool stringFeatures,
const bool avoidDiagonal,
const scalar featureCos,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const scalarField& snapDist, const scalarField& snapDist,
const vectorField& nearestDisp, const vectorField& nearestDisp,
const vectorField& nearestNormal,
const List<List<point> >& pointFaceSurfNormals, const List<List<point> >& pointFaceSurfNormals,
const List<List<point> >& pointFaceDisp, const List<List<point> >& pointFaceDisp,
@ -465,12 +613,14 @@ class autoSnapDriver
vectorField& patchAttraction, vectorField& patchAttraction,
List<pointConstraint>& patchConstraints List<pointConstraint>& patchConstraints
) const; ) const;
void preventFaceSqueeze void preventFaceSqueeze
( (
const label iter, const label iter,
const scalar featureCos, const scalar featureCos,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const scalarField& snapDist, const scalarField& snapDist,
const vectorField& nearestAttraction,
vectorField& patchAttraction, vectorField& patchAttraction,
List<pointConstraint>& patchConstraints List<pointConstraint>& patchConstraints
@ -483,15 +633,19 @@ class autoSnapDriver
vectorField calcNearestSurfaceFeature vectorField calcNearestSurfaceFeature
( (
const snapParameters& snapParams, const snapParameters& snapParams,
const bool avoidSnapProblems, const bool alignMeshEdges,
const label iter, const label iter,
const scalar featureCos, const scalar featureCos,
const scalar featureAttract, const scalar featureAttract,
const scalarField& snapDist, const scalarField& snapDist,
const vectorField& nearestDisp, const vectorField& nearestDisp,
const vectorField& nearestNormal,
motionSmoother& meshMover, motionSmoother& meshMover,
vectorField& patchAttraction, vectorField& patchAttraction,
List<pointConstraint>& patchConstraints List<pointConstraint>& patchConstraints,
DynamicList<label>& splitFaces,
DynamicList<labelPair>& splits
) const; ) const;
@ -545,14 +699,6 @@ public:
motionSmoother& motionSmoother&
); );
//- Get points both on patch and facezone.
static labelList getZoneSurfacePoints
(
const fvMesh& mesh,
const indirectPrimitivePatch&,
const word& zoneName
);
//- Helper: calculate average cell centre per point //- Helper: calculate average cell centre per point
static tmp<pointField> avgCellCentres static tmp<pointField> avgCellCentres
( (
@ -575,7 +721,10 @@ public:
// displacement of patch points. // displacement of patch points.
static vectorField calcNearestSurface static vectorField calcNearestSurface
( (
const bool strictRegionSnap,
const meshRefinement& meshRefiner, const meshRefinement& meshRefiner,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch,
const scalarField& snapDist, const scalarField& snapDist,
const indirectPrimitivePatch&, const indirectPrimitivePatch&,
pointField& nearestPoint, pointField& nearestPoint,
@ -622,6 +771,7 @@ public:
( (
const dictionary& snapDict, const dictionary& snapDict,
const dictionary& motionDict, const dictionary& motionDict,
const bool mergePatchFaces,
const scalar featureCos, const scalar featureCos,
const scalar planarAngle, const scalar planarAngle,
const snapParameters& snapParams const snapParameters& snapParams
@ -636,6 +786,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "autoSnapDriverTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "autoSnapDriver.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class FaceList>
Foam::labelList Foam::autoSnapDriver::getFacePoints
(
const indirectPrimitivePatch& pp,
const FaceList& faces
)
{
// Could use PrimitivePatch & localFaces to extract points but might just
// as well do it ourselves.
boolList pointOnZone(pp.nPoints(), false);
forAll(faces, i)
{
const face& f = faces[i];
forAll(f, fp)
{
label meshPointI = f[fp];
Map<label>::const_iterator iter =
pp.meshPointMap().find(meshPointI);
if (iter != pp.meshPointMap().end())
{
label pointI = iter();
pointOnZone[pointI] = true;
}
}
}
return findIndices(pointOnZone, true);
}
// ************************************************************************* //

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-2014 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.
@ -124,6 +124,14 @@ Foam::layerParameters::layerParameters
readScalar(dict.lookup("minThickness")) readScalar(dict.lookup("minThickness"))
), ),
featureAngle_(readScalar(dict.lookup("featureAngle"))), featureAngle_(readScalar(dict.lookup("featureAngle"))),
mergePatchFacesAngle_
(
dict.lookupOrDefault<scalar>
(
"mergePatchFacesAngle",
featureAngle_
)
),
concaveAngle_ concaveAngle_
( (
dict.lookupOrDefault("concaveAngle", defaultConcaveAngle) dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)

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-2014 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.
@ -114,6 +114,8 @@ private:
scalar featureAngle_; scalar featureAngle_;
scalar mergePatchFacesAngle_;
scalar concaveAngle_; scalar concaveAngle_;
label nGrow_; label nGrow_;
@ -247,6 +249,11 @@ public:
return featureAngle_; return featureAngle_;
} }
scalar mergePatchFacesAngle() const
{
return mergePatchFacesAngle_;
}
scalar concaveAngle() const scalar concaveAngle() const
{ {
return concaveAngle_; return concaveAngle_;

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-2014 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.
@ -27,6 +27,8 @@ License
#include "unitConversion.H" #include "unitConversion.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "globalIndex.H" #include "globalIndex.H"
#include "Tuple2.H"
#include "wallPolyPatch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -44,7 +46,15 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
) )
), ),
nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))), nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))),
keepPoints_(pointField(1, dict.lookup("locationInMesh"))), locationsOutsideMesh_
(
dict.lookupOrDefault
(
"locationsOutsideMesh",
pointField(0)
)
),
faceZoneControls_(dict.subOrEmptyDict("faceZoneControls")),
allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")), allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")),
useTopologicalSnapDetection_ useTopologicalSnapDetection_
( (
@ -54,8 +64,35 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
handleSnapProblems_ handleSnapProblems_
( (
dict.lookupOrDefault<Switch>("handleSnapProblems", true) dict.lookupOrDefault<Switch>("handleSnapProblems", true)
),
interfaceRefine_
(
dict.lookupOrDefault<Switch>("interfaceRefine", true)
) )
{ {
point locationInMesh;
if (dict.readIfPresent("locationInMesh", locationInMesh))
{
locationsInMesh_.append(locationInMesh);
zonesInMesh_.append("noneIfNotSet");// special name for no cellZone
}
List<Tuple2<point, word> > pointsToZone;
if (dict.readIfPresent("locationsInMesh", pointsToZone))
{
label nZones = locationsInMesh_.size();
locationsInMesh_.setSize(nZones+pointsToZone.size());
zonesInMesh_.setSize(locationsInMesh_.size());
forAll(pointsToZone, i)
{
locationsInMesh_[nZones] = pointsToZone[i].first();
zonesInMesh_[nZones] = pointsToZone[i].second();
nZones++;
}
}
scalar featAngle(readScalar(dict.lookup("resolveFeatureAngle"))); scalar featAngle(readScalar(dict.lookup("resolveFeatureAngle")));
if (featAngle < 0 || featAngle > 180) if (featAngle < 0 || featAngle > 180)
@ -71,8 +108,68 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::refinementParameters::findCells(const polyMesh& mesh) Foam::dictionary Foam::refinementParameters::getZoneInfo
const (
const word& fzName,
surfaceZonesInfo::faceZoneType& faceType
) const
{
dictionary patchInfo;
patchInfo.add("type", wallPolyPatch::typeName);
faceType = surfaceZonesInfo::INTERNAL;
if (faceZoneControls_.found(fzName))
{
const dictionary& fzDict = faceZoneControls_.subDict(fzName);
if (fzDict.found("patchInfo"))
{
patchInfo = fzDict.subDict("patchInfo");
}
word faceTypeName;
if (fzDict.readIfPresent("faceType", faceTypeName))
{
faceType = surfaceZonesInfo::faceZoneTypeNames[faceTypeName];
}
}
return patchInfo;
}
Foam::labelList Foam::refinementParameters::addCellZonesToMesh
(
polyMesh& mesh
) const
{
labelList zoneIDs(zonesInMesh_.size(), -1);
forAll(zonesInMesh_, i)
{
if
(
zonesInMesh_[i] != word::null
&& zonesInMesh_[i] != "none"
&& zonesInMesh_[i] != "noneIfNotSet"
)
{
zoneIDs[i] = surfaceZonesInfo::addCellZone
(
zonesInMesh_[i], // name
labelList(0), // addressing
mesh
);
}
}
return zoneIDs;
}
Foam::labelList Foam::refinementParameters::findCells
(
const bool checkInsideMesh,
const polyMesh& mesh,
const pointField& locations
)
{ {
// Force calculation of tet-diag decomposition (for use in findCell) // Force calculation of tet-diag decomposition (for use in findCell)
(void)mesh.tetBasePtIs(); (void)mesh.tetBasePtIs();
@ -81,13 +178,13 @@ const
globalIndex globalCells(mesh.nCells()); globalIndex globalCells(mesh.nCells());
// Cell label per point // Cell label per point
labelList cellLabels(keepPoints_.size()); labelList cellLabels(locations.size());
forAll(keepPoints_, i) forAll(locations, i)
{ {
const point& keepPoint = keepPoints_[i]; const point& location = locations[i];
label localCellI = mesh.findCell(keepPoint); label localCellI = mesh.findCell(location);
label globalCellI = -1; label globalCellI = -1;
@ -98,12 +195,13 @@ const
reduce(globalCellI, maxOp<label>()); reduce(globalCellI, maxOp<label>());
if (globalCellI == -1) if (checkInsideMesh && globalCellI == -1)
{ {
FatalErrorIn FatalErrorIn
( (
"refinementParameters::findCells(const polyMesh&) const" "refinementParameters::findCells"
) << "Point " << keepPoint "(const polyMesh&, const pointField&) const"
) << "Point " << location
<< " is not inside the mesh or on a face or edge." << nl << " is not inside the mesh or on a face or edge." << nl
<< "Bounding box of the mesh:" << mesh.bounds() << "Bounding box of the mesh:" << mesh.bounds()
<< exit(FatalError); << exit(FatalError);
@ -113,10 +211,9 @@ const
label procI = globalCells.whichProcID(globalCellI); label procI = globalCells.whichProcID(globalCellI);
label procCellI = globalCells.toLocal(procI, globalCellI); label procCellI = globalCells.toLocal(procI, globalCellI);
Info<< "Found point " << keepPoint << " in cell " << procCellI Info<< "Found point " << location << " in cell " << procCellI
<< " on processor " << procI << endl; << " on processor " << procI << endl;
if (globalCells.isLocal(globalCellI)) if (globalCells.isLocal(globalCellI))
{ {
cellLabels[i] = localCellI; cellLabels[i] = localCellI;
@ -130,4 +227,48 @@ const
} }
Foam::labelList Foam::refinementParameters::zonedLocations
(
const wordList& zonesInMesh
)
{
DynamicList<label> indices(zonesInMesh.size());
forAll(zonesInMesh, i)
{
if
(
zonesInMesh[i] == word::null
|| zonesInMesh[i] != "noneIfNotSet"
)
{
indices.append(i);
}
}
return indices;
}
Foam::labelList Foam::refinementParameters::unzonedLocations
(
const wordList& zonesInMesh
)
{
DynamicList<label> indices(0);
forAll(zonesInMesh, i)
{
if
(
zonesInMesh[i] != word::null
&& zonesInMesh[i] == "noneIfNotSet"
)
{
indices.append(i);
}
}
return indices;
}
// ************************************************************************* // // ************************************************************************* //

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-2014 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.
@ -38,6 +38,8 @@ SourceFiles
#include "dictionary.H" #include "dictionary.H"
#include "pointField.H" #include "pointField.H"
#include "Switch.H" #include "Switch.H"
#include "wordPairHashTable.H"
#include "surfaceZonesInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,8 +75,21 @@ class refinementParameters
//- Number of layers between different refinement levels //- Number of layers between different refinement levels
const label nBufferLayers_; const label nBufferLayers_;
// Selection of areas
//- Areas not to keep
const pointField locationsOutsideMesh_;
//- Areas to keep //- Areas to keep
const pointField keepPoints_; pointField locationsInMesh_;
//- Region for location
wordList zonesInMesh_;
//- Information on how to handle faces on faceZones
dictionary faceZoneControls_;
//- FaceZone faces allowed which have owner and neighbour in same //- FaceZone faces allowed which have owner and neighbour in same
// cellZone? // cellZone?
@ -89,6 +104,8 @@ class refinementParameters
Switch handleSnapProblems_; Switch handleSnapProblems_;
Switch interfaceRefine_;
// Private Member Functions // Private Member Functions
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
@ -147,9 +164,21 @@ public:
} }
//- Areas to keep //- Areas to keep
const pointField& keepPoints() const const pointField& locationsInMesh() const
{ {
return keepPoints_; return locationsInMesh_;
}
//- Per area the zone name
const wordList& zonesInMesh() const
{
return zonesInMesh_;
}
//- Optional points which are checked to be outside the mesh
const pointField& locationsOutsideMesh() const
{
return locationsOutsideMesh_;
} }
//- Are zone faces allowed only inbetween different cell zones //- Are zone faces allowed only inbetween different cell zones
@ -177,11 +206,39 @@ public:
return handleSnapProblems_; return handleSnapProblems_;
} }
//- Refine cell with opposite faces with different refinement level
bool interfaceRefine() const
{
return interfaceRefine_;
}
// Other // Other
//- Checks that cells are in mesh. Returns cells they are in. //- Get patchInfo and faceType for faceZone
labelList findCells(const polyMesh&) const; dictionary getZoneInfo
(
const word& fzName,
surfaceZonesInfo::faceZoneType& faceType
) const;
//- Add cellZones to mesh. Return indices of cellZones (or -1)
labelList addCellZonesToMesh(polyMesh&) const;
//- Checks that cells are in mesh. Returns cells (or -1) they
// are in.
static labelList findCells
(
const bool checkInsideMesh,
const polyMesh&,
const pointField& locations
);
//- Extract indices of named locations (so excludes 'keepPoints')
static labelList zonedLocations(const wordList& zonesInMesh);
//- Extract indices of unnamed locations ('keepPoints')
static labelList unzonedLocations(const wordList& zonesInMesh);
}; };

View File

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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/>.
Typedef
Foam::wordPairHashTable
Description
HashTable of Pair<word>
Typedef
Foam::wordPairHashTable
Description
HashTable of Pair<word>
\*---------------------------------------------------------------------------*/
#ifndef wordPairHashTable_H
#define wordPairHashTable_H
#include "Pair.H"
#include "HashTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef HashTable<word, Pair<word>, FixedList<word, 2>::Hash<> >
wordPairHashTable;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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-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.
@ -31,6 +31,7 @@ License
Foam::snapParameters::snapParameters(const dictionary& dict) Foam::snapParameters::snapParameters(const dictionary& dict)
: :
nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))), nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))),
nSmoothInternal_(dict.lookupOrDefault("nSmoothInternal", 0)),
snapTol_(readScalar(dict.lookup("tolerance"))), snapTol_(readScalar(dict.lookup("tolerance"))),
nSmoothDispl_(readLabel(dict.lookup("nSolveIter"))), nSmoothDispl_(readLabel(dict.lookup("nSolveIter"))),
nSnap_(readLabel(dict.lookup("nRelaxIter"))), nSnap_(readLabel(dict.lookup("nRelaxIter"))),
@ -44,7 +45,22 @@ Foam::snapParameters::snapParameters(const dictionary& dict)
detectNearSurfacesSnap_ detectNearSurfacesSnap_
( (
dict.lookupOrDefault("detectNearSurfacesSnap", true) dict.lookupOrDefault("detectNearSurfacesSnap", true)
) ),
strictRegionSnap_
(
dict.lookupOrDefault("strictRegionSnap", false)
),
detectBaffles_(dict.lookupOrDefault("detectBaffles", true)),
baffleFeaturePoints_(dict.lookupOrDefault("baffleFeaturePoints", false)),
releasePoints_(dict.lookupOrDefault("releasePoints", false)),
stringFeatures_(dict.lookupOrDefault("stringFeatures", true)),
avoidDiagonal_(dict.lookupOrDefault("avoidDiagonal", false)),
nFaceSplitInterval_
(
dict.lookupOrDefault("nFaceSplitInterval", labelMin)
),
concaveAngle_(dict.lookupOrDefault("concaveAngle", 45)),
minAreaRatio_(dict.lookupOrDefault("minAreaRatio", 0.3))
{} {}

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-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.
@ -44,8 +44,6 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Class forward declarations
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class snapParameters Declaration Class snapParameters Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -56,6 +54,8 @@ class snapParameters
const label nSmoothPatch_; const label nSmoothPatch_;
const label nSmoothInternal_;
const scalar snapTol_; const scalar snapTol_;
const label nSmoothDispl_; const label nSmoothDispl_;
@ -72,6 +72,28 @@ class snapParameters
const Switch detectNearSurfacesSnap_; const Switch detectNearSurfacesSnap_;
const Switch strictRegionSnap_;
const Switch detectBaffles_;
const Switch baffleFeaturePoints_;
const Switch releasePoints_;
const Switch stringFeatures_;
const Switch avoidDiagonal_;
//- How often needs face splitting be run
label nFaceSplitInterval_;
//- When is angle too concave too split
scalar concaveAngle_;
//- When is face-split not sufficiently diagonal
scalar minAreaRatio_;
// Private Member Functions // Private Member Functions
@ -101,6 +123,13 @@ public:
return nSmoothPatch_; return nSmoothPatch_;
} }
//- Number of internal point smoothing iterations (combined with
// nSmoothPatch
label nSmoothInternal() const
{
return nSmoothInternal_;
}
//- Relative distance for points to be attracted by surface //- Relative distance for points to be attracted by surface
// feature point // feature point
// or edge. True distance is this factor times local // or edge. True distance is this factor times local
@ -123,6 +152,25 @@ public:
return nSnap_; return nSnap_;
} }
// Surface snapping specific
//- Override attraction to nearest with intersection location
// at near surfaces
Switch detectNearSurfacesSnap() const
{
return detectNearSurfacesSnap_;
}
//- Attract point to corresponding surface region only
Switch strictRegionSnap() const
{
return strictRegionSnap_;
}
// Feature edge snapping specific
label nFeatureSnap() const label nFeatureSnap() const
{ {
return nFeatureSnap_; return nFeatureSnap_;
@ -143,11 +191,52 @@ public:
return multiRegionFeatureSnap_; return multiRegionFeatureSnap_;
} }
Switch detectNearSurfacesSnap() const Switch detectBaffles() const
{ {
return detectNearSurfacesSnap_; return detectBaffles_;
} }
Switch baffleFeaturePoints() const
{
return baffleFeaturePoints_;
}
Switch releasePoints() const
{
return releasePoints_;
}
Switch stringFeatures() const
{
return stringFeatures_;
}
Switch avoidDiagonal() const
{
return avoidDiagonal_;
}
// Face splitting
label nFaceSplitInterval() const
{
return nFaceSplitInterval_;
}
scalar concaveAngle() const
{
return concaveAngle_;
}
scalar minAreaRatio() const
{
return minAreaRatio_;
}
}; };

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) 2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 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.
@ -42,9 +42,6 @@ namespace Foam
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::displacementMeshMoverMotionSolver::displacementMeshMoverMotionSolver Foam::displacementMeshMoverMotionSolver::displacementMeshMoverMotionSolver

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) 2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 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.
@ -25,8 +25,8 @@ Class
Foam::displacementMeshMoverMotionSolver Foam::displacementMeshMoverMotionSolver
Description Description
Mesh motion solver for an fvMesh. Based on solving the cell-centre Mesh motion solver for an fvMesh. Uses externalDisplacementMeshMover
Laplacian for the motion displacement. to do the mesh motion.
SourceFiles SourceFiles
displacementMeshMoverMotionSolver.C displacementMeshMoverMotionSolver.C

View File

@ -0,0 +1,316 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "displacementMotionSolverMeshMover.H"
#include "addToRunTimeSelectionTable.H"
#include "pointConstraints.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(displacementMotionSolverMeshMover, 1);
addToRunTimeSelectionTable
(
externalDisplacementMeshMover,
displacementMotionSolverMeshMover,
dictionary
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::displacementMotionSolverMeshMover::moveMesh
(
const dictionary& moveDict,
const label nAllowableErrors,
labelList& checkFaces
)
{
const label nRelaxIter = readLabel(moveDict.lookup("nRelaxIter"));
meshMover_.setDisplacementPatchFields();
Info<< typeName << " : Moving mesh ..." << endl;
scalar oldErrorReduction = -1;
bool meshOk = false;
for (label iter = 0; iter < 2*nRelaxIter; ++ iter)
{
Info<< typeName << " : Iteration " << iter << endl;
if (iter == nRelaxIter)
{
Info<< typeName
<< " : Displacement scaling for error reduction set to 0."
<< endl;
oldErrorReduction = meshMover_.setErrorReduction(0.0);
}
if
(
meshMover_.scaleMesh
(
checkFaces,
baffles_,
meshMover_.paramDict(),
moveDict,
true,
nAllowableErrors
)
)
{
Info<< typeName << " : Successfully moved mesh" << endl;
meshOk = true;
break;
}
}
if (oldErrorReduction >= 0)
{
meshMover_.setErrorReduction(oldErrorReduction);
}
Info<< typeName << " : Finished moving mesh ..." << endl;
return meshOk;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::displacementMotionSolverMeshMover::displacementMotionSolverMeshMover
(
const dictionary& dict,
const List<labelPair>& baffles,
pointVectorField& pointDisplacement
)
:
externalDisplacementMeshMover(dict, baffles, pointDisplacement),
solverPtr_
(
displacementMotionSolver::New
(
dict.lookup("solver"),
pointDisplacement.mesh()(),
IOdictionary
(
IOobject
(
"motionSolverDict",
pointDisplacement.mesh().time().constant(),
pointDisplacement.db(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
dict
),
pointDisplacement,
pointIOField
(
IOobject
(
"points0",
pointDisplacement.mesh().time().constant(),
pointDisplacement.db(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
pointDisplacement.mesh()().points()
)
)
),
adaptPatchIDs_(getFixedValueBCs(pointDisplacement)),
adaptPatchPtr_(getPatch(mesh(), adaptPatchIDs_)),
scale_
(
IOobject
(
"scale",
pointDisplacement.time().timeName(),
pointDisplacement.db(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pMesh(),
dimensionedScalar("scale", dimless, 1.0)
),
oldPoints_(mesh().points()),
meshMover_
(
const_cast<polyMesh&>(mesh()),
const_cast<pointMesh&>(pMesh()),
adaptPatchPtr_(),
pointDisplacement,
scale_,
oldPoints_,
adaptPatchIDs_,
dict
),
fieldSmoother_(mesh())
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::displacementMotionSolverMeshMover::~displacementMotionSolverMeshMover()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::displacementMotionSolverMeshMover::move
(
const dictionary& moveDict,
const label nAllowableErrors,
labelList& checkFaces
)
{
// Correct and smooth the patch displacements so points next to
// points where the extrusion was disabled also use less extrusion.
// Note that this has to update the pointDisplacement boundary conditions
// as well, not just the internal field.
{
const label nSmoothPatchThickness = readLabel
(
moveDict.lookup("nSmoothThickness")
);
const word minThicknessName = word(moveDict.lookup("minThicknessName"));
scalarField zeroMinThickness;
if (minThicknessName == "none")
{
zeroMinThickness = scalarField(adaptPatchPtr_().nPoints(), 0.0);
}
const scalarField& minThickness =
(
(minThicknessName == "none")
? zeroMinThickness
: mesh().lookupObject<scalarField>(minThicknessName)
);
const PackedBoolList isPatchMasterPoint
(
meshRefinement::getMasterPoints
(
mesh(),
adaptPatchPtr_().meshPoints()
)
);
const PackedBoolList isPatchMasterEdge
(
meshRefinement::getMasterEdges
(
mesh(),
adaptPatchPtr_().meshEdges
(
mesh().edges(),
mesh().pointEdges()
)
)
);
// Smooth patch displacement
vectorField displacement
(
pointDisplacement().internalField(),
adaptPatchPtr_().meshPoints()
);
fieldSmoother_.minSmoothField
(
nSmoothPatchThickness,
isPatchMasterPoint,
isPatchMasterEdge,
adaptPatchPtr_(),
minThickness,
displacement
);
scalar resid = 0;
forAll(displacement, patchPointI)
{
const label pointI(adaptPatchPtr_().meshPoints()[patchPointI]);
resid += mag(pointDisplacement()[pointI]-displacement[patchPointI]);
pointDisplacement()[pointI] = displacement[patchPointI];
}
// Take over smoothed displacements on bcs
meshMover_.setDisplacementPatchFields();
}
// Use motionSolver to calculate internal displacement
{
solverPtr_->pointDisplacement() == pointDisplacement();
// Force solving and constraining - just so its pointDisplacement gets
// the correct value
(void)solverPtr_->newPoints();
pointDisplacement() == solverPtr_->pointDisplacement();
}
return moveMesh(moveDict, nAllowableErrors, checkFaces);
}
void Foam::displacementMotionSolverMeshMover::movePoints
(
const pointField& p
)
{
externalDisplacementMeshMover::movePoints(p);
// Update motion solver for new geometry
solverPtr_->movePoints(p);
// Update motionSmoother for new geometry (moves adaptPatchPtr_)
meshMover_.movePoints();
// Assume current mesh location is correct (reset oldPoints, scale)
meshMover_.correct();
}
// ************************************************************************* //

View File

@ -0,0 +1,158 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify i
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::displacementMotionSolverMeshMover
Description
Quality-based under-relaxation wrapped around generic
displacementMotionSolver.
Example of use in layer settings in snappyHexMeshDict:
\verbatim
meshShrinker displacementMotionSolver;
solver displacementLaplacian;
displacementLaplacianCoeffs
{
diffusivity quadratic inverseDistance 1(wall);
}
\endverbatim
SourceFiles
displacementMotionSolverMeshMover.C
\*---------------------------------------------------------------------------*/
#ifndef displacementMotionSolverMeshMover_H
#define displacementMotionSolverMeshMover_H
#include "externalDisplacementMeshMover.H"
#include "displacementMotionSolver.H"
#include "motionSmootherAlgo.H"
#include "fieldSmoother.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class displacementMotionSolverMeshMover Declaration
\*---------------------------------------------------------------------------*/
class displacementMotionSolverMeshMover
:
public externalDisplacementMeshMover
{
// Private Data
//- Mesh motion solver
autoPtr<displacementMotionSolver> solverPtr_;
//- IDs of fixedValue patches that we can modify
const labelList adaptPatchIDs_;
//- Combined indirect fixedValue patches that we can modify
autoPtr<indirectPrimitivePatch> adaptPatchPtr_;
//- Scale factor for displacemen
pointScalarField scale_;
//- Old point field
pointField oldPoints_;
//- Mesh mover algorithm
motionSmootherAlgo meshMover_;
//- Field smoothing
fieldSmoother fieldSmoother_;
// Private Member Functions
//- Apply the mesh mover algorithm
bool moveMesh
(
const dictionary& moveDict,
const label nAllowableErrors,
labelList& checkFaces
);
public:
//- Runtime type information
TypeName("displacementMotionSolver");
// Constructors
//- Construct from a polyMesh and an IOdictionary
displacementMotionSolverMeshMover
(
const dictionary& dict,
const List<labelPair>& baffles,
pointVectorField& pointDisplacemen
);
//- Destructor
virtual ~displacementMotionSolverMeshMover();
// Member Functions
//- Move mesh using current pointDisplacement boundary values.
// Return true if succesful (errors on checkFaces less than
// allowable). Updates pointDisplacement.
virtual bool move
(
const dictionary&,
const label nAllowableErrors,
labelList& checkFaces
);
//- Update local data for geometry changes
virtual void movePoints(const pointField&);
//- Update local data for topology changes
virtual void updateMesh(const mapPolyMesh&)
{
notImplemented
(
"displacementMotionSolverMeshMover::updateMesh"
"(const mapPolyMesh&)"
);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // 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) 2013-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-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.
@ -25,6 +25,7 @@ License
#include "externalDisplacementMeshMover.H" #include "externalDisplacementMeshMover.H"
#include "mapPolyMesh.H" #include "mapPolyMesh.H"
#include "zeroFixedValuePointPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -35,6 +36,84 @@ namespace Foam
} }
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::labelList Foam::externalDisplacementMeshMover::getFixedValueBCs
(
const pointVectorField& field
)
{
DynamicList<label> adaptPatchIDs;
forAll(field.boundaryField(), patchI)
{
const pointPatchField<vector>& patchField =
field.boundaryField()[patchI];
if (isA<valuePointPatchField<vector> >(patchField))
{
if (isA<zeroFixedValuePointPatchField<vector> >(patchField))
{
// Special condition of fixed boundary condition. Does not
// get adapted
}
else
{
adaptPatchIDs.append(patchI);
}
}
}
return adaptPatchIDs;
}
Foam::autoPtr<Foam::indirectPrimitivePatch>
Foam::externalDisplacementMeshMover::getPatch
(
const polyMesh& mesh,
const labelList& patchIDs
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Count faces.
label nFaces = 0;
forAll(patchIDs, i)
{
const polyPatch& pp = patches[patchIDs[i]];
nFaces += pp.size();
}
// Collect faces.
labelList addressing(nFaces);
nFaces = 0;
forAll(patchIDs, i)
{
const polyPatch& pp = patches[patchIDs[i]];
label meshFaceI = pp.start();
forAll(pp, i)
{
addressing[nFaces++] = meshFaceI++;
}
}
return autoPtr<indirectPrimitivePatch>
(
new indirectPrimitivePatch
(
IndirectList<face>(mesh.faces(), addressing),
mesh.points()
)
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::externalDisplacementMeshMover::externalDisplacementMeshMover Foam::externalDisplacementMeshMover::externalDisplacementMeshMover

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) 2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 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.
@ -67,6 +67,19 @@ protected:
pointVectorField& pointDisplacement_; pointVectorField& pointDisplacement_;
// Protected Member functions
//- Extract fixed-value patchfields
static labelList getFixedValueBCs(const pointVectorField&);
//- Construct patch on selected patches
static autoPtr<indirectPrimitivePatch> getPatch
(
const polyMesh&,
const labelList&
);
private: private:
// Private Member Functions // Private Member Functions
@ -80,6 +93,7 @@ private:
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const externalDisplacementMeshMover&); void operator=(const externalDisplacementMeshMover&);
public: public:
//- Runtime type information //- Runtime type information

View File

@ -0,0 +1,299 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 "fieldSmoother.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fieldSmoother, 0);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldSmoother::fieldSmoother(const polyMesh& mesh)
:
mesh_(mesh)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fieldSmoother::~fieldSmoother()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::fieldSmoother::smoothNormals
(
const label nIter,
const PackedBoolList& isMeshMasterPoint,
const PackedBoolList& isMeshMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const
{
// Get smoothly varying internal normals field.
Info<< typeName
<< " : Smoothing normals in interior ..." << endl;
const edgeList& edges = mesh_.edges();
// Points that do not change.
PackedBoolList isFixedPoint(mesh_.nPoints());
// Internal points that are fixed
forAll(fixedPoints, i)
{
label meshPointI = fixedPoints[i];
isFixedPoint.set(meshPointI, 1);
}
// Make sure that points that are coupled to meshPoints but not on a patch
// are fixed as well
syncTools::syncPointList(mesh_, isFixedPoint, maxEqOp<unsigned int>(), 0);
// Correspondence between local edges/points and mesh edges/points
const labelList meshPoints(identity(mesh_.nPoints()));
// Calculate inverse sum of weights
scalarField edgeWeights(mesh_.nEdges());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh_,
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
vectorField average;
for (label iter = 0; iter < nIter; iter++)
{
meshRefinement::weightedSum
(
mesh_,
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
normals,
average
);
average *= invSumWeight;
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isMeshMasterPoint,
mag(normals-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
// Transfer to normals vector field
forAll(average, pointI)
{
if (isFixedPoint.get(pointI) == 0)
{
//full smoothing neighbours + point value
average[pointI] = 0.5*(normals[pointI]+average[pointI]);
normals[pointI] = average[pointI];
normals[pointI] /= mag(normals[pointI]) + VSMALL;
}
}
}
}
void Foam::fieldSmoother::smoothPatchNormals
(
const label nIter,
const PackedBoolList& isPatchMasterPoint,
const PackedBoolList& isPatchMasterEdge,
const indirectPrimitivePatch& adaptPatch,
pointField& normals
) const
{
const edgeList& edges = adaptPatch.edges();
const labelList& meshPoints = adaptPatch.meshPoints();
// Get smoothly varying internal normals field.
Info<< typeName << " : Smoothing normals ..." << endl;
scalarField edgeWeights(edges.size());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh_,
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
vectorField average;
for (label iter = 0; iter < nIter; iter++)
{
meshRefinement::weightedSum
(
mesh_,
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
normals,
average
);
average *= invSumWeight;
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isPatchMasterPoint,
mag(normals-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
// Transfer to normals vector field
forAll(average, pointI)
{
// full smoothing neighbours + point value
average[pointI] = 0.5*(normals[pointI]+average[pointI]);
normals[pointI] = average[pointI];
normals[pointI] /= mag(normals[pointI]) + VSMALL;
}
}
}
void Foam::fieldSmoother::smoothLambdaMuDisplacement
(
const label nIter,
const PackedBoolList& isMeshMasterPoint,
const PackedBoolList& isMeshMasterEdge,
const PackedBoolList& isToBeSmoothed,
vectorField& displacement
) const
{
const edgeList& edges = mesh_.edges();
// Correspondence between local edges/points and mesh edges/points
const labelList meshPoints(identity(mesh_.nPoints()));
// Calculate inverse sum of weights
scalarField edgeWeights(mesh_.nEdges());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh_,
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
// Get smoothly varying patch field.
Info<< typeName << " : Smoothing displacement ..." << endl;
const scalar lambda = 0.33;
const scalar mu = -0.34;
vectorField average;
for (label iter = 0; iter < nIter; iter++)
{
meshRefinement::weightedSum
(
mesh_,
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
displacement,
average
);
average *= invSumWeight;
forAll(displacement, i)
{
if (isToBeSmoothed[i])
{
displacement[i] = (1-lambda)*displacement[i]+lambda*average[i];
}
}
meshRefinement::weightedSum
(
mesh_,
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
displacement,
average
);
average *= invSumWeight;
forAll(displacement, i)
{
if (isToBeSmoothed[i])
{
displacement[i] = (1-mu)*displacement[i]+mu*average[i];
}
}
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isMeshMasterPoint,
mag(displacement-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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::fieldSmoother
Description
Utility functions for mesh motion solvers
SourceFiles
fieldSmoother.C
\*---------------------------------------------------------------------------*/
#ifndef fieldSmoother_H
#define fieldSmoother_H
#include "meshRefinement.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fieldSmoother Declaration
\*---------------------------------------------------------------------------*/
class fieldSmoother
{
// Private data
//- Reference to the poly mesh
const polyMesh& mesh_;
// Private Member Functions
//- Disallow default bitwise copy construct
fieldSmoother(const fieldSmoother&);
//- Disallow default bitwise assignment
void operator=(const fieldSmoother&);
public:
// Run-time type information
TypeName("fieldSmoother");
// Constructors
//- Construct from a polyMesh
fieldSmoother(const polyMesh&);
//- Destructor
virtual ~fieldSmoother();
// Member Functions
//- Smooth interior normals
void smoothNormals
(
const label nIter,
const PackedBoolList& isMeshMasterPoint,
const PackedBoolList& isMeshMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const;
//- Smooth patch normals
void smoothPatchNormals
(
const label nIter,
const PackedBoolList& isPatchMasterPoint,
const PackedBoolList& isPatchMasterEdge,
const indirectPrimitivePatch& adaptPatch,
pointField& normals
) const;
//- Smooth a scalar field towards, but not beyond, a minimum value
template <class Type>
void minSmoothField
(
const label nIter,
const PackedBoolList& isPatchMasterPoint,
const PackedBoolList& isPatchMasterEdge,
const indirectPrimitivePatch& adaptPatch,
const scalarField& fieldMin,
Field<Type>& field
) const;
//- Smooth and then un-smooth a displacement
void smoothLambdaMuDisplacement
(
const label nIter,
const PackedBoolList& isMeshMasterPoint,
const PackedBoolList& isMeshMasterEdge,
const PackedBoolList& isSmoothable,
vectorField& displacement
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "fieldSmootherTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template <class Type>
void Foam::fieldSmoother::minSmoothField
(
const label nIter,
const PackedBoolList& isPatchMasterPoint,
const PackedBoolList& isPatchMasterEdge,
const indirectPrimitivePatch& adaptPatch,
const scalarField& fieldMinMag,
Field<Type>& field
) const
{
const edgeList& edges = adaptPatch.edges();
const labelList& meshPoints = adaptPatch.meshPoints();
scalarField edgeWeights(edges.size());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh_,
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
// Get smoothly varying patch field.
Info<< typeName << " : Smoothing field ..." << endl;
for (label iter = 0; iter < nIter; iter++)
{
Field<Type> average(adaptPatch.nPoints());
meshRefinement::weightedSum
(
mesh_,
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
field,
average
);
average *= invSumWeight;
// Transfer to field
forAll(field, pointI)
{
//full smoothing neighbours + point value
average[pointI] = 0.5*(field[pointI]+average[pointI]);
// perform monotonic smoothing
if
(
mag(average[pointI]) < mag(field[pointI])
&& mag(average[pointI]) >= mag(fieldMinMag[pointI])
)
{
field[pointI] = average[pointI];
}
}
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isPatchMasterPoint,
mag(field-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
}
}
// ************************************************************************* //

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) 2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 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.
@ -32,7 +32,7 @@ License
#include "unitConversion.H" #include "unitConversion.H"
#include "PatchTools.H" #include "PatchTools.H"
#include "OBJstream.H" #include "OBJstream.H"
#include "pointData.H" #include "PointData.H"
#include "zeroFixedValuePointPatchFields.H" #include "zeroFixedValuePointPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -52,241 +52,11 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelList Foam::medialAxisMeshMover::getFixedValueBCs
(
const pointVectorField& fld
)
{
DynamicList<label> adaptPatchIDs;
forAll(fld.boundaryField(), patchI)
{
const pointPatchField<vector>& patchFld =
fld.boundaryField()[patchI];
if (isA<valuePointPatchField<vector> >(patchFld))
{
if (isA<zeroFixedValuePointPatchField<vector> >(patchFld))
{
// Special condition of fixed boundary condition. Does not
// get adapted
}
else
{
adaptPatchIDs.append(patchI);
}
}
}
return adaptPatchIDs;
}
Foam::autoPtr<Foam::indirectPrimitivePatch>
Foam::medialAxisMeshMover::getPatch
(
const polyMesh& mesh,
const labelList& patchIDs
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Count faces.
label nFaces = 0;
forAll(patchIDs, i)
{
const polyPatch& pp = patches[patchIDs[i]];
nFaces += pp.size();
}
// Collect faces.
labelList addressing(nFaces);
nFaces = 0;
forAll(patchIDs, i)
{
const polyPatch& pp = patches[patchIDs[i]];
label meshFaceI = pp.start();
forAll(pp, i)
{
addressing[nFaces++] = meshFaceI++;
}
}
return autoPtr<indirectPrimitivePatch>
(
new indirectPrimitivePatch
(
IndirectList<face>(mesh.faces(), addressing),
mesh.points()
)
);
}
void Foam::medialAxisMeshMover::smoothPatchNormals
(
const label nSmoothDisp,
const PackedBoolList& isPatchMasterPoint,
const PackedBoolList& isPatchMasterEdge,
pointField& normals
) const
{
const indirectPrimitivePatch& pp = adaptPatchPtr_();
const edgeList& edges = pp.edges();
const labelList& meshPoints = pp.meshPoints();
// Get smoothly varying internal normals field.
Info<< typeName << " : Smoothing normals ..." << endl;
scalarField edgeWeights(edges.size());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh(),
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
vectorField average;
for (label iter = 0; iter < nSmoothDisp; iter++)
{
meshRefinement::weightedSum
(
mesh(),
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
normals,
average
);
average *= invSumWeight;
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isPatchMasterPoint,
mag(normals-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
// Transfer to normals vector field
forAll(average, pointI)
{
// full smoothing neighbours + point value
average[pointI] = 0.5*(normals[pointI]+average[pointI]);
normals[pointI] = average[pointI];
normals[pointI] /= mag(normals[pointI]) + VSMALL;
}
}
}
// Smooth normals in interior.
void Foam::medialAxisMeshMover::smoothNormals
(
const label nSmoothDisp,
const PackedBoolList& isMeshMasterPoint,
const PackedBoolList& isMeshMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const
{
// Get smoothly varying internal normals field.
Info<< typeName
<< " : Smoothing normals in interior ..." << endl;
const edgeList& edges = mesh().edges();
// Points that do not change.
PackedBoolList isFixedPoint(mesh().nPoints());
// Internal points that are fixed
forAll(fixedPoints, i)
{
label meshPointI = fixedPoints[i];
isFixedPoint.set(meshPointI, 1);
}
// Make sure that points that are coupled to meshPoints but not on a patch
// are fixed as well
syncTools::syncPointList(mesh(), isFixedPoint, maxEqOp<unsigned int>(), 0);
// Correspondence between local edges/points and mesh edges/points
const labelList meshPoints(identity(mesh().nPoints()));
// Calculate inverse sum of weights
scalarField edgeWeights(mesh().nEdges());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh(),
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
vectorField average;
for (label iter = 0; iter < nSmoothDisp; iter++)
{
meshRefinement::weightedSum
(
mesh(),
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
normals,
average
);
average *= invSumWeight;
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isMeshMasterPoint,
mag(normals-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
// Transfer to normals vector field
forAll(average, pointI)
{
if (isFixedPoint.get(pointI) == 0)
{
//full smoothing neighbours + point value
average[pointI] = 0.5*(normals[pointI]+average[pointI]);
normals[pointI] = average[pointI];
normals[pointI] /= mag(normals[pointI]) + VSMALL;
}
}
}
}
// Tries and find a medial axis point. Done by comparing vectors to nearest // Tries and find a medial axis point. Done by comparing vectors to nearest
// wall point for both vertices of edge. // wall point for both vertices of edge.
bool Foam::medialAxisMeshMover::isMaxEdge bool Foam::medialAxisMeshMover::isMaxEdge
( (
const List<pointData>& pointWallDist, const List<PointData<vector> >& pointWallDist,
const label edgeI, const label edgeI,
const scalar minCos const scalar minCos
) const ) const
@ -331,7 +101,7 @@ bool Foam::medialAxisMeshMover::isMaxEdge
//- Detect based on extrusion vector differing for both endpoints //- Detect based on extrusion vector differing for both endpoints
// the idea is that e.g. a sawtooth wall can still be extruded // the idea is that e.g. a sawtooth wall can still be extruded
// successfully as long as it is done all to the same direction. // successfully as long as it is done all to the same direction.
if ((pointWallDist[e[0]].v() & pointWallDist[e[1]].v()) < minCos) if ((pointWallDist[e[0]].data() & pointWallDist[e[1]].data()) < minCos)
{ {
return true; return true;
} }
@ -439,11 +209,12 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
pointField pointNormals(PatchTools::pointNormals(mesh(), pp)); pointField pointNormals(PatchTools::pointNormals(mesh(), pp));
// Smooth patch normal vectors // Smooth patch normal vectors
smoothPatchNormals fieldSmoother_.smoothPatchNormals
( (
nSmoothSurfaceNormals, nSmoothSurfaceNormals,
isPatchMasterPoint, isPatchMasterPoint,
isPatchMasterEdge, isPatchMasterEdge,
pp,
pointNormals pointNormals
); );
@ -452,7 +223,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Distance to wall // Distance to wall
List<pointData> pointWallDist(mesh().nPoints()); List<PointData<vector> > pointWallDist(mesh().nPoints());
// Dummy additional info for PointEdgeWave // Dummy additional info for PointEdgeWave
int dummyTrackData = 0; int dummyTrackData = 0;
@ -461,23 +232,22 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// 1. Calculate distance to points where displacement is specified. // 1. Calculate distance to points where displacement is specified.
{ {
// Seed data. // Seed data.
List<pointData> wallInfo(meshPoints.size()); List<PointData<vector> > wallInfo(meshPoints.size());
forAll(meshPoints, patchPointI) forAll(meshPoints, patchPointI)
{ {
label pointI = meshPoints[patchPointI]; label pointI = meshPoints[patchPointI];
wallInfo[patchPointI] = pointData wallInfo[patchPointI] = PointData<vector>
( (
points[pointI], points[pointI],
0.0, 0.0,
pointI, // passive scalar
pointNormals[patchPointI] // surface normals pointNormals[patchPointI] // surface normals
); );
} }
// Do all calculations // Do all calculations
List<pointData> edgeWallDist(mesh().nEdges()); List<PointData<vector> > edgeWallDist(mesh().nEdges());
PointEdgeWave<pointData> wallDistCalc PointEdgeWave<PointData<vector> > wallDistCalc
( (
mesh(), mesh(),
meshPoints, meshPoints,
@ -525,11 +295,11 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// 2. Find points with max distance and transport information back to // 2. Find points with max distance and transport information back to
// wall. // wall.
{ {
List<pointData> pointMedialDist(mesh().nPoints()); List<pointEdgePoint> pointMedialDist(mesh().nPoints());
List<pointData> edgeMedialDist(mesh().nEdges()); List<pointEdgePoint> edgeMedialDist(mesh().nEdges());
// Seed point data. // Seed point data.
DynamicList<pointData> maxInfo(meshPoints.size()); DynamicList<pointEdgePoint> maxInfo(meshPoints.size());
DynamicList<label> maxPoints(meshPoints.size()); DynamicList<label> maxPoints(meshPoints.size());
// 1. Medial axis points // 1. Medial axis points
@ -556,12 +326,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI); maxPoints.append(pointI);
maxInfo.append maxInfo.append
( (
pointData pointEdgePoint
( (
points[pointI], points[pointI],
0.0, 0.0
pointI, // passive data
vector::zero // passive data
) )
); );
pointMedialDist[pointI] = maxInfo.last(); pointMedialDist[pointI] = maxInfo.last();
@ -612,12 +380,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI); maxPoints.append(pointI);
maxInfo.append maxInfo.append
( (
pointData pointEdgePoint
( (
medialAxisPt, //points[pointI], medialAxisPt, //points[pointI],
magSqr(points[pointI]-medialAxisPt),//0.0, magSqr(points[pointI]-medialAxisPt)//0.0
pointI, // passive data
vector::zero // passive data
) )
); );
pointMedialDist[pointI] = maxInfo.last(); pointMedialDist[pointI] = maxInfo.last();
@ -669,12 +435,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI); maxPoints.append(pointI);
maxInfo.append maxInfo.append
( (
pointData pointEdgePoint
( (
points[pointI], points[pointI],
0.0, 0.0
pointI, // passive data
vector::zero // passive data
) )
); );
pointMedialDist[pointI] = maxInfo.last(); pointMedialDist[pointI] = maxInfo.last();
@ -715,7 +479,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// Check if angle not too large. // Check if angle not too large.
scalar cosAngle = scalar cosAngle =
( (
-pointWallDist[pointI].v() -pointWallDist[pointI].data()
& pointNormals[i] & pointNormals[i]
); );
if (cosAngle > slipFeatureAngleCos) if (cosAngle > slipFeatureAngleCos)
@ -726,12 +490,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI); maxPoints.append(pointI);
maxInfo.append maxInfo.append
( (
pointData pointEdgePoint
( (
points[pointI], points[pointI],
0.0, 0.0
pointI, // passive data
vector::zero // passive data
) )
); );
pointMedialDist[pointI] = maxInfo.last(); pointMedialDist[pointI] = maxInfo.last();
@ -751,7 +513,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.shrink(); maxPoints.shrink();
// Do all calculations // Do all calculations
PointEdgeWave<pointData> medialDistCalc PointEdgeWave<pointEdgePoint> medialDistCalc
( (
mesh(), mesh(),
maxPoints, maxPoints,
@ -794,12 +556,12 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
} }
else else
{ {
dispVec_[i] = pointWallDist[i].v(); dispVec_[i] = pointWallDist[i].data();
} }
} }
// Smooth normal vectors. Do not change normals on pp.meshPoints // Smooth normal vectors. Do not change normals on pp.meshPoints
smoothNormals fieldSmoother_.smoothNormals
( (
nSmoothNormals, nSmoothNormals,
isMeshMasterPoint, isMeshMasterPoint,
@ -1003,79 +765,6 @@ void Foam::medialAxisMeshMover::syncPatchDisplacement
} }
void Foam::medialAxisMeshMover::minSmoothField
(
const label nSmoothDisp,
const PackedBoolList& isPatchMasterPoint,
const PackedBoolList& isPatchMasterEdge,
const scalarField& fieldMin,
scalarField& field
) const
{
const indirectPrimitivePatch& pp = adaptPatchPtr_();
const edgeList& edges = pp.edges();
const labelList& meshPoints = pp.meshPoints();
scalarField edgeWeights(edges.size());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh(),
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
// Get smoothly varying patch field.
Info<< typeName << " : Smoothing field ..." << endl;
for (label iter = 0; iter < nSmoothDisp; iter++)
{
scalarField average(pp.nPoints());
meshRefinement::weightedSum
(
mesh(),
isPatchMasterEdge,
meshPoints,
edges,
edgeWeights,
field,
average
);
average *= invSumWeight;
// Transfer to field
forAll(field, pointI)
{
//full smoothing neighbours + point value
average[pointI] = 0.5*(field[pointI]+average[pointI]);
// perform monotonic smoothing
if
(
average[pointI] < field[pointI]
&& average[pointI] >= fieldMin[pointI]
)
{
field[pointI] = average[pointI];
}
}
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isPatchMasterPoint,
mag(field-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
}
}
// Stop layer growth where mesh wraps around edge with a // Stop layer growth where mesh wraps around edge with a
// large feature angle // large feature angle
void Foam::medialAxisMeshMover:: void Foam::medialAxisMeshMover::
@ -1204,7 +893,8 @@ handleFeatureAngleLayerTerminations
//Info<< "Added " //Info<< "Added "
// << returnReduce(nPointCounter-nOldPointCounter, sumOp<label>()) // << returnReduce(nPointCounter-nOldPointCounter, sumOp<label>())
// << " point not to extrude." << endl; // << " point not to extrude due to minCos "
// << minCos << endl;
} }
@ -1226,34 +916,30 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
const labelListList& pointFaces = pp.pointFaces(); const labelListList& pointFaces = pp.pointFaces();
const labelList& meshPoints = pp.meshPoints(); const labelList& meshPoints = pp.meshPoints();
Info<< typeName << " : Removing isolated regions ..." << endl;
Info<< typeName << " : Removing isolated regions ..." << nl
<< indent << "- if partially extruded faces make angle < "
<< Foam::radToDeg(Foam::acos(minCosLayerTermination)) << nl;
if (detectExtrusionIsland)
{
Info<< indent << "- if exclusively surrounded by non-extruded points"
<< nl;
}
else
{
Info<< indent << "- if exclusively surrounded by non-extruded faces"
<< nl;
}
// Keep count of number of points unextruded // Keep count of number of points unextruded
label nPointCounter = 0; label nPointCounter = 0;
autoPtr<OBJstream> str;
if (debug)
{
str.reset
(
new OBJstream
(
mesh().time().path()
/ "islandExcludePoints_"
+ mesh().time().timeName()
+ ".obj"
)
);
Info<< typeName
<< " : Writing points surrounded by non-extruded points to "
<< str().name() << endl;
}
while (true) while (true)
{ {
// Stop layer growth where mesh wraps around edge with a // Stop layer growth where mesh wraps around edge with a
// large feature angle // large feature angle
if (minCosLayerTermination > -1)
{
handleFeatureAngleLayerTerminations handleFeatureAngleLayerTerminations
( (
minCosLayerTermination, minCosLayerTermination,
@ -1266,7 +952,7 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
); );
syncPatchDisplacement(minThickness, patchDisp, extrudeStatus); syncPatchDisplacement(minThickness, patchDisp, extrudeStatus);
}
// Detect either: // Detect either:
@ -1389,11 +1075,6 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
{ {
nPointCounter++; nPointCounter++;
nChanged++; nChanged++;
if (str.valid())
{
str().write(pp.points()[meshPoints[patchPointI]]);
}
} }
} }
} }
@ -1483,11 +1164,6 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
) )
{ {
nPointCounter++; nPointCounter++;
if (str.valid())
{
str().write(pp.points()[meshPoints[f[fp]]]);
}
} }
} }
} }
@ -1501,98 +1177,6 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
} }
void Foam::medialAxisMeshMover::smoothLambdaMuDisplacement
(
const label nSmoothDisp,
const PackedBoolList& isMeshMasterPoint,
const PackedBoolList& isMeshMasterEdge,
vectorField& displacement
) const
{
const edgeList& edges = mesh().edges();
// Correspondence between local edges/points and mesh edges/points
const labelList meshPoints(identity(mesh().nPoints()));
// Calculate inverse sum of weights
scalarField edgeWeights(mesh().nEdges());
scalarField invSumWeight(meshPoints.size());
meshRefinement::calculateEdgeWeights
(
mesh(),
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
invSumWeight
);
// Get smoothly varying patch field.
Info<< typeName << " : Smoothing displacement ..." << endl;
const scalar lambda = 0.33;
const scalar mu = -0.34;
vectorField average;
for (label iter = 0; iter < nSmoothDisp; iter++)
{
meshRefinement::weightedSum
(
mesh(),
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
displacement,
average
);
average *= invSumWeight;
forAll(displacement, i)
{
if (medialRatio_[i] > SMALL && medialRatio_[i] < 1-SMALL)
{
displacement[i] = (1-lambda)*displacement[i]+lambda*average[i];
}
}
meshRefinement::weightedSum
(
mesh(),
isMeshMasterEdge,
meshPoints,
edges,
edgeWeights,
displacement,
average
);
average *= invSumWeight;
forAll(displacement, i)
{
if (medialRatio_[i] > SMALL && medialRatio_[i] < 1-SMALL)
{
displacement[i] = (1-mu)*displacement[i]+mu*average[i];
}
}
// Do residual calculation every so often.
if ((iter % 10) == 0)
{
scalar resid = meshRefinement::gAverage
(
isMeshMasterPoint,
mag(displacement-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::medialAxisMeshMover::medialAxisMeshMover Foam::medialAxisMeshMover::medialAxisMeshMover
@ -1630,6 +1214,7 @@ Foam::medialAxisMeshMover::medialAxisMeshMover
adaptPatchIDs_, adaptPatchIDs_,
dict dict
), ),
fieldSmoother_(mesh()),
dispVec_ dispVec_
( (
IOobject IOobject
@ -1733,10 +1318,12 @@ void Foam::medialAxisMeshMover::calculateDisplacement
const scalar featureAngle = readScalar(coeffDict.lookup("featureAngle")); const scalar featureAngle = readScalar(coeffDict.lookup("featureAngle"));
//- Stop layer growth where mesh wraps around sharp edge //- Stop layer growth where mesh wraps around sharp edge
const scalar minCosLayerTermination = Foam::cos scalar layerTerminationAngle = coeffDict.lookupOrDefault<scalar>
( (
degToRad(0.5*featureAngle) "layerTerminationAngle",
0.5*featureAngle
); );
scalar minCosLayerTermination = Foam::cos(degToRad(layerTerminationAngle));
//- Smoothing wanted patch thickness //- Smoothing wanted patch thickness
const label nSmoothPatchThickness = readLabel const label nSmoothPatchThickness = readLabel
@ -1791,9 +1378,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
); );
scalarField thickness(patchDisp.size()); scalarField thickness(mag(patchDisp));
thickness = mag(patchDisp);
forAll(thickness, patchPointI) forAll(thickness, patchPointI)
{ {
@ -1860,7 +1445,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
vector n = vector n =
patchDisp[patchPointI] patchDisp[patchPointI]
/ (mag(patchDisp[patchPointI]) + VSMALL); / (mag(patchDisp[patchPointI]) + VSMALL);
vector mVec = mesh().points()[pointI]-medialVec_[pointI]; vector mVec = medialVec_[pointI]-mesh().points()[pointI];
mVec /= mag(mVec)+VSMALL; mVec /= mag(mVec)+VSMALL;
thicknessRatio *= (n&mVec); thicknessRatio *= (n&mVec);
@ -1947,14 +1532,17 @@ void Foam::medialAxisMeshMover::calculateDisplacement
} }
// smooth layer thickness on moving patch // Smooth layer thickness on moving patch. Since some locations will have
minSmoothField // disabled the extrusion this might cause big jumps in wanted displacement
// for neighbouring patch points. So smooth the wanted displacement
// before actually trying to move the mesh.
fieldSmoother_.minSmoothField
( (
nSmoothPatchThickness, nSmoothPatchThickness,
isPatchMasterPoint, isPatchMasterPoint,
isPatchMasterEdge, isPatchMasterEdge,
pp,
minThickness, minThickness,
thickness thickness
); );
@ -1962,34 +1550,33 @@ void Foam::medialAxisMeshMover::calculateDisplacement
// Dummy additional info for PointEdgeWave // Dummy additional info for PointEdgeWave
int dummyTrackData = 0; int dummyTrackData = 0;
List<pointData> pointWallDist(mesh().nPoints()); List<PointData<scalar> > pointWallDist(mesh().nPoints());
const pointField& points = mesh().points(); const pointField& points = mesh().points();
// 1. Calculate distance to points where displacement is specified. // 1. Calculate distance to points where displacement is specified.
// This wave is used to transport layer thickness // This wave is used to transport layer thickness
{ {
// Distance to wall and medial axis on edges. // Distance to wall and medial axis on edges.
List<pointData> edgeWallDist(mesh().nEdges()); List<PointData<scalar> > edgeWallDist(mesh().nEdges());
labelList wallPoints(meshPoints.size()); labelList wallPoints(meshPoints.size());
// Seed data. // Seed data.
List<pointData> wallInfo(meshPoints.size()); List<PointData<scalar> > wallInfo(meshPoints.size());
forAll(meshPoints, patchPointI) forAll(meshPoints, patchPointI)
{ {
label pointI = meshPoints[patchPointI]; label pointI = meshPoints[patchPointI];
wallPoints[patchPointI] = pointI; wallPoints[patchPointI] = pointI;
wallInfo[patchPointI] = pointData wallInfo[patchPointI] = PointData<scalar>
( (
points[pointI], points[pointI],
0.0, 0.0,
thickness[patchPointI], // transport layer thickness thickness[patchPointI] // transport layer thickness
vector::zero // passive vector
); );
} }
// Do all calculations // Do all calculations
PointEdgeWave<pointData> wallDistCalc PointEdgeWave<PointData<scalar> > wallDistCalc
( (
mesh(), mesh(),
wallPoints, wallPoints,
@ -2016,12 +1603,12 @@ void Foam::medialAxisMeshMover::calculateDisplacement
{ {
// 1) displacement on nearest wall point, scaled by medialRatio // 1) displacement on nearest wall point, scaled by medialRatio
// (wall distance / medial distance) // (wall distance / medial distance)
// 2) pointWallDist[pointI].s() is layer thickness transported // 2) pointWallDist[pointI].data() is layer thickness transported
// from closest wall point. // from closest wall point.
// 3) shrink in opposite direction of addedPoints // 3) shrink in opposite direction of addedPoints
displacement[pointI] = displacement[pointI] =
-medialRatio_[pointI] -medialRatio_[pointI]
*pointWallDist[pointI].s() *pointWallDist[pointI].data()
*dispVec_[pointI]; *dispVec_[pointI];
} }
} }
@ -2030,11 +1617,20 @@ void Foam::medialAxisMeshMover::calculateDisplacement
// Smear displacement away from fixed values (medialRatio=0 or 1) // Smear displacement away from fixed values (medialRatio=0 or 1)
if (nSmoothDisplacement > 0) if (nSmoothDisplacement > 0)
{ {
smoothLambdaMuDisplacement PackedBoolList isToBeSmoothed(displacement.size(), false);
forAll(displacement, i)
{
isToBeSmoothed[i] =
medialRatio_[i] > SMALL && medialRatio_[i] < 1-SMALL;
}
fieldSmoother_.smoothLambdaMuDisplacement
( (
nSmoothDisplacement, nSmoothDisplacement,
isMeshMasterPoint, isMeshMasterPoint,
isMeshMasterEdge, isMeshMasterEdge,
isToBeSmoothed,
displacement displacement
); );
} }
@ -2052,8 +1648,6 @@ bool Foam::medialAxisMeshMover::shrinkMesh
const label nSnap = readLabel(meshQualityDict.lookup("nRelaxIter")); const label nSnap = readLabel(meshQualityDict.lookup("nRelaxIter"));
// Make sure displacement boundary conditions is uptodate with // Make sure displacement boundary conditions is uptodate with
// internal field // internal field
meshMover_.setDisplacementPatchFields(); meshMover_.setDisplacementPatchFields();
@ -2119,14 +1713,6 @@ bool Foam::medialAxisMeshMover::move
const word minThicknessName = word(moveDict.lookup("minThicknessName")); const word minThicknessName = word(moveDict.lookup("minThicknessName"));
// The points have moved so before calculation update
// the mesh and motionSolver accordingly
movePoints(mesh().points());
//
//// Update any point motion bcs (e.g. timevarying)
//pointDisplacement_.boundaryField().updateCoeffs();
// Extract out patch-wise displacement // Extract out patch-wise displacement
const indirectPrimitivePatch& pp = adaptPatchPtr_(); const indirectPrimitivePatch& pp = adaptPatchPtr_();
@ -2180,13 +1766,10 @@ void Foam::medialAxisMeshMover::movePoints(const pointField& p)
{ {
externalDisplacementMeshMover::movePoints(p); externalDisplacementMeshMover::movePoints(p);
// Update local data for new geometry // Update motionSmoother for new geometry (moves adaptPatchPtr_)
adaptPatchPtr_().movePoints(p);
// Update motionSmoother for new geometry
meshMover_.movePoints(); meshMover_.movePoints();
// Assume corrent mesh location is correct // Assume corrent mesh location is correct (reset oldPoints, scale)
meshMover_.correct(); meshMover_.correct();
} }

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) 2014-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2014-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.
@ -28,10 +28,13 @@ Description
Mesh motion solver that uses a medial axis algorithm to work Mesh motion solver that uses a medial axis algorithm to work
out a fraction between the (nearest point on a) moving surface out a fraction between the (nearest point on a) moving surface
and the (nearest point on a) fixed surface. and the (nearest point on a) fixed surface.
This fraction is then used to scale the motion. Use This fraction is then used to scale the motion. Use
- fixedValue on all moving patches - fixedValue on all moving patches
- zeroFixedValue on stationary patches - zeroFixedValue on stationary patches
- slip on all slipping patches - slip on all slipping patches
Note that the fixedValue boundary conditions might be changed by this
solver to enforce consistency and a valid resulting mesh.
SourceFiles SourceFiles
medialAxisMeshMover.C medialAxisMeshMover.C
@ -44,13 +47,15 @@ SourceFiles
#include "externalDisplacementMeshMover.H" #include "externalDisplacementMeshMover.H"
#include "motionSmootherAlgo.H" #include "motionSmootherAlgo.H"
#include "autoLayerDriver.H" #include "autoLayerDriver.H"
#include "fieldSmoother.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
class pointData; template <class DataType>
class PointData;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class medialAxisMeshMover Declaration Class medialAxisMeshMover Declaration
@ -75,6 +80,9 @@ class medialAxisMeshMover
//- Mesh mover algorithm //- Mesh mover algorithm
motionSmootherAlgo meshMover_; motionSmootherAlgo meshMover_;
//- Field smoothing
fieldSmoother fieldSmoother_;
// Pre-calculated medial axis information // Pre-calculated medial axis information
@ -95,45 +103,16 @@ class medialAxisMeshMover
// Private Member Functions // Private Member Functions
//- Extract fixed-value patchfields
static labelList getFixedValueBCs(const pointVectorField&);
//- Extract bc types. Replace fixedValue derivatives with fixedValue //- Extract bc types. Replace fixedValue derivatives with fixedValue
wordList getPatchFieldTypes(const pointVectorField& fld); wordList getPatchFieldTypes(const pointVectorField& fld);
//- Construct patch on selected patches
static autoPtr<indirectPrimitivePatch> getPatch
(
const polyMesh&,
const labelList&
);
// Calculation of medial axis information // Calculation of medial axis information
//- Smooth normals on patch
void smoothPatchNormals
(
const label nSmoothDisp,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge,
pointField& normals
) const;
//- Smooth normals on interior
void smoothNormals
(
const label nSmoothDisp,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const;
//- Is mesh edge on a cusp of displacement //- Is mesh edge on a cusp of displacement
bool isMaxEdge bool isMaxEdge
( (
const List<pointData>& pointWallDist, const List<PointData<vector> >& pointWallDist,
const label edgeI, const label edgeI,
const scalar minCos const scalar minCos
) const; ) const;
@ -161,23 +140,6 @@ class medialAxisMeshMover
List<autoLayerDriver::extrudeMode>& extrudeStatus List<autoLayerDriver::extrudeMode>& extrudeStatus
) const; ) const;
void smoothLambdaMuDisplacement
(
const label nSmoothDisp,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge,
vectorField& displacement
) const;
void minSmoothField
(
const label nSmoothDisp,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge,
const scalarField& fieldMin,
scalarField& field
) const;
//- Stop layer growth at feature edges //- Stop layer growth at feature edges
void handleFeatureAngleLayerTerminations void handleFeatureAngleLayerTerminations
( (

File diff suppressed because it is too large Load Diff

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.
@ -51,6 +51,8 @@ SourceFiles
#include "pointFieldsFwd.H" #include "pointFieldsFwd.H"
#include "Tuple2.H" #include "Tuple2.H"
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "wordPairHashTable.H"
#include "surfaceZonesInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -66,14 +68,11 @@ class refinementFeatures;
class shellSurfaces; class shellSurfaces;
class removeCells; class removeCells;
class fvMeshDistribute; class fvMeshDistribute;
class searchableSurface;
class regionSplit;
class globalIndex;
class removePoints; class removePoints;
class localPointRegion; class localPointRegion;
class snapParameters; class snapParameters;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class meshRefinement Declaration Class meshRefinement Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -183,6 +182,14 @@ private:
//- Per cc-cc vector the index of the surface hit //- Per cc-cc vector the index of the surface hit
labelIOList surfaceIndex_; labelIOList surfaceIndex_;
// For baffle merging
//- Original patch for baffle faces that used to be on
// coupled patches
Map<label> faceToCoupledPatch_;
//- User supplied face based data. //- User supplied face based data.
List<Tuple2<mapType, labelList> > userFaceData_; List<Tuple2<mapType, labelList> > userFaceData_;
@ -190,6 +197,15 @@ private:
// order changes. // order changes.
wordList meshedPatches_; wordList meshedPatches_;
//- FaceZone to master patch name
HashTable<word, word> faceZoneToMasterPatch_;
//- FaceZone to slave patch name
HashTable<word, word> faceZoneToSlavePatch_;
//- FaceZone to method to handle faces
HashTable<surfaceZonesInfo::faceZoneType, word> faceZoneToType_;
// Private Member Functions // Private Member Functions
@ -216,9 +232,6 @@ private:
pointField& neiCc pointField& neiCc
) const; ) const;
//- Find any intersection of surface. Store in surfaceIndex_.
void updateIntersections(const labelList& changedFaces);
//- Remove cells. Put exposedFaces into exposedPatchIDs. //- Remove cells. Put exposedFaces into exposedPatchIDs.
autoPtr<mapPolyMesh> doRemoveCells autoPtr<mapPolyMesh> doRemoveCells
( (
@ -369,10 +382,25 @@ private:
const labelList& globalToSlavePatch const labelList& globalToSlavePatch
) const; ) const;
//- Calculate intersections. Return per face -1 or the global
// surface region
void getIntersections
(
const labelList& surfacesToTest,
const pointField& neiCc,
const labelList& testFaces,
labelList& globalRegion1,
labelList& globalRegion2
) const;
//- Determine patches for baffles //- Determine patches for baffles
void getBafflePatches void getBafflePatches
( (
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const labelList& neiLevel, const labelList& neiLevel,
const pointField& neiCc, const pointField& neiCc,
labelList& ownPatch, labelList& ownPatch,
@ -454,7 +482,9 @@ private:
labelList markFacesOnProblemCellsGeometric labelList markFacesOnProblemCellsGeometric
( (
const snapParameters& snapParams, const snapParameters& snapParams,
const dictionary& motionDict const dictionary& motionDict,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch
) const; ) const;
@ -494,6 +524,16 @@ private:
labelList& cellToZone labelList& cellToZone
) const; ) const;
//- Finds zone per cell for cells inside region for which name
// is specified.
void findCellZoneInsideWalk
(
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const labelList& blockedFace, // per face -1 or some index >= 0
labelList& cellToZone
) const;
//- Determines cell zone from cell region information. //- Determines cell zone from cell region information.
bool calcRegionToZone bool calcRegionToZone
( (
@ -508,7 +548,7 @@ private:
// marked in namedSurfaceIndex regarded as blocked. // marked in namedSurfaceIndex regarded as blocked.
void findCellZoneTopo void findCellZoneTopo
( (
const point& keepPoint, const pointField& locationsInMesh,
const labelList& namedSurfaceIndex, const labelList& namedSurfaceIndex,
const labelList& surfaceToCellZone, const labelList& surfaceToCellZone,
labelList& cellToZone labelList& cellToZone
@ -520,6 +560,26 @@ private:
labelList& namedSurfaceIndex labelList& namedSurfaceIndex
) const; ) const;
//- Put cells into cellZone, faces into faceZone
void zonify
(
const PackedBoolList& isMasterFace,
const labelList& cellToZone,
const labelList& neiCellZone,
const labelList& faceToZone,
const boolList& meshFlipMap,
polyTopoChange& meshMod
) const;
//- Allocate faceZoneName
void allocateInterRegionFaceZone
(
const label ownZone,
const label neiZone,
wordPairHashTable& zonesToFaceZone,
HashTable<word, labelPair, labelPair::Hash<> >&
) const;
//- Remove any loose standing cells //- Remove any loose standing cells
void handleSnapProblems void handleSnapProblems
( (
@ -667,6 +727,13 @@ public:
return surfaceIndex_; return surfaceIndex_;
} }
//- For faces originating from processor faces store the original
// patch
const Map<label>& faceToCoupledPatch() const
{
return faceToCoupledPatch_;
}
//- Additional face data that is maintained across //- Additional face data that is maintained across
// topo changes. Every entry is a list over all faces. // topo changes. Every entry is a list over all faces.
// Bit of a hack. Additional flag to say whether to maintain master // Bit of a hack. Additional flag to say whether to maintain master
@ -829,16 +896,29 @@ public:
const bool useTopologicalSnapDetection, const bool useTopologicalSnapDetection,
const bool removeEdgeConnectedCells, const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle, const scalarField& perpendicularAngle,
// How to handle free-standing baffles
const bool mergeFreeStanding,
const scalar freeStandingAngle,
const dictionary& motionDict, const dictionary& motionDict,
Time& runTime, Time& runTime,
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch, const labelList& globalToSlavePatch,
const point& keepPoint const pointField& locationsInMesh,
const wordList& regionsInMesh,
const pointField& locationsOutsideMesh
);
//- Merge free-standing baffles
void mergeFreeStandingBaffles
(
const snapParameters& snapParams,
const bool useTopologicalSnapDetection,
const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle,
const scalar planarAngle,
const dictionary& motionDict,
Time& runTime,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch,
const pointField& locationsInMesh,
const pointField& locationsOutsideMesh
); );
//- Split off (with optional buffer layers) unreachable areas //- Split off (with optional buffer layers) unreachable areas
@ -848,7 +928,10 @@ public:
const label nBufferLayers, const label nBufferLayers,
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch, const labelList& globalToSlavePatch,
const point& keepPoint
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const pointField& locationsOutsideMesh
); );
//- Find boundary points that connect to more than one cell //- Find boundary points that connect to more than one cell
@ -859,6 +942,16 @@ public:
// region and split them. // region and split them.
autoPtr<mapPolyMesh> dupNonManifoldPoints(); autoPtr<mapPolyMesh> dupNonManifoldPoints();
//- Find boundary points that are on faceZones of type boundary
// and duplicate them
autoPtr<mapPolyMesh> dupNonManifoldBoundaryPoints();
//- Merge duplicate points
autoPtr<mapPolyMesh> mergePoints
(
const labelList& pointToDuplicate
);
//- Create baffle for every internal face where ownPatch != -1. //- Create baffle for every internal face where ownPatch != -1.
// External faces get repatched according to ownPatch (neiPatch // External faces get repatched according to ownPatch (neiPatch
// should be -1 for these) // should be -1 for these)
@ -868,28 +961,55 @@ public:
const labelList& neiPatch const labelList& neiPatch
); );
//- Debug helper: check faceZones are not on processor patches //- Get zones of given type
void checkZoneFaces() const; labelList getZones
//- Create baffles for faces straddling zoned surfaces. Return
// baffles.
autoPtr<mapPolyMesh> createZoneBaffles
( (
const labelList& globalToMasterPatch, const List<surfaceZonesInfo::faceZoneType>& fzTypes
const labelList& globalToSlavePatch, ) const;
List<labelPair>&
//- Subset baffles according to zones
static List<labelPair> subsetBaffles
(
const polyMesh& mesh,
const labelList& zoneIDs,
const List<labelPair>& baffles
); );
//- Merge baffles. Gets pairs of faces. //- Create baffles for faces on faceZones. Return created baffles
autoPtr<mapPolyMesh> mergeBaffles(const List<labelPair>&); // (= pairs of faces) and corresponding faceZone
autoPtr<mapPolyMesh> createZoneBaffles
(
const labelList& zoneIDs,
List<labelPair>& baffles,
labelList& originatingFaceZone
);
//- Merge baffles. Gets pairs of faces and boundary faces to move
// onto (coupled) patches
autoPtr<mapPolyMesh> mergeBaffles
(
const List<labelPair>&,
const Map<label>& faceToPatch
);
//- Merge all baffles on faceZones
autoPtr<mapPolyMesh> mergeZoneBaffles
(
const bool doInternalZones,
const bool doBaffleZones
);
//- Put faces/cells into zones according to surface specification. //- Put faces/cells into zones according to surface specification.
// Returns null if no zone surfaces present. Region containing // Returns null if no zone surfaces present. Regions containing
// the keepPoint will not be put into a cellZone. // locationsInMesh/regionsInMesh will be put in corresponding
// cellZone. keepPoints is for backwards compatibility and sets
// all yet unassigned cells to be non-zoned (zone = -1)
autoPtr<mapPolyMesh> zonify autoPtr<mapPolyMesh> zonify
( (
const point& keepPoint, const bool allowFreeStandingZoneFaces,
const bool allowFreeStandingZoneFaces const pointField& locationsInMesh,
const wordList& regionsInMesh,
wordPairHashTable& zonesToFaceZone
); );
@ -914,9 +1034,32 @@ public:
//- Get patchIDs for patches added in addMeshedPatch. //- Get patchIDs for patches added in addMeshedPatch.
labelList meshedPatches() const; labelList meshedPatches() const;
//- Add/lookup faceZone and update information. Return index of
// faceZone
label addFaceZone
(
const word& fzName,
const word& masterPatch,
const word& slavePatch,
const surfaceZonesInfo::faceZoneType& fzType
);
//- Lookup faceZone information. Return false if no information
// for faceZone
bool getFaceZoneInfo
(
const word& fzName,
label& masterPatchID,
label& slavePatchID,
surfaceZonesInfo::faceZoneType& fzType
) const;
//- Select coupled faces that are not collocated //- Select coupled faces that are not collocated
void selectSeparatedCoupledFaces(boolList&) const; void selectSeparatedCoupledFaces(boolList&) const;
//- Find any intersection of surface. Store in surfaceIndex_.
void updateIntersections(const labelList& changedFaces);
//- Find region point is in. Uses optional perturbation to re-test. //- Find region point is in. Uses optional perturbation to re-test.
static label findRegion static label findRegion
( (
@ -926,19 +1069,44 @@ public:
const point& p const point& p
); );
//- Split mesh. Keep part containing point. static void findRegions
(
const polyMesh&,
const vector& perturbVec,
const pointField& locationsInMesh,
const pointField& locationsOutsideMesh,
const label nRegions,
labelList& cellRegion
);
//- Split mesh. Keep part containing point. Return empty map if
// no cells removed.
autoPtr<mapPolyMesh> splitMeshRegions autoPtr<mapPolyMesh> splitMeshRegions
( (
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch, const labelList& globalToSlavePatch,
const point& keepPoint const pointField& locationsInMesh,
const pointField& locationsOutsideMesh
); );
//- Split faces into two //- Split faces into two
autoPtr<mapPolyMesh> splitFaces void doSplitFaces
( (
const labelList& splitFaces, const labelList& splitFaces,
const labelPairList& splits const labelPairList& splits,
polyTopoChange& meshMod
) const;
//- Split faces along diagonal. Maintain mesh quality. Return
// total number of faces split.
label splitFacesUndo
(
const labelList& splitFaces,
const labelPairList& splits,
const dictionary& motionDict,
labelList& duplicateFace,
List<labelPair>& baffles
); );
//- Update local numbering for mesh redistribution //- Update local numbering for mesh redistribution
@ -986,6 +1154,16 @@ public:
// Merging coplanar faces and edges // Merging coplanar faces and edges
//- Merge coplanar faces if sets are of size mergeSize
// (usually 4)
label mergePatchFaces
(
const scalar minCos,
const scalar concaveCos,
const label mergeSize,
const labelList& patchIDs
);
//- Merge coplanar faces. preserveFaces is != -1 for faces //- Merge coplanar faces. preserveFaces is != -1 for faces
// to be preserved // to be preserved
label mergePatchFacesUndo label mergePatchFacesUndo

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.
@ -34,110 +34,115 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//// Merge faces that are in-line. // Merge faces that are in-line.
//Foam::label Foam::meshRefinement::mergePatchFaces Foam::label Foam::meshRefinement::mergePatchFaces
//( (
// const scalar minCos, const scalar minCos,
// const scalar concaveCos, const scalar concaveCos,
// const labelList& patchIDs const label mergeSize,
//) const labelList& patchIDs
//{ )
// // Patch face merging engine {
// combineFaces faceCombiner(mesh_); // Patch face merging engine
// combineFaces faceCombiner(mesh_, false);
// const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// // Pick up all candidate cells on boundary
// labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces()); // Pick up all candidate cells on boundary
// labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
// forAll(patchIDs, i)
// { forAll(patchIDs, i)
// label patchI = patchIDs[i]; {
// label patchI = patchIDs[i];
// const polyPatch& patch = patches[patchI];
// const polyPatch& patch = patches[patchI];
// if (!patch.coupled())
// { if (!patch.coupled())
// forAll(patch, i) {
// { forAll(patch, i)
// boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]); {
// } boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]);
// } }
// } }
// }
// // Get all sets of faces that can be merged
// labelListList mergeSets // Get all sets of faces that can be merged
// ( labelListList mergeSets
// faceCombiner.getMergeSets (
// ( faceCombiner.getMergeSets
// minCos, (
// concaveCos, minCos,
// boundaryCells concaveCos,
// ) boundaryCells
// ); )
// );
// label nFaceSets = returnReduce(mergeSets.size(), sumOp<label>());
// if (mergeSize != -1)
// Info<< "mergePatchFaces : Merging " << nFaceSets {
// << " sets of faces." << endl; // Keep only those that are mergeSize faces
// label compactI = 0;
// if (nFaceSets > 0) forAll(mergeSets, setI)
// { {
// // Topology changes container if (mergeSets[setI].size() == mergeSize)
// polyTopoChange meshMod(mesh_); {
// mergeSets[compactI++] = mergeSets[setI];
// // Merge all faces of a set into the first face of the set. Remove }
// // unused points. }
// faceCombiner.setRefinement(mergeSets, meshMod); mergeSets.setSize(compactI);
// }
// // Change the mesh (no inflation)
// autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, true);
// label nFaceSets = returnReduce(mergeSets.size(), sumOp<label>());
// // Update fields
// mesh_.updateMesh(map); Info<< "Merging " << nFaceSets << " sets of faces." << nl << endl;
//
// // Move mesh (since morphing does not do this) if (nFaceSets > 0)
// if (map().hasMotionPoints()) {
// { // Topology changes container
// mesh_.movePoints(map().preMotionPoints()); polyTopoChange meshMod(mesh_);
// }
// else // Merge all faces of a set into the first face of the set. Remove
// { // unused points.
// // Delete mesh volumes. No other way to do this? faceCombiner.setRefinement(mergeSets, meshMod);
// mesh_.clearOut();
// } // Change the mesh (no inflation)
// autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, true);
//
// // Reset the instance for if in overwrite mode // Update fields
// mesh_.setInstance(timeName()); mesh_.updateMesh(map);
//
// faceCombiner.updateMesh(map); // Move mesh (since morphing does not do this)
// if (map().hasMotionPoints())
// // Get the kept faces that need to be recalculated. {
// // Merging two boundary faces might shift the cell centre mesh_.movePoints(map().preMotionPoints());
// // (unless the faces are absolutely planar) }
// labelHashSet retestFaces(6*mergeSets.size()); else
// {
// forAll(mergeSets, setI) // Delete mesh volumes. No other way to do this?
// { mesh_.clearOut();
// label oldMasterI = mergeSets[setI][0]; }
//
// label faceI = map().reverseFaceMap()[oldMasterI]; // Reset the instance for if in overwrite mode
// mesh_.setInstance(timeName());
// // faceI is always uncoupled boundary face
// const cell& cFaces = mesh_.cells()[mesh_.faceOwner()[faceI]]; faceCombiner.updateMesh(map);
//
// forAll(cFaces, i) // Get the kept faces that need to be recalculated.
// { // Merging two boundary faces might shift the cell centre
// retestFaces.insert(cFaces[i]); // (unless the faces are absolutely planar)
// } labelHashSet retestFaces(2*mergeSets.size());
// }
// updateMesh(map, retestFaces.toc()); forAll(mergeSets, setI)
// } {
// label oldMasterI = mergeSets[setI][0];
// retestFaces.insert(map().reverseFaceMap()[oldMasterI]);
// return nFaceSets; }
//} updateMesh(map, growFaceCellFace(retestFaces));
}
return nFaceSets;
}
// //
// //
//// Remove points not used by any face or points used by only two faces where //// Remove points not used by any face or points used by only two faces where

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-2014 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.
@ -1085,7 +1085,9 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
( (
const snapParameters& snapParams, const snapParameters& snapParams,
const dictionary& motionDict const dictionary& motionDict,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch
) const ) const
{ {
pointField oldPoints(mesh_.points()); pointField oldPoints(mesh_.points());
@ -1162,7 +1164,10 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
( (
autoSnapDriver::calcNearestSurface autoSnapDriver::calcNearestSurface
( (
snapParams.strictRegionSnap(),
*this, *this,
globalToMasterPatch,
globalToSlavePatch,
snapDist, // attraction snapDist, // attraction
pp, pp,
nearestPoint, nearestPoint,

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.
@ -980,6 +980,7 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
labelList surfaceMinLevel; labelList surfaceMinLevel;
surfaces_.findHigherIntersection surfaces_.findHigherIntersection
( (
shells_,
start, start,
end, end,
minLevel, minLevel,

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-2014 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.
@ -33,6 +33,91 @@ License
#include "UPtrList.H" #include "UPtrList.H"
#include "volumeType.H" #include "volumeType.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelList Foam::refinementSurfaces::findHigherLevel
(
const searchableSurface& geom,
const shellSurfaces& shells,
const List<pointIndexHit>& intersectionInfo,
const labelList& surfaceLevel // current level
) const
{
// See if a cached level field available
labelList minLevelField;
geom.getField(intersectionInfo, minLevelField);
// Detect any uncached values and do proper search
labelList localLevel(surfaceLevel);
{
// Check hits:
// 1. cached value == -1 : store for re-testing
// 2. cached value != -1 : use
// 3. uncached : use region 0 value
DynamicList<label> retestSet;
label nHits = 0;
forAll(intersectionInfo, i)
{
if (intersectionInfo[i].hit())
{
nHits++;
// Check if minLevelField for this surface.
if (minLevelField.size())
{
if (minLevelField[i] == -1)
{
retestSet.append(i);
}
else
{
localLevel[i] = max(localLevel[i], minLevelField[i]);
}
}
else
{
retestSet.append(i);
}
}
}
label nRetest = returnReduce(retestSet.size(), sumOp<label>());
if (nRetest > 0)
{
reduce(nHits, sumOp<label>());
//Info<< "Retesting " << nRetest
// << " out of " << nHits
// << " intersections on uncached elements on geometry "
// << geom.name() << endl;
pointField samples(retestSet.size());
forAll(retestSet, i)
{
samples[i] = intersectionInfo[retestSet[i]].hitPoint();
}
labelList shellLevel;
shells.findHigherLevel
(
samples,
UIndirectList<label>(surfaceLevel, retestSet)(),
shellLevel
);
forAll(retestSet, i)
{
label sampleI = retestSet[i];
localLevel[sampleI] = max(localLevel[sampleI], shellLevel[i]);
}
}
}
return localLevel;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::refinementSurfaces::refinementSurfaces Foam::refinementSurfaces::refinementSurfaces
@ -408,19 +493,19 @@ void Foam::refinementSurfaces::setMinLevelFields
{ {
const searchableSurface& geom = allGeometry_[surfaces_[surfI]]; const searchableSurface& geom = allGeometry_[surfaces_[surfI]];
// Precalculation only makes sense if there are different regions // Cache the refinement level (max of surface level and shell level)
// (so different refinement levels possible) and there are some // on a per-element basis. Only makes sense if there are lots of
// elements. Possibly should have 'enough' elements to have fine // elements. Possibly should have 'enough' elements to have fine
// enough resolution but for now just make sure we don't catch e.g. // enough resolution but for now just make sure we don't catch e.g.
// searchableBox (size=6) // searchableBox (size=6)
if (geom.regions().size() > 1 && geom.globalSize() > 10) if (geom.globalSize() > 10)
{ {
// Representative local coordinates and bounding sphere // Representative local coordinates and bounding sphere
pointField ctrs; pointField ctrs;
scalarField radiusSqr; scalarField radiusSqr;
geom.boundingSpheres(ctrs, radiusSqr); geom.boundingSpheres(ctrs, radiusSqr);
labelList minLevelField(ctrs.size(), -1); labelList minLevelField(ctrs.size(), 0);
{ {
// Get the element index in a roundabout way. Problem is e.g. // Get the element index in a roundabout way. Problem is e.g.
// distributed surface where local indices differ from global // distributed surface where local indices differ from global
@ -447,10 +532,79 @@ void Foam::refinementSurfaces::setMinLevelFields
labelList shellLevel; labelList shellLevel;
shells.findHigherLevel(ctrs, minLevelField, shellLevel); shells.findHigherLevel(ctrs, minLevelField, shellLevel);
// In case of triangulated surfaces only cache value if triangle
// centre and vertices are in same shell
if (isA<triSurface>(geom))
{
label nUncached = 0;
// Check if points differing from ctr level
const triSurface& ts = refCast<const triSurface>(geom);
const pointField& points = ts.points();
// Determine minimum expected level to avoid having to
// test lots of points
labelList minPointLevel(points.size(), labelMax);
forAll(shellLevel, triI)
{
const labelledTri& t = ts[triI];
label level = shellLevel[triI];
forAll(t, tI)
{
minPointLevel[t[tI]] = min(minPointLevel[t[tI]], level);
}
}
// See if inside any shells with higher refinement level
labelList pointLevel;
shells.findHigherLevel(points, minPointLevel, pointLevel);
// See if triangle centre values differ from triangle points
forAll(shellLevel, triI)
{
const labelledTri& t = ts[triI];
label fLevel = shellLevel[triI];
if
(
(pointLevel[t[0]] != fLevel)
|| (pointLevel[t[1]] != fLevel)
|| (pointLevel[t[2]] != fLevel)
)
{
//Pout<< "Detected triangle " << t.tri(ts.points())
// << " partially inside/partially outside" << endl;
// Mark as uncached
shellLevel[triI] = -1;
nUncached++;
}
}
Info<< "For geometry " << geom.name()
<< " detected " << returnReduce(nUncached, sumOp<label>())
<< " uncached triangles out of " << geom.globalSize()
<< endl;
}
// Combine overall level field with current shell level. Make sure
// to preserve -1 (from triSurfaceMeshes with triangles partly
// inside/outside
forAll(minLevelField, i) forAll(minLevelField, i)
{
if (min(minLevelField[i], shellLevel[i]) < 0)
{
minLevelField[i] = -1;
}
else
{ {
minLevelField[i] = max(minLevelField[i], shellLevel[i]); minLevelField[i] = max(minLevelField[i], shellLevel[i]);
} }
}
// Store minLevelField on surface // Store minLevelField on surface
const_cast<searchableSurface&>(geom).setField(minLevelField); const_cast<searchableSurface&>(geom).setField(minLevelField);
@ -463,6 +617,8 @@ void Foam::refinementSurfaces::setMinLevelFields
// number. // number.
void Foam::refinementSurfaces::findHigherIntersection void Foam::refinementSurfaces::findHigherIntersection
( (
const shellSurfaces& shells,
const pointField& start, const pointField& start,
const pointField& end, const pointField& end,
const labelList& currentLevel, // current cell refinement level const labelList& currentLevel, // current cell refinement level
@ -494,42 +650,49 @@ void Foam::refinementSurfaces::findHigherIntersection
List<pointIndexHit> intersectionInfo(start.size()); List<pointIndexHit> intersectionInfo(start.size());
geom.findLineAny(start, end, intersectionInfo); geom.findLineAny(start, end, intersectionInfo);
// See if a cached level field available
labelList minLevelField;
geom.getField(intersectionInfo, minLevelField);
bool haveLevelField =
(
returnReduce(minLevelField.size(), sumOp<label>())
> 0
);
if (!haveLevelField && geom.regions().size() == 1) // Surface-based refinement level
labelList surfaceOnlyLevel(start.size(), -1);
{ {
minLevelField = labelList // Get per intersection the region
( labelList region;
intersectionInfo.size(), geom.getRegion(intersectionInfo, region);
minLevel(surfI, 0)
);
haveLevelField = true;
}
if (haveLevelField)
{
forAll(intersectionInfo, i) forAll(intersectionInfo, i)
{ {
if if (intersectionInfo[i].hit())
{
surfaceOnlyLevel[i] = minLevel(surfI, region[i]);
}
}
}
// Get shell refinement level if higher
const labelList localLevel
( (
intersectionInfo[i].hit() findHigherLevel
&& minLevelField[i] > currentLevel[i] (
geom,
shells,
intersectionInfo,
surfaceOnlyLevel // starting level
) )
);
// Combine localLevel with current level
forAll(localLevel, i)
{
if (localLevel[i] > currentLevel[i])
{ {
surfaces[i] = surfI; // index of surface surfaces[i] = surfI; // index of surface
surfaceLevel[i] = minLevelField[i]; surfaceLevel[i] = localLevel[i];
} }
} }
return; return;
} }
}
@ -546,40 +709,48 @@ void Foam::refinementSurfaces::findHigherIntersection
// Do intersection test // Do intersection test
geom.findLineAny(p0, p1, intersectionInfo); geom.findLineAny(p0, p1, intersectionInfo);
// See if a cached level field available
labelList minLevelField;
geom.getField(intersectionInfo, minLevelField);
// Copy all hits into arguments, In-place compact misses. // Surface-based refinement level
label missI = 0; labelList surfaceOnlyLevel(intersectionInfo.size(), -1);
{
// Get per intersection the region
labelList region;
geom.getRegion(intersectionInfo, region);
forAll(intersectionInfo, i) forAll(intersectionInfo, i)
{ {
// Get the minLevel for the point
label minLocalLevel = -1;
if (intersectionInfo[i].hit()) if (intersectionInfo[i].hit())
{ {
// Check if minLevelField for this surface. surfaceOnlyLevel[i] = minLevel(surfI, region[i]);
if (minLevelField.size())
{
minLocalLevel = minLevelField[i];
} }
else
{
// Use the min level for the surface instead. Assume
// single region 0.
minLocalLevel = minLevel(surfI, 0);
} }
} }
// Get shell refinement level if higher
const labelList localLevel
(
findHigherLevel
(
geom,
shells,
intersectionInfo,
surfaceOnlyLevel
)
);
// Combine localLevel with current level
label missI = 0;
forAll(localLevel, i)
{
label pointI = intersectionToPoint[i]; label pointI = intersectionToPoint[i];
if (minLocalLevel > currentLevel[pointI]) if (localLevel[i] > currentLevel[pointI])
{ {
// Mark point for refinement // Mark point for refinement
surfaces[pointI] = surfI; surfaces[pointI] = surfI;
surfaceLevel[pointI] = minLocalLevel; surfaceLevel[pointI] = localLevel[i];
} }
else else
{ {
@ -590,6 +761,7 @@ void Foam::refinementSurfaces::findHigherIntersection
} }
} }
// All done? Note that this decision should be synchronised // All done? Note that this decision should be synchronised
if (returnReduce(missI, sumOp<label>()) == 0) if (returnReduce(missI, sumOp<label>()) == 0)
{ {
@ -1337,4 +1509,121 @@ void Foam::refinementSurfaces::findInside
} }
void Foam::refinementSurfaces::findNearest
(
const labelList& surfacesToTest,
const labelListList& regions,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& hitSurface,
List<pointIndexHit>& hitInfo
) const
{
labelList geometries(UIndirectList<label>(surfaces_, surfacesToTest));
// Do the tests. Note that findNearest returns index in geometries.
searchableSurfacesQueries::findNearest
(
allGeometry_,
geometries,
regions,
samples,
nearestDistSqr,
hitSurface,
hitInfo
);
// Rework the hitSurface to be surface (i.e. index into surfaces_)
forAll(hitSurface, pointI)
{
if (hitSurface[pointI] != -1)
{
hitSurface[pointI] = surfacesToTest[hitSurface[pointI]];
}
}
}
void Foam::refinementSurfaces::findNearestRegion
(
const labelList& surfacesToTest,
const labelListList& regions,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& hitSurface,
List<pointIndexHit>& hitInfo,
labelList& hitRegion,
vectorField& hitNormal
) const
{
labelList geometries(UIndirectList<label>(surfaces_, surfacesToTest));
// Do the tests. Note that findNearest returns index in geometries.
searchableSurfacesQueries::findNearest
(
allGeometry_,
geometries,
regions,
samples,
nearestDistSqr,
hitSurface,
hitInfo
);
// Rework the hitSurface to be surface (i.e. index into surfaces_)
forAll(hitSurface, pointI)
{
if (hitSurface[pointI] != -1)
{
hitSurface[pointI] = surfacesToTest[hitSurface[pointI]];
}
}
// Collect the region
hitRegion.setSize(hitSurface.size());
hitRegion = -1;
hitNormal.setSize(hitSurface.size());
hitNormal = vector::zero;
forAll(surfacesToTest, i)
{
label surfI = surfacesToTest[i];
// Collect hits for surfI
const labelList localIndices(findIndices(hitSurface, surfI));
List<pointIndexHit> localHits
(
UIndirectList<pointIndexHit>
(
hitInfo,
localIndices
)
);
// Region
labelList localRegion;
allGeometry_[surfaces_[surfI]].getRegion(localHits, localRegion);
forAll(localIndices, i)
{
hitRegion[localIndices[i]] = localRegion[i];
}
// Normal
vectorField localNormal;
allGeometry_[surfaces_[surfI]].getNormal(localHits, localNormal);
forAll(localIndices, i)
{
hitNormal[localIndices[i]] = localNormal[i];
}
}
}
// ************************************************************************* // // ************************************************************************* //

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.
@ -42,6 +42,7 @@ SourceFiles
#include "vectorList.H" #include "vectorList.H"
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "surfaceZonesInfo.H" #include "surfaceZonesInfo.H"
#include "pointList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,8 +53,6 @@ class searchableSurfaces;
class shellSurfaces; class shellSurfaces;
class triSurfaceMesh; class triSurfaceMesh;
typedef List<point> pointList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class refinementSurfaces Declaration Class refinementSurfaces Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -95,6 +94,16 @@ class refinementSurfaces
// Private Member Functions // Private Member Functions
//- Given intersection results with geom detect local shell refinement
// level (possibly cached on triangles of geom)
labelList findHigherLevel
(
const searchableSurface& geom,
const shellSurfaces& shells,
const List<pointIndexHit>& intersectionInfo,
const labelList& surfaceLevel
) const;
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
refinementSurfaces(const refinementSurfaces&); refinementSurfaces(const refinementSurfaces&);
@ -234,6 +243,8 @@ public:
// Return surface number and level. // Return surface number and level.
void findHigherIntersection void findHigherIntersection
( (
const shellSurfaces& shells,
const pointField& start, const pointField& start,
const pointField& end, const pointField& end,
const labelList& currentLevel, // current cell refinement level const labelList& currentLevel, // current cell refinement level
@ -354,6 +365,37 @@ public:
const pointField& pt, const pointField& pt,
labelList& insideSurfaces labelList& insideSurfaces
) const; ) const;
// Region wise searching
//- Find nearest point on selected regions of surfaces.
void findNearest
(
const labelList& surfacesToTest,
const labelListList& regions,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& hitSurface,
List<pointIndexHit>& hitInfo
) const;
//- Find nearest point on selected regions of surfaces.
void findNearestRegion
(
const labelList& surfacesToTest,
const labelListList& regions,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& hitSurface,
List<pointIndexHit>& hitInfo,
labelList& hitRegion,
vectorField& hitNormal
) const;
}; };

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) 2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 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.
@ -341,26 +341,16 @@ Foam::labelList Foam::surfaceZonesInfo::getInsidePointNamedSurfaces
} }
Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh Foam::label Foam::surfaceZonesInfo::addCellZone
( (
const PtrList<surfaceZonesInfo>& surfList, const word& name,
const labelList& namedSurfaces, const labelList& addressing,
polyMesh& mesh polyMesh& mesh
) )
{ {
labelList surfaceToCellZone(surfList.size(), -1);
cellZoneMesh& cellZones = mesh.cellZones(); cellZoneMesh& cellZones = mesh.cellZones();
forAll(namedSurfaces, i) label zoneI = cellZones.findZoneID(name);
{
label surfI = namedSurfaces[i];
const word& cellZoneName = surfList[surfI].cellZoneName();
if (cellZoneName != word::null)
{
label zoneI = cellZones.findZoneID(cellZoneName);
if (zoneI == -1) if (zoneI == -1)
{ {
@ -371,13 +361,40 @@ Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh
zoneI, zoneI,
new cellZone new cellZone
( (
cellZoneName, //name name, // name
labelList(0), //addressing addressing, // addressing
zoneI, // index zoneI, // index
cellZones // cellZoneMesh cellZones // cellZoneMesh
) )
); );
} }
return zoneI;
}
Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh
(
const PtrList<surfaceZonesInfo>& surfList,
const labelList& namedSurfaces,
polyMesh& mesh
)
{
labelList surfaceToCellZone(surfList.size(), -1);
forAll(namedSurfaces, i)
{
label surfI = namedSurfaces[i];
const word& cellZoneName = surfList[surfI].cellZoneName();
if (cellZoneName != word::null)
{
label zoneI = addCellZone
(
cellZoneName,
labelList(0), // addressing
mesh
);
surfaceToCellZone[surfI] = zoneI; surfaceToCellZone[surfI] = zoneI;
} }
@ -385,7 +402,7 @@ Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh
// Check they are synced // Check they are synced
List<wordList> allCellZones(Pstream::nProcs()); List<wordList> allCellZones(Pstream::nProcs());
allCellZones[Pstream::myProcNo()] = cellZones.names(); allCellZones[Pstream::myProcNo()] = mesh.cellZones().names();
Pstream::gatherList(allCellZones); Pstream::gatherList(allCellZones);
Pstream::scatterList(allCellZones); Pstream::scatterList(allCellZones);
@ -409,6 +426,40 @@ Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh
} }
Foam::label Foam::surfaceZonesInfo::addFaceZone
(
const word& name,
const labelList& addressing,
const boolList& flipMap,
polyMesh& mesh
)
{
faceZoneMesh& faceZones = mesh.faceZones();
label zoneI = faceZones.findZoneID(name);
if (zoneI == -1)
{
zoneI = faceZones.size();
faceZones.setSize(zoneI+1);
faceZones.set
(
zoneI,
new faceZone
(
name, // name
addressing, // addressing
flipMap, // flipMap
zoneI, // index
faceZones // faceZoneMesh
)
);
}
return zoneI;
}
Foam::labelList Foam::surfaceZonesInfo::addFaceZonesToMesh Foam::labelList Foam::surfaceZonesInfo::addFaceZonesToMesh
( (
const PtrList<surfaceZonesInfo>& surfList, const PtrList<surfaceZonesInfo>& surfList,
@ -426,25 +477,13 @@ Foam::labelList Foam::surfaceZonesInfo::addFaceZonesToMesh
const word& faceZoneName = surfList[surfI].faceZoneName(); const word& faceZoneName = surfList[surfI].faceZoneName();
label zoneI = faceZones.findZoneID(faceZoneName); label zoneI = addFaceZone
if (zoneI == -1)
{
zoneI = faceZones.size();
faceZones.setSize(zoneI+1);
faceZones.set
(
zoneI,
new faceZone
( (
faceZoneName, //name faceZoneName, //name
labelList(0), //addressing labelList(0), //addressing
boolList(0), //flipmap boolList(0), //flipmap
zoneI, //index mesh
faceZones //faceZoneMesh
)
); );
}
surfaceToFaceZone[surfI] = zoneI; surfaceToFaceZone[surfI] = zoneI;
} }

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) 2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 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.
@ -39,6 +39,7 @@ SourceFiles
#include "word.H" #include "word.H"
#include "PtrList.H" #include "PtrList.H"
#include "labelList.H" #include "labelList.H"
#include "boolList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -222,6 +223,13 @@ public:
const PtrList<surfaceZonesInfo>& surfList const PtrList<surfaceZonesInfo>& surfList
); );
static label addCellZone
(
const word& name,
const labelList& addressing,
polyMesh& mesh
);
static labelList addCellZonesToMesh static labelList addCellZonesToMesh
( (
const PtrList<surfaceZonesInfo>& surfList, const PtrList<surfaceZonesInfo>& surfList,
@ -229,6 +237,14 @@ public:
polyMesh& mesh polyMesh& mesh
); );
static label addFaceZone
(
const word& name,
const labelList& addressing,
const boolList& flipMap,
polyMesh& mesh
);
static labelList addFaceZonesToMesh static labelList addFaceZonesToMesh
( (
const PtrList<surfaceZonesInfo>& surfList, const PtrList<surfaceZonesInfo>& surfList,

View File

@ -7,6 +7,11 @@ cd ${0%/*} || exit 1 # Run from this directory
./Allrun ./Allrun
) )
(
cd addLayersToFaceZone || 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