Merge branch 'feature-snappyHexMesh' into 'develop'

Feature snappy hex mesh

It's got all of the VW snappyHexMesh developments in it.

Not yet the automatic-gap refinement.

See merge request !1
This commit is contained in:
Andrew Heather
2015-11-09 11:36:13 +00:00
111 changed files with 13326 additions and 6598 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

@ -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.
@ -234,6 +234,25 @@ Foam::IOobject::IOobject
} }
Foam::IOobject::IOobject
(
const IOobject& io,
const word& name
)
:
name_(name),
headerClassName_(io.headerClassName_),
note_(io.note_),
instance_(io.instance_),
local_(io.local_),
db_(io.db_),
rOpt_(io.rOpt_),
wOpt_(io.wOpt_),
registerObject_(io.registerObject_),
objState_(io.objState_)
{}
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
Foam::IOobject::~IOobject() Foam::IOobject::~IOobject()

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.
@ -236,6 +236,13 @@ public:
bool registerObject=true bool registerObject=true
); );
//- Construct as copy resetting name
IOobject
(
const IOobject& io,
const word& name
);
//- Clone //- Clone
Foam::autoPtr<IOobject> clone() const Foam::autoPtr<IOobject> clone() const
{ {

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.
@ -2748,7 +2748,13 @@ void Foam::globalMeshData::updateMesh()
// *** Temporary hack to avoid problems with overlapping communication // *** Temporary hack to avoid problems with overlapping communication
// *** between these reductions and the calculation of deltaCoeffs // *** between these reductions and the calculation of deltaCoeffs
label comm = UPstream::worldComm + 1; //label comm = UPstream::worldComm + 1;
label comm = UPstream::allocateCommunicator
(
UPstream::worldComm,
identity(UPstream::nProcs(UPstream::worldComm)),
true
);
// Total number of faces. // Total number of faces.
nTotalFaces_ = returnReduce nTotalFaces_ = returnReduce
@ -2785,6 +2791,8 @@ void Foam::globalMeshData::updateMesh()
comm comm
); );
UPstream::freeCommunicator(comm);
if (debug) if (debug)
{ {
Pout<< "globalMeshData : nTotalPoints_:" << nTotalPoints_ << endl; Pout<< "globalMeshData : nTotalPoints_:" << nTotalPoints_ << 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) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -164,7 +164,8 @@ public:
const polyMesh&, const polyMesh&,
UList<T>&, UList<T>&,
const CombineOp& cop, const CombineOp& cop,
const TransformOp& top const TransformOp& top,
const bool parRun = Pstream::parRun()
); );
@ -556,7 +557,8 @@ public:
( (
const polyMesh& mesh, const polyMesh& mesh,
PackedList<nBits>& faceValues, PackedList<nBits>& faceValues,
const CombineOp& cop const CombineOp& cop,
const bool parRun = Pstream::parRun()
); );
template<unsigned nBits> template<unsigned nBits>

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -1316,7 +1316,8 @@ void Foam::syncTools::syncBoundaryFaceList
const polyMesh& mesh, const polyMesh& mesh,
UList<T>& faceValues, UList<T>& faceValues,
const CombineOp& cop, const CombineOp& cop,
const TransformOp& top const TransformOp& top,
const bool parRun
) )
{ {
const label nBFaces = mesh.nFaces() - mesh.nInternalFaces(); const label nBFaces = mesh.nFaces() - mesh.nInternalFaces();
@ -1327,7 +1328,7 @@ void Foam::syncTools::syncBoundaryFaceList
( (
"syncTools<class T, class CombineOp>::syncBoundaryFaceList" "syncTools<class T, class CombineOp>::syncBoundaryFaceList"
"(const polyMesh&, UList<T>&, const CombineOp&" "(const polyMesh&, UList<T>&, const CombineOp&"
", const bool)" ", const TransformOp&, const bool)"
) << "Number of values " << faceValues.size() ) << "Number of values " << faceValues.size()
<< " is not equal to the number of boundary faces in the mesh " << " is not equal to the number of boundary faces in the mesh "
<< nBFaces << abort(FatalError); << nBFaces << abort(FatalError);
@ -1335,7 +1336,7 @@ void Foam::syncTools::syncBoundaryFaceList
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (Pstream::parRun()) if (parRun)
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);
@ -1441,7 +1442,8 @@ void Foam::syncTools::syncFaceList
( (
const polyMesh& mesh, const polyMesh& mesh,
PackedList<nBits>& faceValues, PackedList<nBits>& faceValues,
const CombineOp& cop const CombineOp& cop,
const bool parRun
) )
{ {
if (faceValues.size() != mesh.nFaces()) if (faceValues.size() != mesh.nFaces())
@ -1457,7 +1459,7 @@ void Foam::syncTools::syncFaceList
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
if (Pstream::parRun()) if (parRun)
{ {
PstreamBuffers pBufs(Pstream::nonBlocking); PstreamBuffers pBufs(Pstream::nonBlocking);

View File

@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::pointList
Description
A List of points
Typedef
Foam::pointListList
Description
A List of labelList
\*---------------------------------------------------------------------------*/
#ifndef pointList_H
#define pointList_H
#include "point.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Note: frequently used UList version is located in container itself
typedef List<point> pointList;
typedef List<pointList> pointListList;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#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 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.
@ -28,6 +28,14 @@ License
#include "faceCoupleInfo.H" #include "faceCoupleInfo.H"
#include "fvMesh.H" #include "fvMesh.H"
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
namespace Foam
{
defineTypeNameAndDebug(fvMeshAdder, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- Calculate map from new patch faces to old patch faces. -1 where //- Calculate map from new patch faces to old patch faces. -1 where
@ -108,6 +116,12 @@ Foam::autoPtr<Foam::mapAddedPolyMesh> Foam::fvMeshAdder::add
fvMeshAdder::MapSurfaceFields<symmTensor>(mapPtr, mesh0, mesh1); fvMeshAdder::MapSurfaceFields<symmTensor>(mapPtr, mesh0, mesh1);
fvMeshAdder::MapSurfaceFields<tensor>(mapPtr, mesh0, mesh1); fvMeshAdder::MapSurfaceFields<tensor>(mapPtr, mesh0, mesh1);
fvMeshAdder::MapDimFields<scalar>(mapPtr, mesh0, mesh1);
fvMeshAdder::MapDimFields<vector>(mapPtr, mesh0, mesh1);
fvMeshAdder::MapDimFields<sphericalTensor>(mapPtr, mesh0, mesh1);
fvMeshAdder::MapDimFields<symmTensor>(mapPtr, mesh0, mesh1);
fvMeshAdder::MapDimFields<tensor>(mapPtr, mesh0, mesh1);
return mapPtr; return mapPtr;
} }

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.
@ -26,7 +26,7 @@ Class
Description Description
Adds two fvMeshes without using any polyMesh morphing. Adds two fvMeshes without using any polyMesh morphing.
Uses fvMeshAdder. Uses polyMeshAdder.
SourceFiles SourceFiles
fvMeshAdder.C fvMeshAdder.C
@ -42,6 +42,7 @@ SourceFiles
#include "fvPatchFieldsFwd.H" #include "fvPatchFieldsFwd.H"
#include "fvsPatchFieldsFwd.H" #include "fvsPatchFieldsFwd.H"
#include "fvPatchFieldMapper.H" #include "fvPatchFieldMapper.H"
#include "DimensionedField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -101,8 +102,22 @@ private:
const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd
); );
//- Update single dimensionedField.
template<class Type>
static void MapDimField
(
const mapAddedPolyMesh& meshMap,
DimensionedField<Type, volMesh>& fld,
const DimensionedField<Type, volMesh>& fldToAdd
);
public: public:
// Declare name of the class and its debug switch
ClassName("fvMeshAdder");
// Member Functions // Member Functions
//- Inplace add mesh to fvMesh. Maps all stored fields. Returns map. //- Inplace add mesh to fvMesh. Maps all stored fields. Returns map.
@ -131,6 +146,15 @@ public:
const fvMesh& mesh, const fvMesh& mesh,
const fvMesh& meshToAdd const fvMesh& meshToAdd
); );
//- Map all DimensionedFields of Type
template<class Type>
static void MapDimFields
(
const mapAddedPolyMesh&,
const fvMesh& mesh,
const fvMesh& meshToAdd
);
}; };

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.
@ -280,6 +280,12 @@ void Foam::fvMeshAdder::MapVolFields
++fieldIter ++fieldIter
) )
{ {
if (debug)
{
Pout<< "MapVolFields : Storing old time for " << fieldIter()->name()
<< endl;
}
const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter()) const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
->storeOldTimes(); ->storeOldTimes();
} }
@ -304,6 +310,12 @@ void Foam::fvMeshAdder::MapVolFields
const GeometricField<Type, fvPatchField, volMesh>& fldToAdd = const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
*fieldsToAdd[fld.name()]; *fieldsToAdd[fld.name()];
if (debug)
{
Pout<< "MapVolFields : mapping " << fld.name()
<< " and " << fldToAdd.name() << endl;
}
MapVolField<Type>(meshMap, fld, fldToAdd); MapVolField<Type>(meshMap, fld, fldToAdd);
} }
else else
@ -585,8 +597,13 @@ void Foam::fvMeshAdder::MapSurfaceFields
++fieldIter ++fieldIter
) )
{ {
const_cast<fldType*>(fieldIter()) if (debug)
->storeOldTimes(); {
Pout<< "MapSurfaceFields : Storing old time for "
<< fieldIter()->name() << endl;
}
const_cast<fldType*>(fieldIter())->storeOldTimes();
} }
@ -604,6 +621,12 @@ void Foam::fvMeshAdder::MapSurfaceFields
{ {
const fldType& fldToAdd = *fieldsToAdd[fld.name()]; const fldType& fldToAdd = *fieldsToAdd[fld.name()];
if (debug)
{
Pout<< "MapSurfaceFields : mapping " << fld.name()
<< " and " << fldToAdd.name() << endl;
}
MapSurfaceField<Type>(meshMap, fld, fldToAdd); MapSurfaceField<Type>(meshMap, fld, fldToAdd);
} }
else else
@ -617,4 +640,80 @@ void Foam::fvMeshAdder::MapSurfaceFields
} }
template<class Type>
void Foam::fvMeshAdder::MapDimField
(
const mapAddedPolyMesh& meshMap,
DimensionedField<Type, volMesh>& fld,
const DimensionedField<Type, volMesh>& fldToAdd
)
{
const fvMesh& mesh = fld.mesh();
// Store old field
Field<Type> oldField(fld);
fld.setSize(mesh.nCells());
fld.rmap(oldField, meshMap.oldCellMap());
fld.rmap(fldToAdd, meshMap.addedCellMap());
}
template<class Type>
void Foam::fvMeshAdder::MapDimFields
(
const mapAddedPolyMesh& meshMap,
const fvMesh& mesh,
const fvMesh& meshToAdd
)
{
typedef DimensionedField<Type, volMesh> fldType;
// Note: use strict flag on lookupClass to avoid picking up
// volFields
HashTable<const fldType*> fields
(
mesh.objectRegistry::lookupClass<fldType>(true)
);
HashTable<const fldType*> fieldsToAdd
(
meshToAdd.objectRegistry::lookupClass<fldType>(true)
);
for
(
typename HashTable<const fldType*>::
iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
fldType& fld = const_cast<fldType&>(*fieldIter());
if (fieldsToAdd.found(fld.name()))
{
const fldType& fldToAdd = *fieldsToAdd[fld.name()];
if (debug)
{
Pout<< "MapDimFields : mapping " << fld.name()
<< " and " << fldToAdd.name() << endl;
}
MapDimField<Type>(meshMap, fld, fldToAdd);
}
else
{
WarningIn("fvMeshAdder::MapDimFields(..)")
<< "Not mapping field " << fld.name()
<< " since not present on mesh to add"
<< 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) 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.
@ -332,6 +332,17 @@ public:
const dictionary& paramDict() const; const dictionary& paramDict() const;
//- Return reference to the point motion displacement field
pointVectorField& pointDisplacement()
{
return displacement_;
}
//- Return const reference to the point motion displacement field
const pointVectorField& pointDisplacement() const
{
return displacement_;
}
// Edit // Edit
@ -339,7 +350,6 @@ public:
//- Take over existing mesh position. //- Take over existing mesh position.
void correct(); void correct();
//- Set patch fields on patchIDs to be consistent with //- Set patch fields on patchIDs to be consistent with
// all other boundary conditions // all other boundary conditions
static void setDisplacementPatchFields static void setDisplacementPatchFields
@ -471,6 +481,7 @@ public:
const bool report, const bool report,
const dictionary& dict, const dictionary& dict,
const polyMeshGeometry&, const polyMeshGeometry&,
const pointField&,
const labelList& checkFaces, const labelList& checkFaces,
labelHashSet& wrongFaces labelHashSet& wrongFaces
); );
@ -483,6 +494,7 @@ public:
const bool report, const bool report,
const dictionary& dict, const dictionary& dict,
const polyMeshGeometry&, const polyMeshGeometry&,
const pointField&,
const labelList& checkFaces, const labelList& checkFaces,
const List<labelPair>& baffles, const List<labelPair>& baffles,
labelHashSet& wrongFaces labelHashSet& wrongFaces

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.
@ -434,6 +434,7 @@ bool Foam::motionSmootherAlgo::checkMesh
const bool report, const bool report,
const dictionary& dict, const dictionary& dict,
const polyMeshGeometry& meshGeom, const polyMeshGeometry& meshGeom,
const pointField& points,
const labelList& checkFaces, const labelList& checkFaces,
labelHashSet& wrongFaces labelHashSet& wrongFaces
) )
@ -445,6 +446,7 @@ bool Foam::motionSmootherAlgo::checkMesh
report, report,
dict, dict,
meshGeom, meshGeom,
points,
checkFaces, checkFaces,
emptyBaffles, emptyBaffles,
wrongFaces wrongFaces
@ -457,6 +459,7 @@ bool Foam::motionSmootherAlgo::checkMesh
const bool report, const bool report,
const dictionary& dict, const dictionary& dict,
const polyMeshGeometry& meshGeom, const polyMeshGeometry& meshGeom,
const pointField& points,
const labelList& checkFaces, const labelList& checkFaces,
const List<labelPair>& baffles, const List<labelPair>& baffles,
labelHashSet& wrongFaces labelHashSet& wrongFaces
@ -482,14 +485,14 @@ bool Foam::motionSmootherAlgo::checkMesh
( (
readScalar(dict.lookup("minArea", true)) readScalar(dict.lookup("minArea", true))
); );
//const scalar maxIntSkew const scalar maxIntSkew
//( (
// readScalar(dict.lookup("maxInternalSkewness", true)) readScalar(dict.lookup("maxInternalSkewness", true))
//); );
//const scalar maxBounSkew const scalar maxBounSkew
//( (
// readScalar(dict.lookup("maxBoundarySkewness", true)) readScalar(dict.lookup("maxBoundarySkewness", true))
//); );
const scalar minWeight const scalar minWeight
( (
readScalar(dict.lookup("minFaceWeight", true)) readScalar(dict.lookup("minFaceWeight", true))
@ -512,7 +515,6 @@ bool Foam::motionSmootherAlgo::checkMesh
( (
readScalar(dict.lookup("minDeterminant", true)) readScalar(dict.lookup("minDeterminant", true))
); );
label nWrongFaces = 0; label nWrongFaces = 0;
Info<< "Checking faces in error :" << endl; Info<< "Checking faces in error :" << endl;
@ -544,8 +546,8 @@ bool Foam::motionSmootherAlgo::checkMesh
meshGeom.checkFacePyramids meshGeom.checkFacePyramids
( (
report, report,
minVol, minTetQuality,
meshGeom.mesh().points(), points,
checkFaces, checkFaces,
baffles, baffles,
&wrongFaces &wrongFaces
@ -566,7 +568,7 @@ bool Foam::motionSmootherAlgo::checkMesh
( (
report, report,
minTetQuality, minTetQuality,
meshGeom.mesh().points(), points,
checkFaces, checkFaces,
baffles, baffles,
&wrongFaces &wrongFaces
@ -587,7 +589,7 @@ bool Foam::motionSmootherAlgo::checkMesh
( (
report, report,
maxConcave, maxConcave,
meshGeom.mesh().points(), points,
checkFaces, checkFaces,
&wrongFaces &wrongFaces
); );
@ -604,7 +606,13 @@ bool Foam::motionSmootherAlgo::checkMesh
if (minArea > -SMALL) if (minArea > -SMALL)
{ {
meshGeom.checkFaceArea(report, minArea, checkFaces, &wrongFaces); meshGeom.checkFaceArea
(
report,
minArea,
checkFaces,
&wrongFaces
);
label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>()); label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());
@ -616,30 +624,32 @@ bool Foam::motionSmootherAlgo::checkMesh
nWrongFaces = nNewWrongFaces; nWrongFaces = nNewWrongFaces;
} }
if (maxIntSkew > 0 || maxBounSkew > 0)
{
polyMeshGeometry::checkFaceSkewness
(
report,
maxIntSkew,
maxBounSkew,
meshGeom.mesh(),
points,
meshGeom.cellCentres(),
meshGeom.faceCentres(),
meshGeom.faceAreas(),
checkFaces,
baffles,
&wrongFaces
);
//- Note: cannot check the skewness without the points and don't want label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());
// to store them on polyMeshGeometry.
//if (maxIntSkew > 0 || maxBounSkew > 0) Info<< " faces with skewness > "
//{ << setw(3) << maxIntSkew
// meshGeom.checkFaceSkewness << " (internal) or " << setw(3) << maxBounSkew
// ( << " (boundary) : " << nNewWrongFaces-nWrongFaces << endl;
// report,
// maxIntSkew, nWrongFaces = nNewWrongFaces;
// maxBounSkew, }
// checkFaces,
// baffles,
// &wrongFaces
// );
//
// label nNewWrongFaces = returnReduce(wrongFaces.size(),sumOp<label>());
//
// Info<< " faces with skewness > "
// << setw(3) << maxIntSkew
// << " (internal) or " << setw(3) << maxBounSkew
// << " (boundary) : " << nNewWrongFaces-nWrongFaces << endl;
//
// nWrongFaces = nNewWrongFaces;
//}
if (minWeight >= 0 && minWeight < 1) if (minWeight >= 0 && minWeight < 1)
{ {
@ -691,7 +701,7 @@ bool Foam::motionSmootherAlgo::checkMesh
( (
report, report,
minTwist, minTwist,
meshGeom.mesh().points(), points,
checkFaces, checkFaces,
&wrongFaces &wrongFaces
); );
@ -714,7 +724,7 @@ bool Foam::motionSmootherAlgo::checkMesh
( (
report, report,
minTriangleTwist, minTriangleTwist,
meshGeom.mesh().points(), points,
checkFaces, checkFaces,
&wrongFaces &wrongFaces
); );
@ -729,13 +739,13 @@ bool Foam::motionSmootherAlgo::checkMesh
nWrongFaces = nNewWrongFaces; nWrongFaces = nNewWrongFaces;
} }
if (minFaceFlatness > -1) if (minFaceFlatness > -SMALL)
{ {
meshGeom.checkFaceFlatness meshGeom.checkFaceFlatness
( (
report, report,
minFaceFlatness, minFaceFlatness,
meshGeom.mesh().points(), points,
checkFaces, checkFaces,
&wrongFaces &wrongFaces
); );
@ -757,7 +767,7 @@ bool Foam::motionSmootherAlgo::checkMesh
report, report,
minDet, minDet,
checkFaces, checkFaces,
meshGeom.affectedCells(meshGeom.mesh(), checkFaces), polyMeshGeometry::affectedCells(meshGeom.mesh(), checkFaces),
&wrongFaces &wrongFaces
); );

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.
@ -105,86 +105,82 @@ void Foam::polyMeshGeometry::updateCellCentresAndVols
const labelList& changedFaces const labelList& changedFaces
) )
{ {
const labelList& own = mesh().faceOwner();
const cellList& cells = mesh().cells();
// Clear the fields for accumulation // Clear the fields for accumulation
UIndirectList<vector>(cellCentres_, changedCells) = vector::zero; UIndirectList<vector>(cellCentres_, changedCells) = vector::zero;
UIndirectList<scalar>(cellVolumes_, changedCells) = 0.0; UIndirectList<scalar>(cellVolumes_, changedCells) = 0.0;
const labelList& own = mesh_.faceOwner();
const labelList& nei = mesh_.faceNeighbour();
// first estimate the approximate cell centre as the average of face centres // Re-calculate the changed cell centres and volumes
forAll(changedCells, changedCellI)
vectorField cEst(mesh_.nCells());
UIndirectList<vector>(cEst, changedCells) = vector::zero;
scalarField nCellFaces(mesh_.nCells());
UIndirectList<scalar>(nCellFaces, changedCells) = 0.0;
forAll(changedFaces, i)
{ {
label faceI = changedFaces[i]; const label cellI(changedCells[changedCellI]);
cEst[own[faceI]] += faceCentres_[faceI];
nCellFaces[own[faceI]] += 1;
if (mesh_.isInternalFace(faceI)) const labelList& cFaces(cells[cellI]);
// Estimate the cell centre and bounding box using the face centres
vector cEst = vector::zero;
boundBox bb(boundBox::invertedBox);
forAll(cFaces, cFaceI)
{ {
cEst[nei[faceI]] += faceCentres_[faceI]; const point& fc = faceCentres_[cFaces[cFaceI]];
nCellFaces[nei[faceI]] += 1; cEst += fc;
} bb.max() = max(bb.max(), fc);
bb.min() = min(bb.min(), fc);
} }
cEst /= cFaces.size();
forAll(changedCells, i)
// Sum up the face-pyramid contributions
forAll(cFaces, cFaceI)
{ {
label cellI = changedCells[i]; const label faceI(cFaces[cFaceI]);
cEst[cellI] /= nCellFaces[cellI];
}
forAll(changedFaces, i) // Calculate 3* the face-pyramid volume
scalar pyr3Vol = faceAreas_[faceI] & (faceCentres_[faceI] - cEst);
if (own[faceI] != cellI)
{ {
label faceI = changedFaces[i]; pyr3Vol = -pyr3Vol;
}
// Calculate 3*face-pyramid volume
scalar pyr3Vol = max
(
faceAreas_[faceI] & (faceCentres_[faceI] - cEst[own[faceI]]),
VSMALL
);
// Calculate face-pyramid centre
vector pc = (3.0/4.0)*faceCentres_[faceI] + (1.0/4.0)*cEst[own[faceI]];
// Accumulate volume-weighted face-pyramid centre
cellCentres_[own[faceI]] += pyr3Vol*pc;
// Accumulate face-pyramid volume // Accumulate face-pyramid volume
cellVolumes_[own[faceI]] += pyr3Vol; cellVolumes_[cellI] += pyr3Vol;
if (mesh_.isInternalFace(faceI)) // Calculate the face-pyramid centre
{ const vector pCtr = (3.0/4.0)*faceCentres_[faceI] + (1.0/4.0)*cEst;
// Calculate 3*face-pyramid volume
scalar pyr3Vol = max
(
faceAreas_[faceI] & (cEst[nei[faceI]] - faceCentres_[faceI]),
VSMALL
);
// Calculate face-pyramid centre
vector pc =
(3.0/4.0)*faceCentres_[faceI]
+ (1.0/4.0)*cEst[nei[faceI]];
// Accumulate volume-weighted face-pyramid centre // Accumulate volume-weighted face-pyramid centre
cellCentres_[nei[faceI]] += pyr3Vol*pc; cellCentres_[cellI] += pyr3Vol*pCtr;
// Accumulate face-pyramid volume
cellVolumes_[nei[faceI]] += pyr3Vol;
}
} }
forAll(changedCells, i) // Average the accumulated quantities
if (mag(cellVolumes_[cellI]) > VSMALL)
{ {
label cellI = changedCells[i]; point cc = cellCentres_[cellI] / cellVolumes_[cellI];
// Do additional check for collapsed cells since some volumes
// (e.g. 1e-33) do not trigger above but do return completely
// wrong cell centre
if (bb.contains(cc))
{
cellCentres_[cellI] = cc;
}
else
{
cellCentres_[cellI] = cEst;
}
}
else
{
cellCentres_[cellI] = cEst;
}
cellCentres_[cellI] /= cellVolumes_[cellI] + VSMALL;
cellVolumes_[cellI] *= (1.0/3.0); cellVolumes_[cellI] *= (1.0/3.0);
} }
} }

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) 2012-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-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.
@ -31,25 +31,23 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(displacementMotionSolver, 0); defineTypeNameAndDebug(displacementMotionSolver, 0);
defineRunTimeSelectionTable(displacementMotionSolver, displacement);
} }
// * * * * * * * * * * * * * Protected Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::IOobject Foam::displacementMotionSolver::points0IO Foam::IOobject Foam::displacementMotionSolver::points0IO(const polyMesh& mesh)
(
const polyMesh& mesh
) const
{ {
const word instance = const word instance =
time().findInstance mesh.time().findInstance
( (
mesh.meshDir(), mesh.meshDir(),
"points0", "points0",
IOobject::READ_IF_PRESENT IOobject::READ_IF_PRESENT
); );
if (instance != time().constant()) if (instance != mesh.time().constant())
{ {
// points0 written to a time folder // points0 written to a time folder
@ -58,7 +56,7 @@ Foam::IOobject Foam::displacementMotionSolver::points0IO
( (
"points0", "points0",
instance, instance,
polyMesh::meshSubDir, mesh.meshDir(),
mesh, mesh,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -73,7 +71,7 @@ Foam::IOobject Foam::displacementMotionSolver::points0IO
( (
"points0", "points0",
instance, instance,
polyMesh::meshSubDir, mesh.meshDir(),
mesh, mesh,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -93,7 +91,7 @@ Foam::IOobject Foam::displacementMotionSolver::points0IO
( (
"points", "points",
instance, instance,
polyMesh::meshSubDir, mesh.meshDir(),
mesh, mesh,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -142,12 +140,11 @@ Foam::displacementMotionSolver::displacementMotionSolver
) << "Number of points in mesh " << mesh.nPoints() ) << "Number of points in mesh " << mesh.nPoints()
<< " differs from number of points " << points0_.size() << " differs from number of points " << points0_.size()
<< " read from file " << " read from file "
<< << IOobject
IOobject
( (
"points", "points",
time().constant(), time().constant(),
polyMesh::meshSubDir, mesh.meshDir(),
mesh, mesh,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -158,6 +155,104 @@ Foam::displacementMotionSolver::displacementMotionSolver
} }
Foam::displacementMotionSolver::displacementMotionSolver
(
const polyMesh& mesh,
const IOdictionary& dict,
const pointVectorField& pointDisplacement,
const pointIOField& points0,
const word& type
)
:
motionSolver(mesh, dict, type),
pointDisplacement_
(
IOobject(pointDisplacement, "pointDisplacement"),
pointDisplacement
),
points0_(points0)
{
if (points0_.size() != mesh.nPoints())
{
FatalErrorIn
(
"displacementMotionSolver::"
"displacementMotionSolver\n"
"(\n"
" const polyMesh&,\n"
" const IOdictionary&,\n"
" const pointVectorField&,\n"
" const pointIOField&,\n"
" const word&\n"
")"
) << "Number of points in mesh " << mesh.nPoints()
<< " differs from number of points " << points0_.size()
<< " read from file " << points0.filePath()
<< exit(FatalError);
}
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::displacementMotionSolver>
Foam::displacementMotionSolver::New
(
const word& solverTypeName,
const polyMesh& mesh,
const IOdictionary& solverDict,
const pointVectorField& pointDisplacement,
const pointIOField& points0
)
{
//const word solverTypeName(solverDict.lookup("solver"));
Info<< "Selecting motion solver: " << solverTypeName << endl;
const_cast<Time&>(mesh.time()).libs().open
(
solverDict,
"motionSolverLibs",
displacementConstructorTablePtr_
);
if (!displacementConstructorTablePtr_)
{
FatalErrorIn
(
"displacementMotionSolver::New(const polyMesh& mesh)"
) << "solver table is empty"
<< exit(FatalError);
}
displacementConstructorTable::iterator cstrIter =
displacementConstructorTablePtr_->find(solverTypeName);
if (cstrIter == displacementConstructorTablePtr_->end())
{
FatalErrorIn
(
"displacementMotionSolver::New(const polyMesh&)"
) << "Unknown solver type "
<< solverTypeName << nl << nl
<< "Valid solver types are:" << endl
<< displacementConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<displacementMotionSolver>
(
cstrIter()
(
mesh,
solverDict,
pointDisplacement,
points0
)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::displacementMotionSolver::~displacementMotionSolver() Foam::displacementMotionSolver::~displacementMotionSolver()

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) 2012-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-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.
@ -68,14 +68,8 @@ protected:
pointIOField points0_; pointIOField points0_;
// Protected Member Functions
//- Return IO object for points0
IOobject points0IO(const polyMesh& mesh) const;
private: private:
// Private Member Functions // Private Member Functions
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
@ -84,12 +78,49 @@ private:
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const displacementMotionSolver&); void operator=(const displacementMotionSolver&);
public: public:
//- Runtime type information //- Runtime type information
TypeName("displacementMotionSolver"); TypeName("displacementMotionSolver");
// Declare run-time constructor selection tables
declareRunTimeSelectionTable
(
autoPtr,
displacementMotionSolver,
displacement,
(
const polyMesh& mesh,
const IOdictionary& dict,
const pointVectorField& pointDisplacement,
const pointIOField& points0
),
(mesh, dict, pointDisplacement, points0)
);
// Static Member Functions
//- Return IO object for points0
static IOobject points0IO(const polyMesh& mesh);
// Selectors
//- Select constructed from polyMesh, dictionary and components.
// If dictionary was registered this will 'steal' that registration.
static autoPtr<displacementMotionSolver> New
(
const word& solverTypeName,
const polyMesh&,
const IOdictionary&,
const pointVectorField& pointDisplacement,
const pointIOField& points0
);
// Constructors // Constructors
//- Construct from mesh and dictionary //- Construct from mesh and dictionary
@ -100,6 +131,16 @@ public:
const word& type const word& type
); );
//- Construct from mesh and dictionary
displacementMotionSolver
(
const polyMesh&,
const IOdictionary&,
const pointVectorField& pointDisplacement,
const pointIOField& points0,
const word& type
);
//- Destructor //- Destructor
virtual ~displacementMotionSolver(); virtual ~displacementMotionSolver();

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -67,7 +67,9 @@ private:
dictionary coeffDict_; dictionary coeffDict_;
// Private Member Functions protected:
// Protected Member Functions
//- De-register object if registered and assign to current //- De-register object if registered and assign to current
static IOobject stealRegistration(const IOdictionary& dict); static IOobject stealRegistration(const IOdictionary& dict);

View File

@ -0,0 +1,199 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "velocityDisplacementMotionSolver.H"
#include "displacementMotionSolver.H"
#include "fixedValuePointPatchField.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(velocityDisplacementMotionSolver, 0);
addToRunTimeSelectionTable
(
motionSolver,
velocityDisplacementMotionSolver,
dictionary
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::wordList
Foam::velocityDisplacementMotionSolver::pointDisplacementBoundaryTypes() const
{
const pointVectorField::GeometricBoundaryField& pmUbf
(
pointMotionU().boundaryField()
);
wordList cmUbf = pmUbf.types();
forAll(pmUbf, patchI)
{
if (isA<fixedValuePointPatchField<vector> >(pmUbf[patchI]))
{
cmUbf[patchI] = fixedValuePointPatchField<vector>::typeName;
}
}
return cmUbf;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::velocityDisplacementMotionSolver::velocityDisplacementMotionSolver
(
const polyMesh& mesh,
const IOdictionary& dict
)
:
velocityMotionSolver(mesh, dict, typeName),
displacementMotionSolverPtr_()
{
pointIOField points0(displacementMotionSolver::points0IO(mesh));
pointVectorField pointDisplacement
(
IOobject
(
"pointVelocityDisplacement",
mesh.time().timeName(),
mesh
),
pointMotionU().mesh(),
dimLength,
pointDisplacementBoundaryTypes()
);
pointDisplacement.internalField() = mesh.points() - points0;
displacementMotionSolverPtr_.set
(
dynamic_cast<displacementMotionSolver*>
(
displacementMotionSolver::New
(
coeffDict().lookup("solver"),
mesh,
IOdictionary
(
IOobject
(
dict.name() + "Coeffs",
mesh.time().constant(),
mesh
),
coeffDict()
),
pointDisplacement,
points0
).ptr()
)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::velocityDisplacementMotionSolver::~velocityDisplacementMotionSolver()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::pointField>
Foam::velocityDisplacementMotionSolver::curPoints() const
{
return displacementMotionSolverPtr_->curPoints();
}
void Foam::velocityDisplacementMotionSolver::solve()
{
movePoints(mesh().points());
const scalar deltaT(mesh().time().deltaTValue());
// Current and old point displacements
pointVectorField& displacement
(
displacementMotionSolverPtr_->pointDisplacement()
);
const vectorField displacementOld
(
mesh().points() - displacementMotionSolverPtr_->points0()
);
// Update the velocity boundary conditions
pointMotionU().correctBoundaryConditions();
// Update the displacement boundary conditions
forAll(pointMotionU().boundaryField(), patchI)
{
const pointPatchVectorField& patchField
(
pointMotionU().boundaryField()[patchI]
);
displacement.boundaryField()[patchI] ==
patchField.patchInternalField()*deltaT
+ patchField.patchInternalField(displacementOld);
}
// Run the sub-solver
displacementMotionSolverPtr_->solve();
// Update the velocity
pointMotionU().internalField() =
(displacement.internalField() - displacementOld)/deltaT;
}
void Foam::velocityDisplacementMotionSolver::movePoints(const pointField& p)
{
velocityMotionSolver::movePoints(p);
displacementMotionSolverPtr_->movePoints(p);
}
void Foam::velocityDisplacementMotionSolver::updateMesh
(
const mapPolyMesh& mpm
)
{
velocityMotionSolver::updateMesh(mpm);
displacementMotionSolverPtr_->updateMesh(mpm);
}
// ************************************************************************* //

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::velocityDisplacementMotionSolver
Description
Mesh motion solver for a polyMesh. Wraps a displacement motion solver in a
velocity motion solver.
SourceFiles
velocityDisplacementMotionSolver.C
\*---------------------------------------------------------------------------*/
#ifndef velocityDisplacementMotionSolver_H
#define velocityDisplacementMotionSolver_H
#include "velocityMotionSolver.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward class declarations
class displacementMotionSolver;
/*---------------------------------------------------------------------------*\
Class velocityDisplacementMotionSolver Declaration
\*---------------------------------------------------------------------------*/
class velocityDisplacementMotionSolver
:
public velocityMotionSolver
{
// Private data
//- Displacement motion solver
autoPtr<displacementMotionSolver> displacementMotionSolverPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct
velocityDisplacementMotionSolver
(
const velocityDisplacementMotionSolver&
);
//- Disallow default bitwise assignment
void operator=(const velocityDisplacementMotionSolver&);
//- Get the boundary condition types for the point displacement
wordList pointDisplacementBoundaryTypes() const;
public:
//- Runtime type information
TypeName("velocityDisplacement");
// Constructors
//- Construct from polyMesh and IOdictionary
velocityDisplacementMotionSolver
(
const polyMesh&,
const IOdictionary&
);
//- Destructor
~velocityDisplacementMotionSolver();
// Member Functions
//- Return point location obtained from the current motion field
virtual tmp<pointField> curPoints() const;
//- Solve for motion
virtual void solve();
//- Update geometry
virtual void movePoints(const pointField&);
//- Update topology
virtual void updateMesh(const mapPolyMesh&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#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.
@ -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

@ -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 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.

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

@ -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.
@ -498,6 +498,21 @@ void Foam::polyTopoChange::makeCells
{ {
if (faceOwner_[faceI] < 0) if (faceOwner_[faceI] < 0)
{ {
pointField newPoints;
if (faceI < faces_.size())
{
const face& f = faces_[faceI];
newPoints.setSize(f.size(), vector::max);
forAll(f, fp)
{
if (f[fp] < points_.size())
{
newPoints[fp] = points_[f[fp]];
}
}
}
FatalErrorIn FatalErrorIn
( (
"polyTopoChange::makeCells\n" "polyTopoChange::makeCells\n"
@ -506,7 +521,9 @@ void Foam::polyTopoChange::makeCells
" labelList&,\n" " labelList&,\n"
" labelList&\n" " labelList&\n"
") const\n" ") const\n"
) << "Face " << faceI << " is active but its owner has" ) << "Face " << faceI
<< " with vertices " << newPoints
<< " is active but its owner has"
<< " been deleted. This is usually due to deleting cells" << " been deleted. This is usually due to deleting cells"
<< " without modifying exposed faces to be boundary faces." << " without modifying exposed faces to be boundary faces."
<< exit(FatalError); << exit(FatalError);

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 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.
@ -116,13 +116,23 @@ Foam::labelList Foam::removeCells::getExposedFaces
} }
// Coupled faces: add number of cells using face across couple. // Coupled faces: add number of cells using face across couple.
if (syncPar_)
{ {
syncTools::syncFaceList // Note cyclics done always, parallel bits only done if syncPar_
SubList<label> bndValues
(
nCellsUsingFace,
mesh_.nFaces()-mesh_.nInternalFaces(),
mesh_.nInternalFaces()
);
syncTools::syncBoundaryFaceList
( (
mesh_, mesh_,
nCellsUsingFace, bndValues,
plusEqOp<label>() plusEqOp<label>(),
mapDistribute::transform(),
syncPar_
); );
} }

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) 2012-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-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.
@ -149,7 +149,7 @@ Foam::label Foam::tetDecomposer::triIndex(const label faceI, const label fp)
const const
{ {
const face& f = mesh_.faces()[faceI]; const face& f = mesh_.faces()[faceI];
const label fp0 = mesh_.tetBasePtIs()[faceI]; const label fp0 = max(0, mesh_.tetBasePtIs()[faceI]);
// Work out triangle index on this face // Work out triangle index on this face
label thisTriI; label thisTriI;
@ -436,7 +436,7 @@ void Foam::tetDecomposer::setRefinement
} }
else else
{ {
label fp0 = mesh_.tetBasePtIs()[faceI]; label fp0 = max(mesh_.tetBasePtIs()[faceI], 0);
label fp = f.fcIndex(fp0); label fp = f.fcIndex(fp0);
for (label triI = 0; triI < f.size()-2; triI++) for (label triI = 0; triI < f.size()-2; triI++)

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

@ -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.
@ -810,6 +810,79 @@ void Foam::FaceCellWave<Type, TrackingData>::handleAMICyclicPatches()
} }
template<class Type, class TrackingData>
void Foam::FaceCellWave<Type, TrackingData>::handleExplicitConnections()
{
// Collect changed information
DynamicList<label> f0Baffle(explicitConnections_.size());
DynamicList<Type> f0Info(explicitConnections_.size());
DynamicList<label> f1Baffle(explicitConnections_.size());
DynamicList<Type> f1Info(explicitConnections_.size());
forAll(explicitConnections_, connI)
{
const labelPair& baffle = explicitConnections_[connI];
label f0 = baffle[0];
if (changedFace_[f0])
{
f0Baffle.append(connI);
f0Info.append(allFaceInfo_[f0]);
}
label f1 = baffle[1];
if (changedFace_[f1])
{
f1Baffle.append(connI);
f1Info.append(allFaceInfo_[f1]);
}
}
// Update other side with changed information
forAll(f1Info, index)
{
const labelPair& baffle = explicitConnections_[f1Baffle[index]];
label f0 = baffle[0];
Type& currentWallInfo = allFaceInfo_[f0];
if (!currentWallInfo.equal(f1Info[index], td_))
{
updateFace
(
f0,
f1Info[index],
propagationTol_,
currentWallInfo
);
}
}
forAll(f0Info, index)
{
const labelPair& baffle = explicitConnections_[f0Baffle[index]];
label f1 = baffle[1];
Type& currentWallInfo = allFaceInfo_[f1];
if (!currentWallInfo.equal(f0Info[index], td_))
{
updateFace
(
f1,
f0Info[index],
propagationTol_,
currentWallInfo
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Set up only. Use setFaceInfo and iterate() to do actual calculation. // Set up only. Use setFaceInfo and iterate() to do actual calculation.
@ -823,6 +896,7 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
) )
: :
mesh_(mesh), mesh_(mesh),
explicitConnections_(0),
allFaceInfo_(allFaceInfo), allFaceInfo_(allFaceInfo),
allCellInfo_(allCellInfo), allCellInfo_(allCellInfo),
td_(td), td_(td),
@ -878,6 +952,7 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
) )
: :
mesh_(mesh), mesh_(mesh),
explicitConnections_(0),
allFaceInfo_(allFaceInfo), allFaceInfo_(allFaceInfo),
allCellInfo_(allCellInfo), allCellInfo_(allCellInfo),
td_(td), td_(td),
@ -939,6 +1014,87 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
} }
// Iterate, propagating changedFacesInfo across mesh, until no change (or
// maxIter reached). Initial cell values specified.
template<class Type, class TrackingData>
Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
(
const polyMesh& mesh,
const List<labelPair>& explicitConnections,
const bool handleCyclicAMI,
const labelList& changedFaces,
const List<Type>& changedFacesInfo,
UList<Type>& allFaceInfo,
UList<Type>& allCellInfo,
const label maxIter,
TrackingData& td
)
:
mesh_(mesh),
explicitConnections_(explicitConnections),
allFaceInfo_(allFaceInfo),
allCellInfo_(allCellInfo),
td_(td),
changedFace_(mesh_.nFaces(), false),
changedFaces_(mesh_.nFaces()),
nChangedFaces_(0),
changedCell_(mesh_.nCells(), false),
changedCells_(mesh_.nCells()),
nChangedCells_(0),
hasCyclicPatches_(hasPatch<cyclicPolyPatch>()),
hasCyclicAMIPatches_
(
handleCyclicAMI
&& returnReduce(hasPatch<cyclicAMIPolyPatch>(), orOp<bool>())
),
nEvals_(0),
nUnvisitedCells_(mesh_.nCells()),
nUnvisitedFaces_(mesh_.nFaces())
{
if
(
allFaceInfo.size() != mesh_.nFaces()
|| allCellInfo.size() != mesh_.nCells()
)
{
FatalErrorIn
(
"FaceCellWave<Type, TrackingData>::FaceCellWave"
"(const polyMesh&, const List<labelPair>&, const labelList&"
", const List<Type>,"
" UList<Type>&, UList<Type>&, const label maxIter)"
) << "face and cell storage not the size of mesh faces, cells:"
<< endl
<< " allFaceInfo :" << allFaceInfo.size() << endl
<< " mesh_.nFaces():" << mesh_.nFaces() << endl
<< " allCellInfo :" << allCellInfo.size() << endl
<< " mesh_.nCells():" << mesh_.nCells()
<< exit(FatalError);
}
// Copy initial changed faces data
setFaceInfo(changedFaces, changedFacesInfo);
// Iterate until nothing changes
label iter = iterate(maxIter);
if ((maxIter > 0) && (iter >= maxIter))
{
FatalErrorIn
(
"FaceCellWave<Type, TrackingData>::FaceCellWave"
"(const polyMesh&, const List<labelPair>&, const labelList&"
", const List<Type>, UList<Type>&, UList<Type>&"
", const label maxIter)"
) << "Maximum number of iterations reached. Increase maxIter." << endl
<< " maxIter:" << maxIter << endl
<< " nChangedCells:" << nChangedCells_ << endl
<< " nChangedFaces:" << nChangedFaces_ << endl
<< exit(FatalError);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -1093,6 +1249,10 @@ Foam::label Foam::FaceCellWave<Type, TrackingData>::cellToFace()
// Handled all changed cells by now // Handled all changed cells by now
nChangedCells_ = 0; nChangedCells_ = 0;
// Transfer across any explicitly provided internal connections
handleExplicitConnections();
if (hasCyclicPatches_) if (hasCyclicPatches_)
{ {
// Transfer changed faces across cyclic halves // Transfer changed faces across cyclic halves

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -50,6 +50,7 @@ SourceFiles
#include "boolList.H" #include "boolList.H"
#include "labelList.H" #include "labelList.H"
#include "primitiveFieldsFwd.H" #include "primitiveFieldsFwd.H"
#include "labelPair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -81,6 +82,9 @@ class FaceCellWave
//- Reference to mesh //- Reference to mesh
const polyMesh& mesh_; const polyMesh& mesh_;
//- Optional boundary faces that information should travel through
const List<labelPair> explicitConnections_;
//- Information for all faces //- Information for all faces
UList<Type>& allFaceInfo_; UList<Type>& allFaceInfo_;
@ -232,6 +236,10 @@ class FaceCellWave
//- Merge data from across AMI cyclics //- Merge data from across AMI cyclics
void handleAMICyclicPatches(); void handleAMICyclicPatches();
//- Merge data across explicitly provided local connections (usually
// baffles)
void handleExplicitConnections();
// Private static data // Private static data
@ -286,6 +294,23 @@ public:
TrackingData& td = dummyTrackData_ TrackingData& td = dummyTrackData_
); );
//- Construct from mesh and explicitly connected boundary faces
// and list of changed faces with the Type
// for these faces. Iterates until nothing changes or maxIter reached.
// (maxIter can be 0)
FaceCellWave
(
const polyMesh&,
const List<labelPair>& explicitConnections,
const bool handleCyclicAMI,
const labelList& initialChangedFaces,
const List<Type>& changedFacesInfo,
UList<Type>& allFaceInfo,
UList<Type>& allCellInfo,
const label maxIter,
TrackingData& td = dummyTrackData_
);
// Member Functions // Member Functions

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-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 "PointData.H"
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class DataType>
Foam::Ostream& Foam::operator<<(Ostream& os, const PointData<DataType>& pd)
{
if (os.format() == IOstream::ASCII)
{
return os
<< static_cast<const pointEdgePoint&>(pd)
<< token::SPACE << pd.data();
}
else
{
return os
<< static_cast<const pointEdgePoint&>(pd)
<< pd.data();
}
}
template<class DataType>
Foam::Istream& Foam::operator>>(Istream& is, PointData<DataType>& pd)
{
return is >> static_cast<pointEdgePoint&>(pd) >> pd.data_;
}
// ************************************************************************* //

View File

@ -0,0 +1,211 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-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::PointData
Description
Variant of pointEdgePoint with some transported additional data. Templated
on the transported data type.
SourceFiles
PointDataI.H
PointData.C
\*---------------------------------------------------------------------------*/
#ifndef PointData_H
#define PointData_H
#include "pointEdgePoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class Istream;
class Ostream;
template<class DataType>
class PointData;
// Forward declaration of friend functions and operators
template<class DataType>
Ostream& operator<<(Ostream&, const PointData<DataType>&);
template<class DataType>
Istream& operator>>(Istream&, PointData<DataType>&);
/*---------------------------------------------------------------------------*\
Class PointData Declaration
\*---------------------------------------------------------------------------*/
template<class DataType>
class PointData
:
public pointEdgePoint
{
private:
// Private data
//- Additional transported data
DataType data_;
public:
// Constructors
//- Construct null
inline PointData();
//- Construct from origin, distance and data
inline PointData
(
const point& origin,
const scalar distSqr,
const DataType& data
);
//- Construct as copy
inline PointData(const PointData&);
// Member Functions
// Access
//- Const access the data
inline const DataType& data() const;
// Needed by meshWave
//- Apply rotation matrix to the data
template<class TrackingData>
inline void transform
(
const tensor& rotTensor,
TrackingData& td
);
//- Influence of edge on point
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointI,
const label edgeI,
const PointData<DataType>& edgeInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// Merge new and old info.
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointI,
const PointData<DataType>& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// No information about current position whatsoever.
template<class TrackingData>
inline bool updatePoint
(
const PointData<DataType>& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of point on edge.
template<class TrackingData>
inline bool updateEdge
(
const polyMesh& mesh,
const label edgeI,
const label pointI,
const PointData<DataType>& pointInfo,
const scalar tol,
TrackingData& td
);
// Member Operators
inline bool operator==(const PointData<DataType>&) const;
inline bool operator!=(const PointData<DataType>&) const;
// IOstream Operators
friend Ostream& operator<< <DataType>
(
Ostream&,
const PointData<DataType>&
);
friend Istream& operator>> <DataType>
(
Istream&,
PointData<DataType>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Data associated with PointData types is contiguous
template<>
inline bool contiguous<PointData<scalar> >()
{
return true;
}
template<>
inline bool contiguous<PointData<vector> >()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "PointDataI.H"
#ifdef NoRepository
# include "PointData.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,234 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-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 "polyMesh.H"
#include "transform.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class DataType>
inline Foam::PointData<DataType>::PointData()
:
pointEdgePoint()
{}
template<class DataType>
inline Foam::PointData<DataType>::PointData
(
const point& origin,
const scalar distSqr,
const DataType& data
)
:
pointEdgePoint(origin, distSqr),
data_(data)
{}
template<class DataType>
inline Foam::PointData<DataType>::PointData(const PointData<DataType>& wpt)
:
pointEdgePoint(wpt),
data_(wpt.data())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class DataType>
inline const DataType& Foam::PointData<DataType>::data() const
{
return data_;
}
template<class DataType>
template<class TrackingData>
inline void Foam::PointData<DataType>::transform
(
const tensor& rotTensor,
TrackingData& td
)
{
pointEdgePoint::transform(rotTensor, td);
data_ = Foam::transform(rotTensor, data_);
}
template<class DataType>
template<class TrackingData>
inline bool Foam::PointData<DataType>::updatePoint
(
const polyMesh& mesh,
const label pointI,
const label edgeI,
const PointData<DataType>& edgeInfo,
const scalar tol,
TrackingData& td
)
{
if
(
pointEdgePoint::updatePoint
(
mesh,
pointI,
edgeI,
edgeInfo,
tol,
td
)
)
{
data_ = edgeInfo.data_;
return true;
}
else
{
return false;
}
}
template<class DataType>
template<class TrackingData>
inline bool Foam::PointData<DataType>::updatePoint
(
const polyMesh& mesh,
const label pointI,
const PointData<DataType>& newPointInfo,
const scalar tol,
TrackingData& td
)
{
if
(
pointEdgePoint::updatePoint
(
mesh,
pointI,
newPointInfo,
tol,
td
)
)
{
data_ = newPointInfo.data_;
return true;
}
else
{
return false;
}
}
template<class DataType>
template<class TrackingData>
inline bool Foam::PointData<DataType>::updatePoint
(
const PointData<DataType>& newPointInfo,
const scalar tol,
TrackingData& td
)
{
if (pointEdgePoint::updatePoint(newPointInfo, tol, td))
{
data_ = newPointInfo.data_;
return true;
}
else
{
return false;
}
}
template<class DataType>
template<class TrackingData>
inline bool Foam::PointData<DataType>::updateEdge
(
const polyMesh& mesh,
const label edgeI,
const label pointI,
const PointData<DataType>& pointInfo,
const scalar tol,
TrackingData& td
)
{
if
(
pointEdgePoint::updateEdge
(
mesh,
edgeI,
pointI,
pointInfo,
tol,
td
)
)
{
data_ = pointInfo.data_;
return true;
}
else
{
return false;
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class DataType>
inline bool Foam::PointData<DataType>::operator==
(
const Foam::PointData<DataType>& rhs
)
const
{
return pointEdgePoint::operator==(rhs) && (data() == rhs.data());
}
template<class DataType>
inline bool Foam::PointData<DataType>::operator!=
(
const Foam::PointData<DataType>& rhs
)
const
{
return !(*this == rhs);
}
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -188,8 +188,10 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
<< " nearest face:" << faceI; << " nearest face:" << faceI;
} }
const pointField& points = patch_.localPoints(); const typename PatchType::FaceType& localF = patch_.localFaces()[faceI];
const typename PatchType::FaceType& f = patch_.localFaces()[faceI]; const typename PatchType::FaceType& f = patch_[faceI];
const pointField& points = patch_.points();
const labelList& mp = patch_.meshPoints();
// Retest to classify where on face info is. Note: could be improved. We // Retest to classify where on face info is. Note: could be improved. We
// already have point. // already have point.
@ -242,7 +244,7 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
return indexedOctree<treeDataPrimitivePatch>::getSide return indexedOctree<treeDataPrimitivePatch>::getSide
( (
patch_.pointNormals()[f[fp]], patch_.pointNormals()[localF[fp]],
sample - curPt sample - curPt
); );
} }
@ -280,8 +282,8 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
{ {
label edgeI = fEdges[fEdgeI]; label edgeI = fEdges[fEdgeI];
const edge& e = patch_.edges()[edgeI]; const edge& e = patch_.edges()[edgeI];
const linePointRef ln(points[mp[e.start()]], points[mp[e.end()]]);
pointHit edgeHit = e.line(points).nearestDist(sample); pointHit edgeHit = ln.nearestDist(sample);
if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_) if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_)
{ {
@ -322,11 +324,7 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
forAll(f, fp) forAll(f, fp)
{ {
pointHit edgeHit = linePointRef pointHit edgeHit = linePointRef(points[f[fp]], fc).nearestDist(sample);
(
points[f[fp]],
fc
).nearestDist(sample);
if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_) if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_)
{ {
@ -369,7 +367,8 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
forAll(f, fp) forAll(f, fp)
{ {
Pout<< " vertex:" << f[fp] << " coord:" << points[f[fp]] Pout<< " vertex:" << f[fp]
<< " coord:" << points[f[fp]]
<< endl; << 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) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,7 +29,6 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Check if n is in same direction as normals of all faceLabels
bool Foam::meshTools::visNormal bool Foam::meshTools::visNormal
( (
const vector& n, const vector& n,
@ -309,7 +308,6 @@ bool Foam::meshTools::edgeOnFace
} }
// Return true if faceI part of cellI
bool Foam::meshTools::faceOnCell bool Foam::meshTools::faceOnCell
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,
@ -465,7 +463,6 @@ Foam::label Foam::meshTools::getSharedFace
} }
// Get the two faces on cellI using edgeI.
void Foam::meshTools::getEdgeFaces void Foam::meshTools::getEdgeFaces
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,
@ -511,7 +508,6 @@ void Foam::meshTools::getEdgeFaces
} }
// Return label of other edge connected to vertex
Foam::label Foam::meshTools::otherEdge Foam::label Foam::meshTools::otherEdge
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,
@ -549,7 +545,6 @@ Foam::label Foam::meshTools::otherEdge
} }
// Return face on other side of edgeI
Foam::label Foam::meshTools::otherFace Foam::label Foam::meshTools::otherFace
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,
@ -574,7 +569,6 @@ Foam::label Foam::meshTools::otherFace
} }
// Return face on other side of edgeI
Foam::label Foam::meshTools::otherCell Foam::label Foam::meshTools::otherCell
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,
@ -602,8 +596,6 @@ Foam::label Foam::meshTools::otherCell
} }
// Returns label of edge nEdges away from startEdge (in the direction of
// startVertI)
Foam::label Foam::meshTools::walkFace Foam::label Foam::meshTools::walkFace
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,
@ -688,7 +680,6 @@ void Foam::meshTools::constrainToMeshCentre
} }
//- Set the constrained components of directions/velocity to zero
void Foam::meshTools::constrainDirection void Foam::meshTools::constrainDirection
( (
const polyMesh& mesh, const polyMesh& mesh,
@ -814,7 +805,6 @@ Foam::vector Foam::meshTools::edgeToCutDir
} }
// Find edges most aligned with cutDir
Foam::label Foam::meshTools::cutDirToEdge Foam::label Foam::meshTools::cutDirToEdge
( (
const primitiveMesh& mesh, const primitiveMesh& mesh,

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.
@ -200,7 +200,7 @@ namespace meshTools
const label v1 const label v1
); );
//- Return edge between two vertices. Returns -1 if no edge. //- Return edge between two mesh vertices. Returns -1 if no edge.
label findEdge label findEdge
( (
const primitiveMesh&, const primitiveMesh&,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -242,6 +242,7 @@ void Foam::localPointRegion::countPointRegions
void Foam::localPointRegion::calcPointRegions void Foam::localPointRegion::calcPointRegions
( (
const polyMesh& mesh, const polyMesh& mesh,
const labelPairList& baffles,
boolList& candidatePoint boolList& candidatePoint
) )
{ {
@ -423,6 +424,13 @@ void Foam::localPointRegion::calcPointRegions
minEqOpFace(), minEqOpFace(),
Foam::dummyTransform() // dummy transformation Foam::dummyTransform() // dummy transformation
); );
forAll(baffles, i)
{
label f0 = baffles[i].first();
label f1 = baffles[i].second();
minEqOpFace()(minRegion[f0], minRegion[f1]);
minRegion[f1] = minRegion[f0];
}
} }
@ -469,7 +477,7 @@ Foam::localPointRegion::localPointRegion(const polyMesh& mesh)
} }
} }
calcPointRegions(mesh, candidatePoint); calcPointRegions(mesh, labelPairList(0), candidatePoint);
} }
@ -492,7 +500,31 @@ Foam::localPointRegion::localPointRegion
candidatePoint[candidatePoints[i]] = true; candidatePoint[candidatePoints[i]] = true;
} }
calcPointRegions(mesh, candidatePoint); calcPointRegions(mesh, labelPairList(0), candidatePoint);
}
Foam::localPointRegion::localPointRegion
(
const polyMesh& mesh,
const labelPairList& baffles,
const labelList& candidatePoints
)
:
//nRegions_(0),
meshPointMap_(0),
pointRegions_(0),
meshFaceMap_(0),
faceRegions_(0)
{
boolList candidatePoint(mesh.nPoints(), false);
forAll(candidatePoints, i)
{
candidatePoint[candidatePoints[i]] = true;
}
calcPointRegions(mesh, baffles, candidatePoint);
} }
@ -630,16 +662,20 @@ Foam::List<Foam::labelPair> Foam::localPointRegion::findDuplicateFacePairs
<< " processorPolyPatch." << " processorPolyPatch."
<< "This is not allowed." << nl << "This is not allowed." << nl
<< "Face:" << meshFace0 << "Face:" << meshFace0
<< " fc:" << mesh.faceCentres()[meshFace0]
<< " is on patch:" << patches[patch0].name() << " is on patch:" << patches[patch0].name()
<< nl << nl
<< "Face:" << meshFace1 << "Face:" << meshFace1
<< " fc:" << mesh.faceCentres()[meshFace1]
<< " is on patch:" << patches[patch1].name() << " is on patch:" << patches[patch1].name()
<< abort(FatalError); << abort(FatalError);
} }
else
{
baffles.append(labelPair(meshFace0, meshFace1)); baffles.append(labelPair(meshFace0, meshFace1));
} }
} }
}
return baffles.shrink(); return baffles.shrink();
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -101,10 +101,10 @@ class localPointRegion
void calcPointRegions void calcPointRegions
( (
const polyMesh& mesh, const polyMesh& mesh,
const labelPairList& baffles,
boolList& candidatePoint boolList& candidatePoint
); );
//- Check if two faces are equal. If forward = false checks f1 in //- Check if two faces are equal. If forward = false checks f1 in
// reverse order. // reverse order.
static bool isDuplicate static bool isDuplicate
@ -133,6 +133,14 @@ public:
const labelList& candidatePoints const labelList& candidatePoints
); );
//- Construct from mesh and candidate points for duplication
localPointRegion
(
const polyMesh& mesh,
const labelPairList& baffles,
const labelList& candidatePoints
);
// Member Functions // Member Functions

View File

@ -0,0 +1,401 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 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 "searchableRotatedBox.H"
#include "addToRunTimeSelectionTable.H"
#include "axesRotation.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(searchableRotatedBox, 0);
addToRunTimeSelectionTable(searchableSurface, searchableRotatedBox, dict);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::searchableRotatedBox::searchableRotatedBox
(
const IOobject& io,
const dictionary& dict
)
:
searchableSurface(io),
box_
(
IOobject
(
io.name() + "_box",
io.instance(),
io.local(),
io.db(),
io.readOpt(),
io.writeOpt(),
false, //io.registerObject(),
io.globalObject()
),
treeBoundBox(point::zero, dict.lookup("span"))
),
transform_
(
"rotation",
dict.lookup("origin"),
dict.lookup("e3"),
dict.lookup("e1")
)
{
points_ = transform_.globalPosition(box_.points());
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::searchableRotatedBox::~searchableRotatedBox()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::wordList& Foam::searchableRotatedBox::regions() const
{
return box_.regions();
}
Foam::tmp<Foam::pointField> Foam::searchableRotatedBox::coordinates() const
{
return transform_.globalPosition(box_.coordinates());
}
void Foam::searchableRotatedBox::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
box_.boundingSpheres(centres, radiusSqr);
centres = transform_.globalPosition(centres);
}
Foam::tmp<Foam::pointField> Foam::searchableRotatedBox::points() const
{
return points_;
}
bool Foam::searchableRotatedBox::overlaps(const boundBox& bb) const
{
// (from treeDataPrimitivePatch.C)
// 1. bounding box
if (!bb.overlaps(bounds()))
{
return false;
}
// 2. Check if one or more face points inside
const faceList& fcs = treeBoundBox::faces;
forAll(fcs, faceI)
{
if (bb.containsAny(points_))
{
return true;
}
}
// 3. Difficult case: all points are outside but connecting edges might
// go through cube.
const treeBoundBox treeBb(bb);
// 3a. my edges through bb faces
const edgeList& edges = treeBoundBox::edges;
forAll(edges, edgeI)
{
const edge& e = edges[edgeI];
point inter;
if (treeBb.intersects(points_[e[0]], points_[e[1]], inter))
{
return true;
}
}
// 3b. bb edges through my faces
const pointField bbPoints(bb.points());
forAll(fcs, faceI)
{
const face& f = fcs[faceI];
point fc = f.centre(points_);
forAll(edges, edgeI)
{
const edge& e = edges[edgeI];
pointHit inter = f.intersection
(
bbPoints[e[0]],
bbPoints[e[1]],
fc,
points_,
intersection::HALF_RAY
);
if (inter.hit() && inter.distance() <= 1)
{
return true;
}
}
}
return false;
}
Foam::pointIndexHit Foam::searchableRotatedBox::findNearest
(
const point& sample,
const scalar nearestDistSqr
) const
{
pointIndexHit boxNearest
(
box_.findNearest
(
transform_.localPosition(sample),
nearestDistSqr
)
);
boxNearest.rawPoint() = transform_.globalPosition(boxNearest.rawPoint());
return boxNearest;
}
Foam::pointIndexHit Foam::searchableRotatedBox::findNearest
(
const linePointRef& ln,
treeBoundBox& tightest,
point& linePoint
) const
{
notImplemented
(
"searchableRotatedBox::findNearest"
"(const linePointRef&, treeBoundBox&, point&)"
);
return pointIndexHit();
}
Foam::pointIndexHit Foam::searchableRotatedBox::findLine
(
const point& start,
const point& end
) const
{
pointIndexHit boxHit
(
box_.findLine
(
transform_.localPosition(start),
transform_.localPosition(end)
)
);
boxHit.rawPoint() = transform_.globalPosition(boxHit.rawPoint());
return boxHit;
}
Foam::pointIndexHit Foam::searchableRotatedBox::findLineAny
(
const point& start,
const point& end
) const
{
return findLine(start, end);
}
void Foam::searchableRotatedBox::findNearest
(
const pointField& samples,
const scalarField& nearestDistSqr,
List<pointIndexHit>& info
) const
{
info.setSize(samples.size());
forAll(samples, i)
{
info[i] = findNearest(samples[i], nearestDistSqr[i]);
}
}
void Foam::searchableRotatedBox::findLine
(
const pointField& start,
const pointField& end,
List<pointIndexHit>& info
) const
{
info.setSize(start.size());
forAll(start, i)
{
info[i] = findLine(start[i], end[i]);
}
}
void Foam::searchableRotatedBox::findLineAny
(
const pointField& start,
const pointField& end,
List<pointIndexHit>& info
) const
{
info.setSize(start.size());
forAll(start, i)
{
info[i] = findLineAny(start[i], end[i]);
}
}
void Foam::searchableRotatedBox::findLineAll
(
const pointField& start,
const pointField& end,
List<List<pointIndexHit> >& info
) const
{
info.setSize(start.size());
// Work array
DynamicList<pointIndexHit, 1, 1> hits;
// Tolerances:
// To find all intersections we add a small vector to the last intersection
// This is chosen such that
// - it is significant (SMALL is smallest representative relative tolerance;
// we need something bigger since we're doing calculations)
// - if the start-end vector is zero we still progress
const vectorField dirVec(end-start);
const scalarField magSqrDirVec(magSqr(dirVec));
const vectorField smallVec
(
Foam::sqrt(SMALL)*dirVec
+ vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
);
forAll(start, pointI)
{
// See if any intersection between pt and end
pointIndexHit inter = findLine(start[pointI], end[pointI]);
if (inter.hit())
{
hits.clear();
hits.append(inter);
point pt = inter.hitPoint() + smallVec[pointI];
while (((pt-start[pointI])&dirVec[pointI]) <= magSqrDirVec[pointI])
{
// See if any intersection between pt and end
pointIndexHit inter = findLine(pt, end[pointI]);
// Check for not hit or hit same face as before (can happen
// if vector along surface of face)
if
(
!inter.hit()
|| (inter.index() == hits.last().index())
)
{
break;
}
hits.append(inter);
pt = inter.hitPoint() + smallVec[pointI];
}
info[pointI].transfer(hits);
}
else
{
info[pointI].clear();
}
}
}
void Foam::searchableRotatedBox::getRegion
(
const List<pointIndexHit>& info,
labelList& region
) const
{
region.setSize(info.size());
region = 0;
}
void Foam::searchableRotatedBox::getNormal
(
const List<pointIndexHit>& info,
vectorField& normal
) const
{
// searchableBox does not use hitPoints so no need to transform
box_.getNormal(info, normal);
normal = transform_.globalVector(normal);
}
void Foam::searchableRotatedBox::getVolumeType
(
const pointField& points,
List<volumeType>& volType
) const
{
box_.getVolumeType(transform_.localPosition(points), volType);
}
// ************************************************************************* //

View File

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 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::searchableRotatedBox
Description
Searching on a rotated box
Box defined as min and max coordinate. Rotation by coordinate system
at box middle.
E.g. box with sides 1 1 1 rotated 45 degrees around z-axis at
origin (0.5 0.5 0.5)
\verbatim
span (1 1 1);
origin (0.5 0.5 0.5);
e1 (1 1 0);
e3 (0 0 1);
\endverbatim
SourceFiles
searchableRotatedBox.C
\*---------------------------------------------------------------------------*/
#ifndef searchableRotatedBox_H
#define searchableRotatedBox_H
#include "searchableSurface.H"
#include "coordinateSystem.H"
#include "searchableBox.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
/*---------------------------------------------------------------------------*\
Class searchableRotatedBox Declaration
\*---------------------------------------------------------------------------*/
class searchableRotatedBox
:
public searchableSurface
{
private:
// Private Member Data
//- box in local coordinate system
searchableBox box_;
//- transformation from local to global coordinates
coordinateSystem transform_;
//- (global) corner points (in treeBoundBox order)
pointField points_;
// Private Member Functions
//- Disallow default bitwise copy construct
searchableRotatedBox(const searchableRotatedBox&);
//- Disallow default bitwise assignment
void operator=(const searchableRotatedBox&);
public:
//- Runtime type information
TypeName("searchableRotatedBox");
// Constructors
//- Construct from dictionary (used by searchableSurface)
searchableRotatedBox
(
const IOobject& io,
const dictionary& dict
);
//- Destructor
virtual ~searchableRotatedBox();
// Member Functions
virtual const wordList& regions() const;
//- Whether supports volume type below
virtual bool hasVolumeType() const
{
return true;
}
//- Range of local indices that can be returned.
virtual label size() const
{
return 6;
}
//- Get representative set of element coordinates
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const;
// Does any part of the surface overlap the supplied bound box?
virtual bool overlaps(const boundBox& bb) const;
// Single point queries.
//- Calculate nearest point on surface.
// Returns
// - bool : any point found nearer than nearestDistSqr
// - label: relevant index in surface (=face 0..5)
// - point: actual nearest point found
pointIndexHit findNearest
(
const point& sample,
const scalar nearestDistSqr
) const;
//- Find nearest to segment.
// Returns
// - bool : any point found?
// - label: relevant index in shapes (=face 0..5)
// - point: actual nearest point found
// sets:
// - tightest : bounding box
// - linePoint : corresponding nearest point on line
pointIndexHit findNearest
(
const linePointRef& ln,
treeBoundBox& tightest,
point& linePoint
) const;
//- Find nearest intersection of line between start and end.
pointIndexHit findLine
(
const point& start,
const point& end
) const;
//- Find any intersection of line between start and end.
pointIndexHit findLineAny
(
const point& start,
const point& end
) const;
// Multiple point queries.
virtual void findNearest
(
const pointField& sample,
const scalarField& nearestDistSqr,
List<pointIndexHit>&
) const;
virtual void findLine
(
const pointField& start,
const pointField& end,
List<pointIndexHit>&
) const;
virtual void findLineAny
(
const pointField& start,
const pointField& end,
List<pointIndexHit>&
) const;
//- Get all intersections in order from start to end.
virtual void findLineAll
(
const pointField& start,
const pointField& end,
List<List<pointIndexHit> >&
) const;
//- From a set of points and indices get the region
virtual void getRegion
(
const List<pointIndexHit>&,
labelList& region
) const;
//- From a set of points and indices get the normal
virtual void getNormal
(
const List<pointIndexHit>&,
vectorField& normal
) const;
//- Determine type (inside/outside/mixed) for point. unknown if
// cannot be determined (e.g. non-manifold surface)
virtual void getVolumeType
(
const pointField&,
List<volumeType>&
) const;
// regIOobject implementation
bool writeData(Ostream&) const
{
notImplemented
(
"searchableRotatedBox::writeData(Ostream&) const"
);
return false;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,8 +25,8 @@ Class
Foam::searchableSurfaceCollection Foam::searchableSurfaceCollection
Description Description
Set of transformed searchableSurfaces. Does not do boolean operations. Set of transformed searchableSurfaces. Does not do boolean operations
So when meshing might find parts 'inside'. so when meshing might find parts 'inside'.
SourceFiles SourceFiles
searchableSurfaceCollection.C searchableSurfaceCollection.C
@ -47,8 +47,6 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class searchableSurfaceCollection Declaration Class searchableSurfaceCollection Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/

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.
@ -34,6 +34,22 @@ Description
- extend the test vector slightly (with SMALL) to account for numerical - extend the test vector slightly (with SMALL) to account for numerical
inaccuracies. inaccuracies.
\verbatim
sphere.stl
{
type triSurfaceMesh;
}
sphere
{
type searchableSurfaceWithGaps;
// Underlying surface
surface sphere.stl;
// Perturb distance
gap 1e-3;
}
\endverbatim
SourceFiles SourceFiles
searchableSurfaceWithGaps.C searchableSurfaceWithGaps.C

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,9 +27,7 @@ License
#include "searchableSurfacesQueries.H" #include "searchableSurfacesQueries.H"
#include "ListOps.H" #include "ListOps.H"
#include "Time.H" #include "Time.H"
//#include "vtkSetWriter.H"
#include "DynamicField.H" #include "DynamicField.H"
//#include "OBJstream.H"
#include "PatchTools.H" #include "PatchTools.H"
#include "triSurfaceMesh.H" #include "triSurfaceMesh.H"
@ -405,9 +403,9 @@ void Foam::searchableSurfaces::findNearest
// Find nearest. Return -1 or nearest point // Find nearest. Return -1 or nearest point
void Foam::searchableSurfaces::findNearest void Foam::searchableSurfaces::findNearest
( (
const labelListList& regionIndices,
const pointField& samples, const pointField& samples,
const scalarField& nearestDistSqr, const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces, labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo List<pointIndexHit>& nearestInfo
) const ) const
@ -416,9 +414,11 @@ void Foam::searchableSurfaces::findNearest
( (
*this, *this,
allSurfaces_, allSurfaces_,
regionIndices,
samples, samples,
nearestDistSqr, nearestDistSqr,
regionIndices,
nearestSurfaces, nearestSurfaces,
nearestInfo nearestInfo
); );

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.
@ -200,9 +200,9 @@ public:
void findNearest void findNearest
( (
const labelListList& regionIndices,
const pointField& samples, const pointField& samples,
const scalarField& nearestDistSqr, const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces, labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo List<pointIndexHit>& nearestInfo
) const; ) 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) 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.
@ -672,9 +672,11 @@ void Foam::searchableSurfacesQueries::findNearest
( (
const PtrList<searchableSurface>& allSurfaces, const PtrList<searchableSurface>& allSurfaces,
const labelList& surfacesToTest, const labelList& surfacesToTest,
const labelListList& regionIndices,
const pointField& samples, const pointField& samples,
const scalarField& nearestDistSqr, const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces, labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo List<pointIndexHit>& nearestInfo
) )
@ -707,7 +709,7 @@ void Foam::searchableSurfacesQueries::findNearest
( (
samples, samples,
minDistSqr, minDistSqr,
regionIndices, regionIndices[testI],
hitInfo hitInfo
); );

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.
@ -183,14 +183,14 @@ public:
List<pointIndexHit>& List<pointIndexHit>&
); );
//- Find nearest points to a specific region of the surface //- Find nearest points to a specific regions of the surface
static void findNearest static void findNearest
( (
const PtrList<searchableSurface>& allSurfaces, const PtrList<searchableSurface>& allSurfaces,
const labelList& surfacesToTest, const labelList& surfacesToTest,
const labelListList& regionIndices,
const pointField& samples, const pointField& samples,
const scalarField& nearestDistSqr, const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces, labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo List<pointIndexHit>& nearestInfo
); );

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.
@ -39,6 +39,8 @@ namespace Foam
defineTypeNameAndDebug(triSurfaceMesh, 0); defineTypeNameAndDebug(triSurfaceMesh, 0);
addToRunTimeSelectionTable(searchableSurface, triSurfaceMesh, dict); addToRunTimeSelectionTable(searchableSurface, triSurfaceMesh, dict);
word triSurfaceMesh::meshSubDir = "triSurface";
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -231,7 +233,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
( (
io.name(), io.name(),
io.instance(), io.instance(),
io.local(), io.local(), //"triSurfaceFields",
io.db(), io.db(),
io.readOpt(), io.readOpt(),
io.writeOpt(), io.writeOpt(),
@ -239,9 +241,10 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
) )
), ),
triSurface(s), triSurface(s),
triSurfaceRegionSearch(s), triSurfaceRegionSearch(static_cast<const triSurface&>(*this)),
minQuality_(-1), minQuality_(-1),
surfaceClosed_(-1) surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{ {
const pointField& pts = triSurface::points(); const pointField& pts = triSurface::points();
@ -272,7 +275,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
( (
io.name(), io.name(),
static_cast<const searchableSurface&>(*this).instance(), static_cast<const searchableSurface&>(*this).instance(),
io.local(), io.local(), //"triSurfaceFields",
io.db(), io.db(),
io.readOpt(), io.readOpt(),
io.writeOpt(), io.writeOpt(),
@ -289,7 +292,8 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
), ),
triSurfaceRegionSearch(static_cast<const triSurface&>(*this)), triSurfaceRegionSearch(static_cast<const triSurface&>(*this)),
minQuality_(-1), minQuality_(-1),
surfaceClosed_(-1) surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{ {
const pointField& pts = triSurface::points(); const pointField& pts = triSurface::points();
@ -323,7 +327,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
( (
io.name(), io.name(),
static_cast<const searchableSurface&>(*this).instance(), static_cast<const searchableSurface&>(*this).instance(),
io.local(), io.local(), //"triSurfaceFields",
io.db(), io.db(),
io.readOpt(), io.readOpt(),
io.writeOpt(), io.writeOpt(),
@ -340,7 +344,8 @@ Foam::triSurfaceMesh::triSurfaceMesh
), ),
triSurfaceRegionSearch(static_cast<const triSurface&>(*this), dict), triSurfaceRegionSearch(static_cast<const triSurface&>(*this), dict),
minQuality_(-1), minQuality_(-1),
surfaceClosed_(-1) surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{ {
scalar scaleFactor = 0; scalar scaleFactor = 0;
@ -377,6 +382,7 @@ Foam::triSurfaceMesh::~triSurfaceMesh()
void Foam::triSurfaceMesh::clearOut() void Foam::triSurfaceMesh::clearOut()
{ {
outsideVolType_ = volumeType::UNKNOWN;
triSurfaceRegionSearch::clearOut(); triSurfaceRegionSearch::clearOut();
edgeTree_.clear(); edgeTree_.clear();
triSurface::clearOut(); triSurface::clearOut();
@ -447,9 +453,22 @@ bool Foam::triSurfaceMesh::overlaps(const boundBox& bb) const
void Foam::triSurfaceMesh::movePoints(const pointField& newPoints) void Foam::triSurfaceMesh::movePoints(const pointField& newPoints)
{ {
outsideVolType_ = volumeType::UNKNOWN;
// Update local information (instance, event number)
searchableSurface::instance() = objectRegistry::time().timeName();
objectRegistry::instance() = searchableSurface::instance();
label event = getEvent();
searchableSurface::eventNo() = event;
objectRegistry::eventNo() = searchableSurface::eventNo();
// Clear additional addressing
triSurfaceRegionSearch::clearOut(); triSurfaceRegionSearch::clearOut();
edgeTree_.clear(); edgeTree_.clear();
triSurface::movePoints(newPoints); triSurface::movePoints(newPoints);
bounds() = boundBox(triSurface::points());
} }
@ -713,6 +732,19 @@ void Foam::triSurfaceMesh::getNormal
void Foam::triSurfaceMesh::setField(const labelList& values) void Foam::triSurfaceMesh::setField(const labelList& values)
{
if (foundObject<triSurfaceLabelField>("values"))
{
triSurfaceLabelField& fld = const_cast<triSurfaceLabelField&>
(
lookupObject<triSurfaceLabelField>
(
"values"
)
);
fld.field() = values;
}
else
{ {
autoPtr<triSurfaceLabelField> fldPtr autoPtr<triSurfaceLabelField> fldPtr
( (
@ -722,7 +754,7 @@ void Foam::triSurfaceMesh::setField(const labelList& values)
( (
"values", "values",
objectRegistry::time().timeName(), // instance objectRegistry::time().timeName(), // instance
"triSurface", // local meshSubDir, // local
*this, *this,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::AUTO_WRITE IOobject::AUTO_WRITE
@ -736,6 +768,7 @@ void Foam::triSurfaceMesh::setField(const labelList& values)
// Store field on triMesh // Store field on triMesh
fldPtr.ptr()->store(); fldPtr.ptr()->store();
} }
}
void Foam::triSurfaceMesh::getField void Foam::triSurfaceMesh::getField
@ -780,18 +813,27 @@ void Foam::triSurfaceMesh::getVolumeType
const point& pt = points[pointI]; const point& pt = points[pointI];
if (!tree().bb().contains(pt)) if (!tree().bb().contains(pt))
{
if (hasVolumeType())
{
// Precalculate and cache value for this outside point
if (outsideVolType_ == volumeType::UNKNOWN)
{
outsideVolType_ = tree().shapes().getVolumeType(tree(), pt);
}
volType[pointI] = outsideVolType_;
}
else
{ {
// Have to calculate directly as outside the octree // Have to calculate directly as outside the octree
volType[pointI] = tree().shapes().getVolumeType(tree(), pt); volType[pointI] = tree().shapes().getVolumeType(tree(), pt);
} }
}
else else
{ {
// - use cached volume type per each tree node // - use cached volume type per each tree node
volType[pointI] = tree().getVolumeType(pt); volType[pointI] = tree().getVolumeType(pt);
} }
// Info<< "octree : " << pt << " = "
// << volumeType::names[volType[pointI]] << endl;
} }
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
@ -806,6 +848,24 @@ bool Foam::triSurfaceMesh::writeObject
IOstream::compressionType cmp IOstream::compressionType cmp
) const ) const
{ {
const Time& runTime = searchableSurface::time();
const fileName& instance = searchableSurface::instance();
if
(
instance != runTime.timeName()
&& instance != runTime.system()
&& instance != runTime.caseSystem()
&& instance != runTime.constant()
&& instance != runTime.caseConstant()
)
{
const_cast<triSurfaceMesh&>(*this).searchableSurface::instance() =
runTime.timeName();
const_cast<triSurfaceMesh&>(*this).objectRegistry::instance() =
runTime.timeName();
}
fileName fullPath(searchableSurface::objectPath()); fileName fullPath(searchableSurface::objectPath());
if (!mkDir(fullPath.path())) if (!mkDir(fullPath.path()))

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -85,6 +85,9 @@ private:
//- Is surface closed //- Is surface closed
mutable label surfaceClosed_; mutable label surfaceClosed_;
//- If surface is closed, what is type of outside points
mutable volumeType outsideVolType_;
// Private Member Functions // Private Member Functions
@ -137,6 +140,9 @@ public:
//- Runtime type information //- Runtime type information
TypeName("triSurfaceMesh"); TypeName("triSurfaceMesh");
//- Return the mesh sub-directory name (usually "triSurface")
static word meshSubDir;
// Constructors // Constructors

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -47,7 +47,7 @@ addToRunTimeSelectionTable(topoSetSource, regionToCell, istream);
Foam::topoSetSource::addToUsageTable Foam::regionToCell::usage_ Foam::topoSetSource::addToUsageTable Foam::regionToCell::usage_
( (
regionToCell::typeName, regionToCell::typeName,
"\n Usage: regionToCell subCellSet (pt0 .. ptn)\n\n" "\n Usage: regionToCell subCellSet (pt0 .. ptn) nErode\n\n"
" Select all cells in the connected region containing" " Select all cells in the connected region containing"
" points (pt0..ptn).\n" " points (pt0..ptn).\n"
); );
@ -433,7 +433,7 @@ Foam::regionToCell::regionToCell
topoSetSource(mesh), topoSetSource(mesh),
setName_(checkIs(is)), setName_(checkIs(is)),
insidePoints_(checkIs(is)), insidePoints_(checkIs(is)),
nErode_(0) nErode_(readLabel(checkIs(is)))
{} {}

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.
@ -65,16 +65,16 @@ class surfaceToPoint
static addToUsageTable usage_; static addToUsageTable usage_;
//- Name of surface file //- Name of surface file
fileName surfName_; const fileName surfName_;
//- If > 0 : include points with distance to surface less than nearDist. //- If > 0 : include points with distance to surface less than nearDist.
scalar nearDist_; const scalar nearDist_;
//- Include all points on opposite sign of normal on nearest surface. //- Include all points on opposite sign of normal on nearest surface.
bool includeInside_; const bool includeInside_;
//- Include all points on this sign of normal on nearest surface. //- Include all points on this sign of normal on nearest surface.
bool includeOutside_; const bool includeOutside_;
// Private Member Functions // Private Member Functions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,8 +36,24 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(booleanSurface, 0); defineTypeNameAndDebug(booleanSurface, 0);
template<>
const char* Foam::NamedEnum
<
Foam::booleanSurface::booleanOpType,
4
>::names[] =
{
"union",
"intersection",
"difference",
"all"
};
} }
const Foam::NamedEnum<Foam::booleanSurface::booleanOpType, 4>
Foam::booleanSurface::booleanOpTypeNames;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //

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.
@ -170,6 +170,11 @@ public:
// surface. (Produces multiply connected surface) // surface. (Produces multiply connected surface)
}; };
// Static data
static const NamedEnum<booleanOpType, 4> booleanOpTypeNames;
// Constructors // Constructors

View File

@ -2,8 +2,8 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-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.
@ -716,66 +716,35 @@ Foam::faceList Foam::intersectedSurface::resplitFace
edgeSurface& eSurf edgeSurface& eSurf
) )
{ {
{
// Dump face for debugging.
Pout<< "Writing face:" << faceI << " to face.obj" << endl;
OFstream str("face.obj");
writeOBJ(eSurf.points(), eSurf.edges(), eSurf.faceEdges()[faceI], str);
}
// Count the number of times point has been visited so we // Count the number of times point has been visited so we
// can compare number to facePointEdges. // can compare number to facePointEdges.
Map<label> pointVisited(2*facePointEdges.size()); Map<label> pointVisited(2*facePointEdges.size());
{
OFstream str0("visitedNone.obj");
OFstream str1("visitedOnce.obj");
OFstream str2("visitedTwice.obj");
forAll(eSurf.points(), pointI)
{
const point& pt = eSurf.points()[pointI];
str0 << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
str1 << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
str2 << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
}
forAllConstIter(Map<label>, visited, iter) forAllConstIter(Map<label>, visited, iter)
{ {
label edgeI = iter.key(); label edgeI = iter.key();
const edge& e = eSurf.edges()[edgeI]; const edge& e = eSurf.edges()[edgeI];
label stat = iter(); label stat = iter();
if (stat == STARTTOEND || stat == ENDTOSTART) if (stat == STARTTOEND || stat == ENDTOSTART)
{ {
incCount(pointVisited, e[0], 1); incCount(pointVisited, e[0], 1);
incCount(pointVisited, e[1], 1); incCount(pointVisited, e[1], 1);
str1 << "l " << e[0]+1 << ' ' << e[1]+1 << nl;
} }
else if (stat == BOTH) else if (stat == BOTH)
{ {
incCount(pointVisited, e[0], 2); incCount(pointVisited, e[0], 2);
incCount(pointVisited, e[1], 2); incCount(pointVisited, e[1], 2);
str2 << "l " << e[0]+1 << ' ' << e[1]+1 << nl;
} }
else if (stat == UNVISITED) else if (stat == UNVISITED)
{ {
incCount(pointVisited, e[0], 0); incCount(pointVisited, e[0], 0);
incCount(pointVisited, e[1], 0); incCount(pointVisited, e[1], 0);
str0 << "l " << e[0]+1 << ' ' << e[1]+1 << nl;
}
} }
} }
if (debug)
{ {
forAllConstIter(Map<label>, pointVisited, iter) forAllConstIter(Map<label>, pointVisited, iter)
{ {
@ -838,8 +807,6 @@ Foam::faceList Foam::intersectedSurface::resplitFace
// Find second intersection. // Find second intersection.
label visitedVert1 = -1;
label unvisitedVert1 = -1;
{ {
scalar minDist = GREAT; scalar minDist = GREAT;
@ -876,8 +843,6 @@ Foam::faceList Foam::intersectedSurface::resplitFace
if (nearDist < minDist) if (nearDist < minDist)
{ {
minDist = nearDist; minDist = nearDist;
visitedVert1 = nearVertI;
unvisitedVert1 = pointI;
} }
} }
} }
@ -885,23 +850,14 @@ Foam::faceList Foam::intersectedSurface::resplitFace
} }
Pout<< "resplitFace : adding intersection from " << visitedVert0
<< " to " << unvisitedVert0 << endl
<< " and from " << visitedVert1
<< " to " << unvisitedVert1 << endl;
// // Add the new intersection edges to the edgeSurface
// edgeList additionalEdges(2);
// additionalEdges[0] = edge(visitedVert0, unvisitedVert0);
// additionalEdges[1] = edge(visitedVert1, unvisitedVert1);
// Add the new intersection edges to the edgeSurface // Add the new intersection edges to the edgeSurface
edgeList additionalEdges(1); edgeList additionalEdges(1);
additionalEdges[0] = edge(visitedVert0, unvisitedVert0); additionalEdges[0] = edge(visitedVert0, unvisitedVert0);
eSurf.addIntersectionEdges(faceI, additionalEdges); eSurf.addIntersectionEdges(faceI, additionalEdges);
if (debug)
{
fileName newFName("face_" + Foam::name(faceI) + "_newEdges.obj"); fileName newFName("face_" + Foam::name(faceI) + "_newEdges.obj");
Pout<< "Dumping face:" << faceI << " to " << newFName << endl; Pout<< "Dumping face:" << faceI << " to " << newFName << endl;
writeLocalOBJ writeLocalOBJ
@ -911,6 +867,7 @@ Foam::faceList Foam::intersectedSurface::resplitFace
eSurf.faceEdges()[faceI], eSurf.faceEdges()[faceI],
newFName newFName
); );
}
// Retry splitFace. Use recursion since is rare situation. // Retry splitFace. Use recursion since is rare situation.
return splitFace(surf, faceI, eSurf); return splitFace(surf, faceI, eSurf);
@ -1085,20 +1042,6 @@ Foam::faceList Foam::intersectedSurface::splitFace
} }
else if (stat != BOTH) else if (stat != BOTH)
{ {
//{
// Pout<< "Dumping faces so far to faces.obj" << nl
// << faces << endl;
//
// OFstream str("faces.obj");
//
// forAll(faces, i)
// {
// writeOBJ(points, faces[i], str);
// }
//}
Pout<< "** Resplitting **" << endl;
// Redo face after introducing extra edge. Edge introduced // Redo face after introducing extra edge. Edge introduced
// should be one nearest to any fully visited edge. // should be one nearest to any fully visited edge.
return resplitFace return resplitFace
@ -1220,34 +1163,6 @@ Foam::intersectedSurface::intersectedSurface
forAll(newFaces, newFaceI) forAll(newFaces, newFaceI)
{ {
const face& newF = newFaces[newFaceI]; const face& newF = newFaces[newFaceI];
// {
// fileName fName
// (
// "face_"
// + Foam::name(faceI)
// + "_subFace_"
// + Foam::name(newFaceI)
// + ".obj"
// );
// Pout<< "Writing original face:" << faceI << " subFace:"
// << newFaceI << " to " << fName << endl;
//
// OFstream str(fName);
//
// forAll(newF, fp)
// {
// meshTools::writeOBJ(str, eSurf.points()[newF[fp]]);
// }
// str << 'l';
// forAll(newF, fp)
// {
// str << ' ' << fp+1;
// }
// str<< " 1" << nl;
// }
const vector& n = surf.faceNormals()[faceI]; const vector& n = surf.faceNormals()[faceI];
const label region = surf[faceI].region(); const label region = surf[faceI].region();

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.
@ -54,7 +54,6 @@ void Foam::edgeIntersections::checkEdges(const triSurface& surf)
{ {
const pointField& localPoints = surf.localPoints(); const pointField& localPoints = surf.localPoints();
const edgeList& edges = surf.edges(); const edgeList& edges = surf.edges();
const labelListList& edgeFaces = surf.edgeFaces();
treeBoundBox bb(localPoints); treeBoundBox bb(localPoints);
@ -78,19 +77,6 @@ void Foam::edgeIntersections::checkEdges(const triSurface& surf)
<< "This might lead to problems in intersection" << "This might lead to problems in intersection"
<< endl; << endl;
} }
if (edgeFaces[edgeI].size() == 1)
{
WarningIn
(
"Foam::edgeIntersections::checkEdges(const triSurface& surf)"
) << "Edge " << edgeI << " vertices " << e
<< " coords:" << localPoints[e[0]] << ' '
<< localPoints[e[1]] << " has only one face connected to it:"
<< edgeFaces[edgeI] << endl
<< "This might lead to problems in intersection"
<< endl;
}
} }
} }
@ -466,7 +452,6 @@ Foam::edgeIntersections::edgeIntersections()
{} {}
// Construct from surface and tolerance
Foam::edgeIntersections::edgeIntersections Foam::edgeIntersections::edgeIntersections
( (
const triSurface& surf1, const triSurface& surf1,
@ -478,16 +463,9 @@ Foam::edgeIntersections::edgeIntersections
classification_(surf1.nEdges()) classification_(surf1.nEdges())
{ {
checkEdges(surf1); checkEdges(surf1);
checkEdges(query2.surface());
// Current set of edges to test // Current set of edges to test
labelList edgesToTest(surf1.nEdges()); labelList edgesToTest(identity(surf1.nEdges()));
// Start off with all edges
forAll(edgesToTest, i)
{
edgesToTest[i] = i;
}
// Determine intersections for edgesToTest // Determine intersections for edgesToTest
intersectEdges intersectEdges

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.
@ -242,9 +242,9 @@ void Foam::surfaceIntersection::storeIntersection
WarningIn WarningIn
( (
"Foam::surfaceIntersection::storeIntersection" "Foam::surfaceIntersection::storeIntersection"
"(const bool isFirstSurf, const labelList& facesA," "(const bool, const labelList&,"
"const label faceB, DynamicList<edge>& allCutEdges," "const label, DynamicList<edge>&,"
"DynamicList<point>& allCutPoints)" "DynamicList<point>&)"
) << "Encountered degenerate edge between face " ) << "Encountered degenerate edge between face "
<< twoFaces[0] << " on first surface" << twoFaces[0] << " on first surface"
<< " and face " << twoFaces[1] << " on second surface" << " and face " << twoFaces[1] << " on second surface"
@ -815,7 +815,7 @@ Foam::surfaceIntersection::surfaceIntersection
} }
// Construct from full intersection Poutrmation // Construct from full intersection information
Foam::surfaceIntersection::surfaceIntersection Foam::surfaceIntersection::surfaceIntersection
( (
const triSurface& surf1, const triSurface& surf1,

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.
@ -163,7 +163,7 @@ Foam::triSurfaceRegionSearch::treeByRegion() const
( (
treeDataIndirectTriSurface treeDataIndirectTriSurface
( (
true, false, //true,
indirectRegionPatches_[regionI], indirectRegionPatches_[regionI],
tolerance() tolerance()
), ),
@ -211,6 +211,7 @@ void Foam::triSurfaceRegionSearch::findNearest
} }
const treeType& octree = octrees[treeI]; const treeType& octree = octrees[treeI];
const treeDataIndirectTriSurface::findNearestOp nearOp(octree);
forAll(samples, i) forAll(samples, i)
{ {
@ -223,7 +224,7 @@ void Foam::triSurfaceRegionSearch::findNearest
( (
samples[i], samples[i],
nearestDistSqr[i], nearestDistSqr[i],
treeDataIndirectTriSurface::findNearestOp(octree) nearOp
); );
if if

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.
@ -234,7 +234,7 @@ Foam::triSurfaceSearch::tree() const
( (
new indexedOctree<treeDataTriSurface> new indexedOctree<treeDataTriSurface>
( (
treeDataTriSurface(true, surface_, tolerance_), treeDataTriSurface(false, surface_, tolerance_),
bb, bb,
maxTreeDepth_, // maxLevel maxTreeDepth_, // maxLevel
10, // leafsize 10, // leafsize
@ -290,15 +290,17 @@ void Foam::triSurfaceSearch::findNearest
const indexedOctree<treeDataTriSurface>& octree = tree(); const indexedOctree<treeDataTriSurface>& octree = tree();
const treeDataTriSurface::findNearestOp fOp(octree);
info.setSize(samples.size()); info.setSize(samples.size());
forAll(samples, i) forAll(samples, i)
{ {
static_cast<pointIndexHit&>(info[i]) = octree.findNearest info[i] = octree.findNearest
( (
samples[i], samples[i],
nearestDistSqr[i], nearestDistSqr[i],
treeDataTriSurface::findNearestOp(octree) fOp
); );
} }
@ -335,11 +337,7 @@ void Foam::triSurfaceSearch::findLine
forAll(start, i) forAll(start, i)
{ {
static_cast<pointIndexHit&>(info[i]) = octree.findLine info[i] = octree.findLine(start[i], end[i]);
(
start[i],
end[i]
);
} }
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
@ -362,11 +360,7 @@ void Foam::triSurfaceSearch::findLineAny
forAll(start, i) forAll(start, i)
{ {
static_cast<pointIndexHit&>(info[i]) = octree.findLineAny info[i] = octree.findLineAny(start[i], end[i]);
(
start[i],
end[i]
);
} }
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;

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

View File

@ -0,0 +1,45 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [m s^-1];
internalField uniform (0 0 0);
boundaryField
{
//- Set patchGroups for constraint patches
#include "${WM_PROJECT_DIR}/etc/caseDicts/setConstraintTypes"
minX
{
type uniformFixedValue;
uniformValue (1 0 0);
}
maxX
{
type zeroGradient;
}
wall
{
type uniformFixedValue;
uniformValue (0 0 0);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [m^2/s^2];
internalField uniform 0;
boundaryField
{
//- Set patchGroups for constraint patches
#include "${WM_PROJECT_DIR}/etc/caseDicts/setConstraintTypes"
minX
{
type zeroGradient;
}
maxX
{
type fixedValue;
value $internalField;
}
wall
{
type zeroGradient;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,8 @@
#!/bin/sh
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
rm -f constant/polyMesh/boundary
cleanCase

Some files were not shown because too many files have changed in this diff Show More