ENH: extrudeMesh,snappyHexMesh: extrude across non-manifold boundaries

This commit is contained in:
mattijs
2011-02-14 14:52:51 +00:00
parent 85190a16b6
commit a9f25c19dc
10 changed files with 847 additions and 261 deletions

View File

@ -104,6 +104,11 @@
taking film into account taking film into account
+ Parallel aware + Parallel aware
*** *New* ptscotch decomposition method *** *New* ptscotch decomposition method
*** *Updated* scotch decomposition method to run in parallel by doing
decomposition on the master. Unfortunately scotch and ptscotch cannot
be linked in to the same executable.
*** *Updated* simple decomposition method to run in parallel by doing
decomposition on the master.
*** *Updated* decomposePar maps polyPatches instead of recreating them so *** *Updated* decomposePar maps polyPatches instead of recreating them so
polyPatches holding data can map the data. polyPatches holding data can map the data.
*** *Updated* particle tracking algorithm *** *Updated* particle tracking algorithm
@ -183,6 +188,9 @@
e.g. pitzDailyDirectMapped tutorial. e.g. pitzDailyDirectMapped tutorial.
+ =setSet=: allows time range (e.g. 0:100) in combination with -batch argument + =setSet=: allows time range (e.g. 0:100) in combination with -batch argument
to execute the commands for multiple times. to execute the commands for multiple times.
+ =extrudeMesh=:
- option to add extrusion to existing mesh.
- works in parallel
* Post-processing * Post-processing
+ =paraFoam=, =foamToVTK=: full support for polyhedral cell type in recent + =paraFoam=, =foamToVTK=: full support for polyhedral cell type in recent
Paraview versions. Paraview versions.

View File

@ -43,6 +43,7 @@ Description
#include "addPatchCellLayer.H" #include "addPatchCellLayer.H"
#include "fvMesh.H" #include "fvMesh.H"
#include "MeshedSurfaces.H" #include "MeshedSurfaces.H"
#include "globalIndex.H"
#include "extrudedMesh.H" #include "extrudedMesh.H"
#include "extrudeModel.H" #include "extrudeModel.H"
@ -261,6 +262,12 @@ int main(int argc, char *argv[])
sourceCasePath.expand(); sourceCasePath.expand();
fileName sourceRootDir = sourceCasePath.path(); fileName sourceRootDir = sourceCasePath.path();
fileName sourceCaseDir = sourceCasePath.name(); fileName sourceCaseDir = sourceCasePath.name();
if (Pstream::parRun())
{
sourceCaseDir =
sourceCaseDir
/"processor" + Foam::name(Pstream::myProcNo());
}
wordList sourcePatches; wordList sourcePatches;
dict.lookup("sourcePatches") >> sourcePatches; dict.lookup("sourcePatches") >> sourcePatches;
@ -279,54 +286,173 @@ int main(int argc, char *argv[])
sourceRootDir, sourceRootDir,
sourceCaseDir sourceCaseDir
); );
#include "createMesh.H" #include "createMesh.H"
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Topo change container. Either copy an existing mesh or start
// with empty storage (number of patches only needed for checking)
autoPtr<polyTopoChange> meshMod
(
(
mode == MESH
? new polyTopoChange(mesh)
: new polyTopoChange(patches.size())
)
);
// Extrusion engine. Either adding to existing mesh or // Extrusion engine. Either adding to existing mesh or
// creating separate mesh. // creating separate mesh.
addPatchCellLayer layerExtrude(mesh, (mode == MESH)); addPatchCellLayer layerExtrude(mesh, (mode == MESH));
const labelList meshFaces(patchFaces(patches, sourcePatches));
indirectPrimitivePatch extrudePatch indirectPrimitivePatch extrudePatch
( (
IndirectList<face> IndirectList<face>
( (
mesh.faces(), mesh.faces(),
patchFaces(patches, sourcePatches) meshFaces
), ),
mesh.points() mesh.points()
); );
// Determine extrudePatch normal
pointField extrudePatchPointNormals
(
PatchTools::pointNormals //calcNormals
(
mesh,
extrudePatch,
meshFaces
)
);
// Precalculate mesh edges for pp.edges.
const labelList meshEdges
(
extrudePatch.meshEdges
(
mesh.edges(),
mesh.pointEdges()
)
);
// Global face indices engine
const globalIndex globalFaces(mesh.nFaces());
// Determine extrudePatch.edgeFaces in global numbering (so across
// coupled patches)
labelListList edgeGlobalFaces
(
addPatchCellLayer::globalEdgeFaces
(
mesh,
globalFaces,
extrudePatch
)
);
// Determine what patches boundary edges need to get extruded into.
// This might actually cause edge-connected processors to become
// face-connected so might need to introduce new processor boundaries.
// Calculates:
// - per pp.edge the patch to extrude into
// - any additional processor boundaries (patchToNbrProc = map from
// new patchID to neighbour processor)
// - number of new patches (nPatches)
labelList sidePatchID;
label nPatches;
Map<label> nbrProcToPatch;
Map<label> patchToNbrProc;
addPatchCellLayer::calcSidePatch
(
mesh,
globalFaces,
edgeGlobalFaces,
extrudePatch,
sidePatchID,
nPatches,
nbrProcToPatch,
patchToNbrProc
);
// Add any patches.
label nAdded = nPatches - mesh.boundaryMesh().size();
reduce(nAdded, sumOp<label>());
Info<< "Adding overall " << nAdded << " processor patches." << endl;
if (nAdded > 0)
{
DynamicList<polyPatch*> newPatches(nPatches);
forAll(mesh.boundaryMesh(), patchI)
{
newPatches.append
(
mesh.boundaryMesh()[patchI].clone
(
mesh.boundaryMesh()
).ptr()
);
}
for
(
label patchI = mesh.boundaryMesh().size();
patchI < nPatches;
patchI++
)
{
label nbrProcI = patchToNbrProc[patchI];
word name =
"procBoundary"
+ Foam::name(Pstream::myProcNo())
+ "to"
+ Foam::name(nbrProcI);
Pout<< "Adding patch " << patchI
<< " name:" << name
<< " between " << Pstream::myProcNo()
<< " and " << nbrProcI
<< endl;
newPatches.append
(
new processorPolyPatch
(
name,
0, // size
mesh.nFaces(), // start
patchI, // index
mesh.boundaryMesh(),// polyBoundaryMesh
Pstream::myProcNo(),// myProcNo
nbrProcI // neighbProcNo
)
);
}
// Add patches. Do no parallel updates.
mesh.removeFvBoundary();
mesh.addFvPatches(newPatches, true);
}
// Only used for addPatchCellLayer into new mesh // Only used for addPatchCellLayer into new mesh
labelList exposedPatchIDs; labelList exposedPatchID;
if (mode == PATCH) if (mode == PATCH)
{ {
dict.lookup("exposedPatchName") >> backPatchName; dict.lookup("exposedPatchName") >> backPatchName;
exposedPatchIDs.setSize exposedPatchID.setSize
( (
extrudePatch.size(), extrudePatch.size(),
findPatchID(patches, backPatchName) findPatchID(patches, backPatchName)
); );
} }
// Determine points and extrusion
pointField layer0Points(extrudePatch.nPoints()); pointField layer0Points(extrudePatch.nPoints());
pointField displacement(extrudePatch.nPoints()); pointField displacement(extrudePatch.nPoints());
forAll(displacement, pointI) forAll(displacement, pointI)
{ {
const vector& patchNormal = extrudePatch.pointNormals()[pointI]; const vector& patchNormal = extrudePatchPointNormals[pointI];
// layer0 point // layer0 point
layer0Points[pointI] = model() layer0Points[pointI] = model()
@ -373,15 +499,31 @@ int main(int argc, char *argv[])
// Layers per point // Layers per point
labelList nPointLayers(extrudePatch.nPoints(), model().nLayers()); labelList nPointLayers(extrudePatch.nPoints(), model().nLayers());
// Displacement for first layer // Displacement for first layer
vectorField firstLayerDisp(displacement*model().sumThickness(1)); vectorField firstLayerDisp = displacement*model().sumThickness(1);
// Expansion ratio not used. // Expansion ratio not used.
scalarField ratio(extrudePatch.nPoints(), 1.0); scalarField ratio(extrudePatch.nPoints(), 1.0);
// Topo change container. Either copy an existing mesh or start
// with empty storage (number of patches only needed for checking)
autoPtr<polyTopoChange> meshMod
(
(
mode == MESH
? new polyTopoChange(mesh)
: new polyTopoChange(patches.size())
)
);
layerExtrude.setRefinement layerExtrude.setRefinement
( (
globalFaces,
edgeGlobalFaces,
ratio, // expansion ratio ratio, // expansion ratio
extrudePatch, // patch faces to extrude extrudePatch, // patch faces to extrude
exposedPatchIDs, // if new mesh: patches for exposed faces sidePatchID, // if boundary edge: patch to use
exposedPatchID, // if new mesh: patches for exposed faces
nFaceLayers, nFaceLayers,
nPointLayers, nPointLayers,
firstLayerDisp, firstLayerDisp,
@ -401,7 +543,7 @@ int main(int argc, char *argv[])
model() model()
( (
extrudePatch.localPoints()[pointI], extrudePatch.localPoints()[pointI],
extrudePatch.pointNormals()[pointI], extrudePatchPointNormals[pointI],
pPointI+1 // layer pPointI+1 // layer
) )
); );

View File

@ -43,75 +43,6 @@ defineTypeNameAndDebug(Foam::addPatchCellLayer, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Calculate global faces per pp edge.
Foam::labelListList Foam::addPatchCellLayer::calcGlobalEdgeFaces
(
const polyMesh& mesh,
const globalIndex& globalFaces,
const indirectPrimitivePatch& pp,
const labelList& meshEdges
)
{
//// Determine coupled edges just so we don't have to have storage
//// for all non-coupled edges.
//
//PackedBoolList isCoupledEdge(mesh.nEdges());
//
//const polyBoundaryMesh& patches = mesh.boundaryMesh();
//
//forAll(patches, patchI)
//{
// const polyPatch& pp = patches[patchI];
//
// if (pp.coupled())
// {
// const labelList& meshEdges = pp.meshEdges();
//
// forAll(meshEdges, i)
// {
// isCoupledEdge.set(meshEdges[i], 1);
// }
// }
//}
// From mesh edge to global face labels. Sized only for pp edges.
labelListList globalEdgeFaces(mesh.nEdges());
const labelListList& edgeFaces = pp.edgeFaces();
forAll(edgeFaces, edgeI)
{
label meshEdgeI = meshEdges[edgeI];
//if (isCoupledEdge.get(meshEdgeI) == 1)
{
const labelList& eFaces = edgeFaces[edgeI];
// Store face and processor as unique tag.
labelList& globalEFaces = globalEdgeFaces[meshEdgeI];
globalEFaces.setSize(eFaces.size());
forAll(eFaces, i)
{
globalEFaces[i] =
globalFaces.toGlobal(pp.addressing()[eFaces[i]]);
}
}
}
// Synchronise across coupled edges.
syncTools::syncEdgeList
(
mesh,
globalEdgeFaces,
uniqueEqOp(),
labelList() // null value
);
// Extract pp part
return labelListList(UIndirectList<labelList>(globalEdgeFaces, meshEdges));
}
Foam::label Foam::addPatchCellLayer::nbrFace Foam::label Foam::addPatchCellLayer::nbrFace
( (
const labelListList& edgeFaces, const labelListList& edgeFaces,
@ -316,12 +247,12 @@ Foam::labelPair Foam::addPatchCellLayer::getEdgeString
Foam::label Foam::addPatchCellLayer::addSideFace Foam::label Foam::addPatchCellLayer::addSideFace
( (
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& patchID, // prestored patch per pp face
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 ownFaceI, // pp face that provides owner const label ownFaceI, // pp face that provides owner
const label nbrFaceI, const label nbrFaceI,
const label patchEdgeI, // edge to add to
const label meshEdgeI, // corresponding mesh edge const label meshEdgeI, // corresponding mesh edge
const label layerI, // layer const label layerI, // layer
const label numEdgeFaces, // number of layers for edge const label numEdgeFaces, // number of layers for edge
@ -329,8 +260,9 @@ Foam::label Foam::addPatchCellLayer::addSideFace
polyTopoChange& meshMod polyTopoChange& meshMod
) const ) const
{ {
// Edge to 'inflate' from // Face or edge to 'inflate' from
label inflateEdgeI = -1; label inflateEdgeI = -1;
label inflateFaceI = -1;
// Check mesh faces using edge // Check mesh faces using edge
if (addToMesh_) if (addToMesh_)
@ -346,8 +278,6 @@ Foam::label Foam::addPatchCellLayer::addSideFace
} }
} }
// Get my mesh face and its zone.
label meshFaceI = pp.addressing()[ownFaceI];
// Zone info comes from any side patch face. Otherwise -1 since we // 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? // don't know what to put it in - inherit from the extruded faces?
label zoneI = -1; //mesh_.faceZones().whichZone(meshFaceI); label zoneI = -1; //mesh_.faceZones().whichZone(meshFaceI);
@ -358,14 +288,15 @@ Foam::label Foam::addPatchCellLayer::addSideFace
// 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. Patch id is obtained from // External edge so external face.
// any other patch connected to edge.
const polyBoundaryMesh& patches = mesh_.boundaryMesh(); const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Loop over all faces connected to edge to inflate and // Loop over all faces connected to edge to inflate and
// see if any boundary face (but not meshFaceI) // see if we can find a face that is otherPatchID
label otherPatchID = patchID[ownFaceI];
// Get my mesh face and its zone.
label meshFaceI = pp.addressing()[ownFaceI];
forAll(meshFaces, k) forAll(meshFaces, k)
{ {
@ -373,11 +304,14 @@ Foam::label Foam::addPatchCellLayer::addSideFace
if if
( (
faceI != meshFaceI (faceI != meshFaceI)
&& !mesh_.isInternalFace(faceI) && (patches.whichPatch(faceI) == newPatchID)
) )
{ {
otherPatchID = patches.whichPatch(faceI); // Found the patch face. Use it to inflate from
inflateEdgeI = -1;
inflateFaceI = faceI;
zoneI = mesh_.faceZones().whichZone(faceI); zoneI = mesh_.faceZones().whichZone(faceI);
if (zoneI != -1) if (zoneI != -1)
{ {
@ -414,7 +348,7 @@ Foam::label Foam::addPatchCellLayer::addSideFace
//Pout<< "Added boundary face:" << newFace //Pout<< "Added boundary face:" << newFace
// << " own:" << addedCells[ownFaceI][layerOwn] // << " own:" << addedCells[ownFaceI][layerOwn]
// << " patch:" << otherPatchID // << " patch:" << newPatchID
// << endl; // << endl;
addedFaceI = meshMod.setAction addedFaceI = meshMod.setAction
@ -426,9 +360,9 @@ Foam::label Foam::addPatchCellLayer::addSideFace
-1, // neighbour -1, // neighbour
-1, // master point -1, // master point
inflateEdgeI, // master edge inflateEdgeI, // master edge
-1, // master face inflateFaceI, // master face
false, // flux flip false, // flux flip
otherPatchID, // patch for face newPatchID, // patch for face
zoneI, // zone for face zoneI, // zone for face
flip // face zone flip flip // face zone flip
) )
@ -510,6 +444,51 @@ Foam::label Foam::addPatchCellLayer::addSideFace
} }
Foam::label Foam::addPatchCellLayer::findProcPatch
(
const polyMesh& mesh,
const label nbrProcID
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
forAll(mesh.globalData().processorPatches(), i)
{
label patchI = mesh.globalData().processorPatches()[i];
if
(
refCast<const processorPolyPatch>(patches[patchI]).neighbProcNo()
== nbrProcID
)
{
return patchI;
}
}
return -1;
}
void Foam::addPatchCellLayer::setFaceProps
(
const polyMesh& mesh,
const label faceI,
label& patchI,
label& zoneI,
bool& zoneFlip
)
{
patchI = mesh.boundaryMesh().whichPatch(faceI);
zoneI = mesh.faceZones().whichZone(faceI);
if (zoneI != -1)
{
label index = mesh.faceZones()[zoneI].whichFace(faceI);
zoneFlip = mesh.faceZones()[zoneI].flipMap()[index];
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from mesh // Construct from mesh
@ -561,10 +540,251 @@ Foam::labelListList Foam::addPatchCellLayer::addedCells() const
} }
// Calculate global faces per pp edge.
Foam::labelListList Foam::addPatchCellLayer::globalEdgeFaces
(
const polyMesh& mesh,
const globalIndex& globalFaces,
const indirectPrimitivePatch& pp
)
{
// Precalculate mesh edges for pp.edges.
const labelList meshEdges(pp.meshEdges(mesh.edges(), mesh.pointEdges()));
// From mesh edge to global face labels. Non-empty sublists only for
// pp edges.
labelListList globalEdgeFaces(mesh.nEdges());
const labelListList& edgeFaces = pp.edgeFaces();
forAll(edgeFaces, edgeI)
{
label meshEdgeI = meshEdges[edgeI];
const labelList& eFaces = edgeFaces[edgeI];
// Store face and processor as unique tag.
labelList& globalEFaces = globalEdgeFaces[meshEdgeI];
globalEFaces.setSize(eFaces.size());
forAll(eFaces, i)
{
globalEFaces[i] = globalFaces.toGlobal(pp.addressing()[eFaces[i]]);
}
}
// Synchronise across coupled edges.
syncTools::syncEdgeList
(
mesh,
globalEdgeFaces,
uniqueEqOp(),
labelList() // null value
);
// Extract pp part
return labelListList(UIndirectList<labelList>(globalEdgeFaces, meshEdges));
}
void Foam::addPatchCellLayer::calcSidePatch
(
const polyMesh& mesh,
const globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID,
label& nPatches,
Map<label>& nbrProcToPatch,
Map<label>& patchToNbrProc
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Precalculate mesh edges for pp.edges.
const labelList meshEdges(pp.meshEdges(mesh.edges(), mesh.pointEdges()));
sidePatchID.setSize(pp.nEdges());
sidePatchID = -1;
// These also get determined but not (yet) exported:
// - whether face is created from other face or edge
// - what zone&orientation face should have
labelList inflateEdgeI(pp.nEdges(), -1);
labelList inflateFaceI(pp.nEdges(), -1);
labelList sideZoneID(pp.nEdges(), -1);
boolList sideFlip(pp.nEdges(), false);
nPatches = patches.size();
forAll(globalEdgeFaces, edgeI)
{
const labelList& eGlobalFaces = globalEdgeFaces[edgeI];
if
(
eGlobalFaces.size() == 2
&& pp.edgeFaces()[edgeI].size() == 1
)
{
// Locally but not globally a boundary edge. Hence a coupled
// edge. Find the patch to use if on different
// processors.
label f0 = eGlobalFaces[0];
label f1 = eGlobalFaces[1];
label otherProcI = -1;
if (globalFaces.isLocal(f0) && !globalFaces.isLocal(f1))
{
otherProcI = globalFaces.whichProcID(f1);
}
else if (!globalFaces.isLocal(f0) && globalFaces.isLocal(f1))
{
otherProcI = globalFaces.whichProcID(f0);
}
if (otherProcI != -1)
{
sidePatchID[edgeI] = findProcPatch(mesh, otherProcI);
if (sidePatchID[edgeI] == -1)
{
// Cannot find a patch to processor. See if already
// marked for addition
if (nbrProcToPatch.found(otherProcI))
{
sidePatchID[edgeI] = nbrProcToPatch[otherProcI];
}
else
{
sidePatchID[edgeI] = nPatches;
nbrProcToPatch.insert(otherProcI, nPatches);
patchToNbrProc.insert(nPatches, otherProcI);
nPatches++;
}
}
}
}
}
// Determine face properties for all other boundary edges
// ------------------------------------------------------
const labelListList& edgeFaces = pp.edgeFaces();
forAll(edgeFaces, edgeI)
{
if (edgeFaces[edgeI].size() == 1 && sidePatchID[edgeI] == -1)
{
// Proper, uncoupled patch edge.
label myFaceI = pp.addressing()[edgeFaces[edgeI][0]];
// Pick up any boundary face on this edge and use its properties
label meshEdgeI = meshEdges[edgeI];
const labelList& meshFaces = mesh.edgeFaces()[meshEdgeI];
forAll(meshFaces, k)
{
label faceI = meshFaces[k];
if (faceI != myFaceI && !mesh.isInternalFace(faceI))
{
setFaceProps
(
mesh,
faceI,
sidePatchID[edgeI],
sideZoneID[edgeI],
sideFlip[edgeI]
);
inflateFaceI[edgeI] = faceI;
inflateEdgeI[edgeI] = -1;
break;
}
}
}
}
// Now hopefully every boundary edge has a side patch. Check
forAll(edgeFaces, edgeI)
{
if (edgeFaces[edgeI].size() == 1 && sidePatchID[edgeI] == -1)
{
const edge& e = pp.edges()[edgeI];
FatalErrorIn("addPatchCellLayer::calcSidePatch(..)")
<< "Have no sidePatchID for edge " << edgeI << " points "
<< pp.points()[pp.meshPoints()[e[0]]]
<< pp.points()[pp.meshPoints()[e[1]]]
<< abort(FatalError);
}
}
// Now we have sidepatch see if we have patchface or edge to inflate
// from.
forAll(edgeFaces, edgeI)
{
if (edgeFaces[edgeI].size() == 1 && inflateFaceI[edgeI] == -1)
{
// 1. Do we have a boundary face to inflate from
label myFaceI = pp.addressing()[edgeFaces[edgeI][0]];
// Pick up any boundary face on this edge and use its properties
label meshEdgeI = meshEdges[edgeI];
const labelList& meshFaces = mesh.edgeFaces()[meshEdgeI];
forAll(meshFaces, k)
{
label faceI = meshFaces[k];
if (faceI != myFaceI)
{
if (mesh.isInternalFace(faceI))
{
inflateEdgeI[edgeI] = meshEdgeI;
}
else
{
if (patches.whichPatch(faceI) == sidePatchID[edgeI])
{
setFaceProps
(
mesh,
faceI,
sidePatchID[edgeI],
sideZoneID[edgeI],
sideFlip[edgeI]
);
inflateFaceI[edgeI] = faceI;
inflateEdgeI[edgeI] = -1;
break;
}
}
}
}
}
}
}
void Foam::addPatchCellLayer::setRefinement void Foam::addPatchCellLayer::setRefinement
( (
const globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const scalarField& expansionRatio, const scalarField& expansionRatio,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& sidePatchID,
const labelList& exposedPatchID, const labelList& exposedPatchID,
const labelList& nFaceLayers, const labelList& nFaceLayers,
const labelList& nPointLayers, const labelList& nPointLayers,
@ -575,7 +795,7 @@ void Foam::addPatchCellLayer::setRefinement
if (debug) if (debug)
{ {
Pout<< "addPatchCellLayer::setRefinement : Adding up to " Pout<< "addPatchCellLayer::setRefinement : Adding up to "
<< max(nPointLayers) << gMax(nPointLayers)
<< " layers of cells to indirectPrimitivePatch with " << " layers of cells to indirectPrimitivePatch with "
<< pp.nPoints() << " points" << endl; << pp.nPoints() << " points" << endl;
} }
@ -788,8 +1008,6 @@ void Foam::addPatchCellLayer::setRefinement
label meshEdgeI = meshEdges[edgeI]; label meshEdgeI = meshEdges[edgeI];
// Mesh faces using edge
// Mesh faces using edge // Mesh faces using edge
const labelList& meshFaces = mesh_.edgeFaces(meshEdgeI, ef); const labelList& meshFaces = mesh_.edgeFaces(meshEdgeI, ef);
@ -1213,22 +1431,6 @@ void Foam::addPatchCellLayer::setRefinement
} }
// Global indices engine
const globalIndex globalFaces(mesh_.nFaces());
// Get for all pp edgeFaces a unique faceID
labelListList globalEdgeFaces
(
calcGlobalEdgeFaces
(
mesh_,
globalFaces,
pp,
meshEdges
)
);
// Mark off which edges have been extruded // Mark off which edges have been extruded
boolList doneEdge(pp.nEdges(), false); boolList doneEdge(pp.nEdges(), false);
@ -1474,16 +1676,17 @@ void Foam::addPatchCellLayer::setRefinement
addSideFace addSideFace
( (
pp, pp,
patchID,
addedCells, addedCells,
newFace,
newFace, // vertices of new face
sidePatchID[startEdgeI],// -1 or patch for face
patchFaceI, patchFaceI,
nbrFaceI, nbrFaceI,
startEdgeI, // edge to inflate from meshEdgeI, // (mesh) edge to inflate
meshEdgeI, // corresponding mesh edge i, // layer
i, numEdgeSideFaces, // num layers
numEdgeSideFaces, meshFaces, // edgeFaces
meshFaces,
meshMod meshMod
); );
} }

View File

@ -181,16 +181,6 @@ class addPatchCellLayer
// Private Member Functions // Private Member Functions
//- Per patch edge the pp faces (in global indices) using it. Uses
// uniqueEqOp() to remove duplicates.
labelListList calcGlobalEdgeFaces
(
const polyMesh& mesh,
const globalIndex& globalFaces,
const indirectPrimitivePatch& pp,
const labelList& meshEdges
);
//- Get the face on the other side of the edge. //- Get the face on the other side of the edge.
static label nbrFace static label nbrFace
( (
@ -226,12 +216,13 @@ class addPatchCellLayer
label addSideFace label addSideFace
( (
const indirectPrimitivePatch&, const indirectPrimitivePatch&,
const labelList& patchID,
const labelListList& addedCells, const labelListList& addedCells,
const face& newFace, const face& newFace,
const label newPatchID,
const label ownFaceI, const label ownFaceI,
const label nbrFaceI, const label nbrFaceI,
const label patchEdgeI,
const label meshEdgeI, const label meshEdgeI,
const label layerI, const label layerI,
const label numEdgeFaces, const label numEdgeFaces,
@ -239,6 +230,18 @@ class addPatchCellLayer
polyTopoChange& polyTopoChange&
) const; ) const;
//- Find patch to neighbouring processor
static label findProcPatch(const polyMesh&, const label nbrProcID);
//- Extract properties from mesh face
static void setFaceProps
(
const polyMesh&,
const label,
label&,
label&,
bool&
);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
addPatchCellLayer(const addPatchCellLayer&); addPatchCellLayer(const addPatchCellLayer&);
@ -256,7 +259,7 @@ public:
// Constructors // Constructors
//- Construct from mesh. //- Construct from mesh.
addPatchCellLayer(const polyMesh& mesh, const bool addToMesh = true); addPatchCellLayer(const polyMesh&, const bool addToMesh = true);
// Member Functions // Member Functions
@ -291,6 +294,33 @@ public:
// Edit // Edit
//- Per patch edge the pp faces (in global indices) using it. Uses
// uniqueEqOp() to remove duplicates.
static labelListList globalEdgeFaces
(
const polyMesh&,
const globalIndex& globalFaces,
const indirectPrimitivePatch& pp
);
//- Boundary edges get extruded into boundary faces. Determine patch
// for these faces. This might be a to-be-created processor patch
// (patchI >= mesh.boundaryMesh().size()) in which case the
// nbrProcToPatch, patchToNbrProc give the correspondence. nPatches
// is the new number of patches.
static void calcSidePatch
(
const polyMesh&,
const globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID,
label& nPatches,
Map<label>& nbrProcToPatch,
Map<label>& patchToNbrProc
);
//- Play commands into polyTopoChange to create layers on top //- Play commands into polyTopoChange to create layers on top
// of indirectPrimitivePatch (have to be outside faces). // of indirectPrimitivePatch (have to be outside faces).
// Gets displacement per patch point. // Gets displacement per patch point.
@ -313,8 +343,11 @@ public:
// (instead of e.g. from patch faces) // (instead of e.g. from patch faces)
void setRefinement void setRefinement
( (
const globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const scalarField& expansionRatio, const scalarField& expansionRatio,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& sidePatchID,
const labelList& exposedPatchID, const labelList& exposedPatchID,
const labelList& nFaceLayers, const labelList& nFaceLayers,
const labelList& nPointLayers, const labelList& nPointLayers,
@ -326,20 +359,26 @@ public:
//- Add with constant expansion ratio and same nLayers everywhere //- Add with constant expansion ratio and same nLayers everywhere
void setRefinement void setRefinement
( (
const globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const label nLayers, const label nLayers,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& sidePatchID,
const vectorField& overallDisplacement, const vectorField& overallDisplacement,
polyTopoChange& meshMod polyTopoChange& meshMod
) )
{ {
setRefinement setRefinement
( (
scalarField(pp.nPoints(), 1.0), // expansion ration globalFaces,
globalEdgeFaces,
scalarField(pp.nPoints(), 1.0), // expansion ration
pp, pp,
sidePatchID,
labelList(0), labelList(0),
labelList(pp.size(), nLayers), labelList(pp.size(), nLayers), // nFaceLayers
labelList(pp.nPoints(), nLayers), labelList(pp.nPoints(), nLayers), // nPointLayers
overallDisplacement / nLayers, overallDisplacement / nLayers, // firstLayerDisp
meshMod meshMod
); );
} }

View File

@ -2,7 +2,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) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -45,6 +45,7 @@ Description
#include "layerParameters.H" #include "layerParameters.H"
#include "combineFaces.H" #include "combineFaces.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -888,68 +889,6 @@ void Foam::autoLayerDriver::handleNonManifolds
Info<< "Outside of local patch is multiply connected across edges or" Info<< "Outside of local patch is multiply connected across edges or"
<< " points at " << nNonManif << " points." << endl; << " points at " << nNonManif << " points." << endl;
const labelList& meshPoints = pp.meshPoints();
// 2. Parallel check
// For now disable extrusion at any shared edges.
const labelHashSet sharedEdgeSet(mesh.globalData().sharedEdgeLabels());
forAll(pp.edges(), edgeI)
{
if (sharedEdgeSet.found(meshEdges[edgeI]))
{
const edge& e = mesh.edges()[meshEdges[edgeI]];
Pout<< "Disabling extrusion at edge "
<< mesh.points()[e[0]] << mesh.points()[e[1]]
<< " since it is non-manifold across coupled patches."
<< endl;
nonManifoldPoints.insert(e[0]);
nonManifoldPoints.insert(e[1]);
}
}
// 3b. extrusion can produce multiple faces between 2 cells
// across processor boundary
// This occurs when a coupled face shares more than 1 edge with a
// non-coupled boundary face.
// This is now correctly handled by addPatchCellLayer in that it
// extrudes a single face from the stringed up edges.
nNonManif = returnReduce(nonManifoldPoints.size(), sumOp<label>());
if (nNonManif > 0)
{
Info<< "Outside of patches is multiply connected across edges or"
<< " points at " << nNonManif << " points." << nl
<< "Writing " << nNonManif
<< " points where this happens to pointSet "
<< nonManifoldPoints.name() << nl
<< "and setting layer thickness to zero on these points."
<< endl;
nonManifoldPoints.instance() = mesh.time().timeName();
nonManifoldPoints.write();
forAll(meshPoints, patchPointI)
{
if (nonManifoldPoints.found(meshPoints[patchPointI]))
{
unmarkExtrusion
(
patchPointI,
patchDisp,
patchNLayers,
extrudeStatus
);
}
}
}
Info<< "Set displacement to zero for all " << nNonManif Info<< "Set displacement to zero for all " << nNonManif
<< " non-manifold points" << endl; << " non-manifold points" << endl;
} }
@ -1348,7 +1287,6 @@ void Foam::autoLayerDriver::setNumLayers
} }
// Grow no-extrusion layer
void Foam::autoLayerDriver::growNoExtrusion void Foam::autoLayerDriver::growNoExtrusion
( (
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
@ -1439,6 +1377,103 @@ void Foam::autoLayerDriver::growNoExtrusion
} }
void Foam::autoLayerDriver::determineSidePatches
(
const globalIndex& globalFaces,
const labelListList& edgeGlobalFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID
)
{
// Sometimes edges-to-be-extruded are on more than 2 processors.
// Work out which 2 hold the faces to be extruded and thus which procpatch
// the side-face should be in. As an additional complication this might
// mean that 2 procesors that were only edge-connected now suddenly need
// to become face-connected i.e. have a processor patch between them.
fvMesh& mesh = meshRefiner_.mesh();
// Determine sidePatchID. Any additional processor boundary gets added to
// patchToNbrProc,nbrProcToPatch and nPatches gets set to the new number
// of patches.
label nPatches;
Map<label> nbrProcToPatch;
Map<label> patchToNbrProc;
addPatchCellLayer::calcSidePatch
(
mesh,
globalFaces,
edgeGlobalFaces,
pp,
sidePatchID,
nPatches,
nbrProcToPatch,
patchToNbrProc
);
label nOldPatches = mesh.boundaryMesh().size();
label nAdded = returnReduce(nPatches-nOldPatches, sumOp<label>());
Info<< nl << "Adding in total " << nAdded/2 << " inter-processor patches to"
<< " handle extrusion of non-manifold processor boundaries."
<< endl;
if (nAdded > 0)
{
// We might not add patches in same order as in patchToNbrProc
// so prepare to renumber sidePatchID
Map<label> wantedToAddedPatch;
for (label patchI = nOldPatches; patchI < nPatches; patchI++)
{
label nbrProcI = patchToNbrProc[patchI];
word name =
"procBoundary"
+ Foam::name(Pstream::myProcNo())
+ "to"
+ Foam::name(nbrProcI);
dictionary patchDict;
patchDict.add("type", processorPolyPatch::typeName);
patchDict.add("myProcNo", Pstream::myProcNo());
patchDict.add("neighbProcNo", nbrProcI);
patchDict.add("nFaces", 0);
patchDict.add("startFace", mesh.nFaces());
Pout<< "Adding patch " << patchI
<< " name:" << name
<< " between " << Pstream::myProcNo()
<< " and " << nbrProcI
<< endl;
label procPatchI = meshRefiner_.appendPatch
(
mesh,
mesh.boundaryMesh().size(), // new patch index
name,
patchDict
);
wantedToAddedPatch.insert(patchI, procPatchI);
}
// Renumber sidePatchID
forAll(sidePatchID, i)
{
label patchI = sidePatchID[i];
Map<label>::const_iterator fnd = wantedToAddedPatch.find(patchI);
if (fnd != wantedToAddedPatch.end())
{
sidePatchID[i] = fnd();
}
}
mesh.clearOut();
const_cast<polyBoundaryMesh&>(mesh.boundaryMesh()).updateMesh();
}
}
void Foam::autoLayerDriver::calculateLayerThickness void Foam::autoLayerDriver::calculateLayerThickness
( (
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
@ -2553,6 +2588,37 @@ void Foam::autoLayerDriver::addLayers
) )
); );
// Global face indices engine
const globalIndex globalFaces(mesh.nFaces());
// Determine extrudePatch.edgeFaces in global numbering (so across
// coupled patches). This is used only to string up edges between coupled
// faces (all edges between same (global)face indices get extruded).
labelListList edgeGlobalFaces
(
addPatchCellLayer::globalEdgeFaces
(
mesh,
globalFaces,
pp
)
);
// Determine patches for extruded boundary edges. Calculates if any
// additional processor patches need to be constructed.
labelList sidePatchID;
determineSidePatches
(
globalFaces,
edgeGlobalFaces,
pp,
sidePatchID
);
// Construct iterative mesh mover. // Construct iterative mesh mover.
Info<< "Constructing mesh displacer ..." << endl; Info<< "Constructing mesh displacer ..." << endl;
@ -3038,8 +3104,12 @@ void Foam::autoLayerDriver::addLayers
// Not add layer if patchDisp is zero. // Not add layer if patchDisp is zero.
addLayer.setRefinement addLayer.setRefinement
( (
globalFaces,
edgeGlobalFaces,
invExpansionRatio, invExpansionRatio,
pp(), pp(),
sidePatchID, // boundary patch for extruded boundary edges
labelList(0), // exposed patchIDs, not used for adding layers labelList(0), // exposed patchIDs, not used for adding layers
nPatchFaceLayers, // layers per face nPatchFaceLayers, // layers per face
nPatchPointLayers, // layers per point nPatchPointLayers, // layers per point

View File

@ -2,7 +2,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) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -243,6 +243,16 @@ class autoLayerDriver
List<extrudeMode>& extrudeStatus List<extrudeMode>& extrudeStatus
) const; ) const;
//- See what patches boundaryedges should be extruded into
void determineSidePatches
(
const globalIndex& globalFaces,
const labelListList& edgeGlobalFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID
);
//- Calculate pointwise wanted and minimum thickness. //- Calculate pointwise wanted and minimum thickness.
// thickness: wanted thickness // thickness: wanted thickness
// minthickness: when to give up and not extrude // minthickness: when to give up and not extrude

View File

@ -1549,60 +1549,28 @@ void Foam::meshRefinement::checkCoupledFaceZones(const polyMesh& mesh)
} }
// Adds patch if not yet there. Returns patchID. Foam::label Foam::meshRefinement::appendPatch
Foam::label Foam::meshRefinement::addPatch
( (
fvMesh& mesh, fvMesh& mesh,
const label insertPatchI,
const word& patchName, const word& patchName,
const dictionary& patchInfo const dictionary& patchDict
) )
{ {
polyBoundaryMesh& polyPatches =
const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
const label patchI = polyPatches.findPatchID(patchName);
if (patchI != -1)
{
// Already there
return patchI;
}
label insertPatchI = polyPatches.size();
label startFaceI = mesh.nFaces();
forAll(polyPatches, patchI)
{
const polyPatch& pp = polyPatches[patchI];
if (isA<processorPolyPatch>(pp))
{
insertPatchI = patchI;
startFaceI = pp.start();
break;
}
}
// Below is all quite a hack. Feel free to change once there is a better
// mechanism to insert and reorder patches.
// Clear local fields and e.g. polyMesh parallelInfo. // Clear local fields and e.g. polyMesh parallelInfo.
mesh.clearOut(); mesh.clearOut();
label sz = polyPatches.size(); polyBoundaryMesh& polyPatches =
const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary()); fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary());
dictionary patchDict(patchInfo); label patchI = polyPatches.size();
patchDict.set("nFaces", 0);
patchDict.set("startFace", startFaceI);
// Add polyPatch at the end // Add polyPatch at the end
polyPatches.setSize(sz+1); polyPatches.setSize(patchI+1);
polyPatches.set polyPatches.set
( (
sz, patchI,
polyPatch::New polyPatch::New
( (
patchName, patchName,
@ -1611,13 +1579,13 @@ Foam::label Foam::meshRefinement::addPatch
polyPatches polyPatches
) )
); );
fvPatches.setSize(sz+1); fvPatches.setSize(patchI+1);
fvPatches.set fvPatches.set
( (
sz, patchI,
fvPatch::New fvPatch::New
( (
polyPatches[sz], // point to newly added polyPatch polyPatches[patchI], // point to newly added polyPatch
mesh.boundary() mesh.boundary()
) )
); );
@ -1675,21 +1643,69 @@ Foam::label Foam::meshRefinement::addPatch
mesh, mesh,
calculatedFvPatchField<tensor>::typeName calculatedFvPatchField<tensor>::typeName
); );
return patchI;
}
// Adds patch if not yet there. Returns patchID.
Foam::label Foam::meshRefinement::addPatch
(
fvMesh& mesh,
const word& patchName,
const dictionary& patchInfo
)
{
polyBoundaryMesh& polyPatches =
const_cast<polyBoundaryMesh&>(mesh.boundaryMesh());
fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary());
const label patchI = polyPatches.findPatchID(patchName);
if (patchI != -1)
{
// Already there
return patchI;
}
label insertPatchI = polyPatches.size();
label startFaceI = mesh.nFaces();
forAll(polyPatches, patchI)
{
const polyPatch& pp = polyPatches[patchI];
if (isA<processorPolyPatch>(pp))
{
insertPatchI = patchI;
startFaceI = pp.start();
break;
}
}
dictionary patchDict(patchInfo);
patchDict.set("nFaces", 0);
patchDict.set("startFace", startFaceI);
// Below is all quite a hack. Feel free to change once there is a better
// mechanism to insert and reorder patches.
label addedPatchI = appendPatch(mesh, insertPatchI, patchName, patchDict);
// Create reordering list // Create reordering list
// patches before insert position stay as is // patches before insert position stay as is
labelList oldToNew(sz+1); labelList oldToNew(addedPatchI+1);
for (label i = 0; i < insertPatchI; i++) for (label i = 0; i < insertPatchI; i++)
{ {
oldToNew[i] = i; oldToNew[i] = i;
} }
// patches after insert position move one up // patches after insert position move one up
for (label i = insertPatchI; i < sz; i++) for (label i = insertPatchI; i < addedPatchI; i++)
{ {
oldToNew[i] = i+1; oldToNew[i] = i+1;
} }
// appended patch gets moved to insert position // appended patch gets moved to insert position
oldToNew[sz] = insertPatchI; oldToNew[addedPatchI] = insertPatchI;
// Shuffle into place // Shuffle into place
polyPatches.reorder(oldToNew); polyPatches.reorder(oldToNew);

View File

@ -2,7 +2,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) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -747,8 +747,17 @@ public:
// Other topo changes // Other topo changes
//- Helper:append patch to end of mesh.
static label appendPatch
(
fvMesh&,
const label insertPatchI,
const word&,
const dictionary&
);
//- Helper:add patch to mesh. Update all registered fields. //- Helper:add patch to mesh. Update all registered fields.
// Use addMeshedPatch to add patches originating from surfaces. // Used by addMeshedPatch to add patches originating from surfaces.
static label addPatch(fvMesh&, const word& name, const dictionary&); static label addPatch(fvMesh&, const word& name, const dictionary&);
//- Add patch originating from meshing. Update meshedPatches_. //- Add patch originating from meshing. Update meshedPatches_.

View File

@ -2,7 +2,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) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -1007,6 +1007,82 @@ void Foam::refinementSurfaces::findNearestRegion
} }
void Foam::refinementSurfaces::findNearestRegion
(
const labelList& surfacesToTest,
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,
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];
}
}
}
//// Find intersection with max of edge. Return -1 or the surface //// Find intersection with max of edge. Return -1 or the surface
//// with the highest maxLevel above currentLevel //// with the highest maxLevel above currentLevel
//Foam::label Foam::refinementSurfaces::findHighestIntersection //Foam::label Foam::refinementSurfaces::findHighestIntersection

View File

@ -2,7 +2,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) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -327,6 +327,19 @@ public:
labelList& hitRegion labelList& hitRegion
) const; ) const;
//- Find nearest point on surfaces. Return surface, region and
// normal on surface (so not global surface)
void findNearestRegion
(
const labelList& surfacesToTest,
const pointField& samples,
const scalarField& nearestDistSqr,
labelList& hitSurface,
List<pointIndexHit>& hitInfo,
labelList& hitRegion,
vectorField& hitNormal
) const;
//- Detect if a point is 'inside' (closed) surfaces. //- Detect if a point is 'inside' (closed) surfaces.
// Returns -1 if not, returns first surface it is. // Returns -1 if not, returns first surface it is.
void findInside void findInside