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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -493,21 +493,30 @@ int main(int argc, char *argv[])
// new patchID to neighbour processor)
// - number of new patches (nPatches)
labelList sidePatchID;
labelList edgePatchID;
labelList edgeZoneID;
boolList edgeFlip;
labelList inflateFaceID;
label nPatches;
Map<label> nbrProcToPatch;
Map<label> patchToNbrProc;
addPatchCellLayer::calcSidePatch
addPatchCellLayer::calcExtrudeInfo
(
true, // for internal edges get zone info from any face
mesh,
globalFaces,
edgeGlobalFaces,
extrudePatch,
sidePatchID,
edgePatchID,
nPatches,
nbrProcToPatch,
patchToNbrProc
patchToNbrProc,
edgeZoneID,
edgeFlip,
inflateFaceID
);
@ -659,7 +668,12 @@ int main(int argc, char *argv[])
ratio, // expansion ratio
extrudePatch, // patch faces to extrude
sidePatchID, // if boundary edge: patch to use
edgePatchID, // if boundary edge: patch for extruded face
edgeZoneID, // optional zone for extruded face
edgeFlip,
inflateFaceID, // mesh face that zone/patch info is from
exposedPatchID, // if new mesh: patches for exposed faces
nFaceLayers,
nPointLayers,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -1121,6 +1121,38 @@ int main(int argc, char *argv[])
);
// Refinement parameters
const refinementParameters refineParams(refineDict);
// Snap parameters
const snapParameters snapParams(snapDict);
// Add all the cellZones and faceZones
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 1. cellZones relating to surface (faceZones added later)
const labelList namedSurfaces
(
surfaceZonesInfo::getNamedSurfaces(surfaces.surfZones())
);
labelList surfaceToCellZone = surfaceZonesInfo::addCellZonesToMesh
(
surfaces.surfZones(),
namedSurfaces,
mesh
);
// 2. cellZones relating to locations
refineParams.addCellZonesToMesh(mesh);
// Add all the surface regions as patches
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1128,6 +1160,8 @@ int main(int argc, char *argv[])
// (faceZone surfaces)
labelList globalToMasterPatch;
labelList globalToSlavePatch;
{
Info<< nl
<< "Adding patches for surface regions" << nl
@ -1148,6 +1182,7 @@ int main(int argc, char *argv[])
const labelList& surfaceGeometry = surfaces.surfaces();
const PtrList<dictionary>& surfacePatchInfo = surfaces.patchInfo();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(surfaceGeometry, surfI)
{
@ -1157,7 +1192,9 @@ int main(int argc, char *argv[])
Info<< surfaces.names()[surfI] << ':' << nl << nl;
if (surfaces.surfZones()[surfI].faceZoneName().empty())
const word& fzName = surfaces.surfZones()[surfI].faceZoneName();
if (fzName.empty())
{
// 'Normal' surface
forAll(regNames, i)
@ -1188,7 +1225,7 @@ int main(int argc, char *argv[])
Info<< setf(ios_base::left)
<< setw(6) << patchI
<< setw(20) << mesh.boundaryMesh()[patchI].type()
<< setw(20) << pbm[patchI].type()
<< setw(30) << regNames[i] << nl;
globalToMasterPatch[globalRegionI] = patchI;
@ -1228,7 +1265,7 @@ int main(int argc, char *argv[])
Info<< setf(ios_base::left)
<< setw(6) << patchI
<< setw(20) << mesh.boundaryMesh()[patchI].type()
<< setw(20) << pbm[patchI].type()
<< setw(30) << regNames[i] << nl;
globalToMasterPatch[globalRegionI] = patchI;
@ -1260,12 +1297,27 @@ int main(int argc, char *argv[])
Info<< setf(ios_base::left)
<< setw(6) << patchI
<< setw(20) << mesh.boundaryMesh()[patchI].type()
<< setw(20) << pbm[patchI].type()
<< setw(30) << slaveName << nl;
globalToSlavePatch[globalRegionI] = patchI;
}
}
// For now: have single faceZone per surface. Use first
// region in surface for patch for zoneing
if (regNames.size())
{
label globalRegionI = surfaces.globalRegion(surfI, 0);
meshRefiner.addFaceZone
(
fzName,
pbm[globalToMasterPatch[globalRegionI]].name(),
pbm[globalToSlavePatch[globalRegionI]].name(),
surfaces.surfZones()[surfI].faceType()
);
}
}
Info<< nl;
@ -1275,10 +1327,85 @@ int main(int argc, char *argv[])
}
// Add all information for all the remaining faceZones
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HashTable<Pair<word> > faceZoneToPatches;
forAll(mesh.faceZones(), zoneI)
{
const word& fzName = mesh.faceZones()[zoneI].name();
label mpI, spI;
surfaceZonesInfo::faceZoneType fzType;
bool hasInfo = meshRefiner.getFaceZoneInfo(fzName, mpI, spI, fzType);
if (!hasInfo)
{
// faceZone does not originate from a surface but presumably
// from a cellZone pair instead
string::size_type i = fzName.find("_to_");
if (i != string::npos)
{
word cz0 = fzName.substr(0, i);
word cz1 = fzName.substr(i+4, fzName.size()-i+4);
word slaveName(cz1 + "_to_" + cz0);
faceZoneToPatches.insert(fzName, Pair<word>(fzName, slaveName));
}
else
{
// Add as fzName + fzName_slave
const word slaveName = fzName + "_slave";
faceZoneToPatches.insert(fzName, Pair<word>(fzName, slaveName));
}
}
}
if (faceZoneToPatches.size())
{
autoRefineDriver::addFaceZones
(
meshRefiner,
refineParams,
faceZoneToPatches
);
}
// Re-do intersections on meshed boundaries since they use an extrapolated
// other side
{
const labelList adaptPatchIDs(meshRefiner.meshedPatches());
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
label nFaces = 0;
forAll(adaptPatchIDs, i)
{
nFaces += pbm[adaptPatchIDs[i]].size();
}
labelList faceLabels(nFaces);
nFaces = 0;
forAll(adaptPatchIDs, i)
{
const polyPatch& pp = pbm[adaptPatchIDs[i]];
forAll(pp, i)
{
faceLabels[nFaces++] = pp.start()+i;
}
}
meshRefiner.updateIntersections(faceLabels);
}
// Parallel
// ~~~~~~~~
// Decomposition
// Construct decomposition engine. Note: cannot use decompositionModel
// MeshObject since we're clearing out the mesh inside the mesh generation.
autoPtr<decompositionMethod> decomposerPtr
(
decompositionMethod::New
@ -1312,14 +1439,17 @@ int main(int argc, char *argv[])
const Switch wantSnap(meshDict.lookup("snap"));
const Switch wantLayers(meshDict.lookup("addLayers"));
// Refinement parameters
const refinementParameters refineParams(refineDict);
const Switch mergePatchFaces
(
meshDict.lookupOrDefault("mergePatchFaces", true)
);
// Snap parameters
const snapParameters snapParams(snapDict);
// Layer addition parameters
const layerParameters layerParams(layerDict, mesh.boundaryMesh());
if (!mergePatchFaces)
{
Info<< "Not merging patch-faces of cell to preserve"
<< " (split)hex cell shape."
<< nl << endl;
}
if (wantRefine)
@ -1348,6 +1478,7 @@ int main(int argc, char *argv[])
refineParams,
snapParams,
refineParams.handleSnapProblems(),
mergePatchFaces, // merge co-planar faces
motionDict
);
@ -1387,6 +1518,7 @@ int main(int argc, char *argv[])
(
snapDict,
motionDict,
mergePatchFaces,
curvature,
planarAngle,
snapParams
@ -1408,6 +1540,9 @@ int main(int argc, char *argv[])
{
cpuTime timer;
// Layer addition parameters
const layerParameters layerParams(layerDict, mesh.boundaryMesh());
autoLayerDriver layerDriver
(
meshRefiner,
@ -1433,6 +1568,7 @@ int main(int argc, char *argv[])
layerDict,
motionDict,
layerParams,
mergePatchFaces,
preBalance,
decomposer,
distributor

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.
castellatedMeshControls
{
@ -177,7 +182,7 @@ castellatedMeshControls
// how to select the cells that are in the cellZone
// (inside / outside / specified insidePoint)
// The orientation of the faceZone is
// - if on cellZone(s) : point out of (maximum) cellZone
// - if on cellZone(s) : point out of (minimum) cellZone
// - if freestanding : oriented according to surface
//faceZone sphere;
@ -249,9 +254,23 @@ castellatedMeshControls
// After refinement patches get added for all refinementSurfaces and
// all cells intersecting the surfaces get put into these patches. The
// section reachable from the locationInMesh is kept.
// section reachable from the location(s)InMesh is kept.
// NOTE: This point should never be on a face, always inside a cell, even
// after refinement.
//
// 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);
// Whether any faceZones (as specified in the refinementSurfaces)
@ -260,12 +279,56 @@ castellatedMeshControls
allowFreeStandingZoneFaces true;
// 2. Specify multiple locations with optional cellZones for the
// regions. faceZones are automatically constructed from the
// names of the cellZones: <cellZoneA> _to_ <cellZoneB>
// where the cellZoneA is the lowest numbered cellZone (non-cellZone
// cells are in a special region called "none" which is always
// last).
locationsInMesh
(
((-0.09 -0.039 -0.049) bottomAir) // cellZone 0
((-0.09 0.009 -0.049) topAir) // cellZone 1
((-0.09 0.001 -0.049) leftSolid) // cellZone 2
((0.02 0.001 -0.049) rightSolid) // cellZone 3
((-0.001 -0.039 0.0015) heater) // cellZone 4
);
// Per synthesised faceZone name the faceType and type of baffles to
// create
faceZoneControls
{
bottomAir_to_heater
{
// Optional specification of patch type (default is wall). No
// constraint types (cyclic, symmetry) etc. are allowed.
patchInfo
{
type patch;
inGroups (patchPatches);
}
faceType baffle;
}
}
// Optional locations that should not be reachable from
// location(s)InMesh
locationsOutsideMesh ((100 100 100));
// Optional: do not remove cells likely to give snapping problems
// handleSnapProblems false;
// Optional: switch off topological test for cells to-be-squashed
// and use geometric test instead
//useTopologicalSnapDetection false;
// Optional: do not refine surface cells with opposite faces of
// differing refinement levels
//interfaceRefine false;
}
// Settings for the snapping.
@ -275,6 +338,11 @@ snapControls
// to surface
nSmoothPatch 3;
// Optional: number of smoothing iterations for internal points on
// refinement interfaces. This will reduce non-orthogonality on
// refinement interfaces.
//nSmoothInternal $nSmoothPatch;
// Maximum relative distance for points to be attracted by surface.
// True distance is this factor times local maximum edge length.
// Note: changed(corrected) w.r.t 17x! (17x used 2* tolerance)
@ -287,6 +355,11 @@ snapControls
// before upon reaching a correct mesh.
nRelaxIter 5;
// (wip) disable snapping to opposite near surfaces (revert to 22x
// behaviour)
// detectNearSurfacesSnap false;
// Feature snapping
// Number of feature edge snapping iterations.
@ -305,8 +378,28 @@ snapControls
multiRegionFeatureSnap false;
// wip: disable snapping to opposite near surfaces (revert to 22x behaviour)
// detectNearSurfacesSnap false;
//- When to run face splitting (never at first iteration, always
// at last iteration). Is interval. Default -1 (disabled)
//nFaceSplitInterval 5;
// (wip) Optional for explicit feature snapping:
//- Detect baffle edges. Default is true.
//detectBaffles false;
//- Erase attraction close to feature point. Default is false.
//releasePoints true;
//- Walk along feature edges, adding missing ones. Default is true.
//stringFeatures false;
//- If diagonal attraction also attract other face points. Default is
// false
//avoidDiagonal true;
//- When splitting what concave faces to leave intact. Default is 45
// degrees.
//concaveAngle 30;
//- When splitting the minimum area ratio of faces. If face split
// causes ratio of area less than this do not split. Default is 0.3
//minAreaRatio 0.3;
}
// Settings for the layer addition.
@ -350,10 +443,10 @@ addLayersControls
// cannot be above minThickness do not add layer.
// If relativeSizes this is relative to undistorted size of cell
// outside layer..
minThickness 0.25;
minThickness 0.1;
// Per final patch (so not geometry!) the layer information
// Per final patch or faceZone (so not geometry!) the layer information
// Note: This behaviour changed after 21x. Any non-mentioned patches
// now slide unless:
// - nSurfaceLayers is explicitly mentioned to be 0.
@ -397,6 +490,10 @@ addLayersControls
// are perpendicular
featureAngle 130;
// When to merge patch faces. Default is featureAngle. Useful when
// featureAngle is large.
//mergePatchFacesAngle 45;
// Stop layer growth on highly warped cells
maxFaceThicknessRatio 0.5;
@ -433,8 +530,10 @@ addLayersControls
// default is 0.
//nSmoothDisplacement 90;
// (wip)Optional: do not extrude a point if none of the surrounding points is
// not extruded. Default is false.
// (wip)Optional: do not extrude any point where
// (false) : all surrounding faces are not fully extruded
// (true) : all surrounding points are not extruded
// Default is false.
//detectExtrusionIsland true;
@ -449,7 +548,8 @@ addLayersControls
// before upon reaching a correct mesh.
nRelaxIter 5;
// Create buffer region for new layer terminations
// Create buffer region for new layer terminations, i.e. gradually
// step down number of layers. Set to <0 to terminate layer in one go.
nBufferCellsNoExtrude 0;
// Overall max number of layer addition iterations. The mesher will

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -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 * * * * * * * * * * * * * * * * //
Foam::IOobject::~IOobject()

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -236,6 +236,13 @@ public:
bool registerObject=true
);
//- Construct as copy resetting name
IOobject
(
const IOobject& io,
const word& name
);
//- Clone
Foam::autoPtr<IOobject> clone() const
{

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -2748,7 +2748,13 @@ void Foam::globalMeshData::updateMesh()
// *** Temporary hack to avoid problems with overlapping communication
// *** 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.
nTotalFaces_ = returnReduce
@ -2785,6 +2791,8 @@ void Foam::globalMeshData::updateMesh()
comm
);
UPstream::freeCommunicator(comm);
if (debug)
{
Pout<< "globalMeshData : nTotalPoints_:" << nTotalPoints_ << endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -164,7 +164,8 @@ public:
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const TransformOp& top
const TransformOp& top,
const bool parRun = Pstream::parRun()
);
@ -556,7 +557,8 @@ public:
(
const polyMesh& mesh,
PackedList<nBits>& faceValues,
const CombineOp& cop
const CombineOp& cop,
const bool parRun = Pstream::parRun()
);
template<unsigned nBits>

View File

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

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,7 +26,7 @@ Class
Description
Adds two fvMeshes without using any polyMesh morphing.
Uses fvMeshAdder.
Uses polyMeshAdder.
SourceFiles
fvMeshAdder.C
@ -42,6 +42,7 @@ SourceFiles
#include "fvPatchFieldsFwd.H"
#include "fvsPatchFieldsFwd.H"
#include "fvPatchFieldMapper.H"
#include "DimensionedField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -101,8 +102,22 @@ private:
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:
// Declare name of the class and its debug switch
ClassName("fvMeshAdder");
// Member Functions
//- Inplace add mesh to fvMesh. Maps all stored fields. Returns map.
@ -131,6 +146,15 @@ public:
const fvMesh& mesh,
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -280,6 +280,12 @@ void Foam::fvMeshAdder::MapVolFields
++fieldIter
)
{
if (debug)
{
Pout<< "MapVolFields : Storing old time for " << fieldIter()->name()
<< endl;
}
const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
->storeOldTimes();
}
@ -304,6 +310,12 @@ void Foam::fvMeshAdder::MapVolFields
const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
*fieldsToAdd[fld.name()];
if (debug)
{
Pout<< "MapVolFields : mapping " << fld.name()
<< " and " << fldToAdd.name() << endl;
}
MapVolField<Type>(meshMap, fld, fldToAdd);
}
else
@ -585,8 +597,13 @@ void Foam::fvMeshAdder::MapSurfaceFields
++fieldIter
)
{
const_cast<fldType*>(fieldIter())
->storeOldTimes();
if (debug)
{
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()];
if (debug)
{
Pout<< "MapSurfaceFields : mapping " << fld.name()
<< " and " << fldToAdd.name() << endl;
}
MapSurfaceField<Type>(meshMap, fld, fldToAdd);
}
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -332,6 +332,17 @@ public:
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
@ -339,7 +350,6 @@ public:
//- Take over existing mesh position.
void correct();
//- Set patch fields on patchIDs to be consistent with
// all other boundary conditions
static void setDisplacementPatchFields
@ -471,6 +481,7 @@ public:
const bool report,
const dictionary& dict,
const polyMeshGeometry&,
const pointField&,
const labelList& checkFaces,
labelHashSet& wrongFaces
);
@ -483,6 +494,7 @@ public:
const bool report,
const dictionary& dict,
const polyMeshGeometry&,
const pointField&,
const labelList& checkFaces,
const List<labelPair>& baffles,
labelHashSet& wrongFaces

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -434,6 +434,7 @@ bool Foam::motionSmootherAlgo::checkMesh
const bool report,
const dictionary& dict,
const polyMeshGeometry& meshGeom,
const pointField& points,
const labelList& checkFaces,
labelHashSet& wrongFaces
)
@ -445,6 +446,7 @@ bool Foam::motionSmootherAlgo::checkMesh
report,
dict,
meshGeom,
points,
checkFaces,
emptyBaffles,
wrongFaces
@ -457,6 +459,7 @@ bool Foam::motionSmootherAlgo::checkMesh
const bool report,
const dictionary& dict,
const polyMeshGeometry& meshGeom,
const pointField& points,
const labelList& checkFaces,
const List<labelPair>& baffles,
labelHashSet& wrongFaces
@ -482,14 +485,14 @@ bool Foam::motionSmootherAlgo::checkMesh
(
readScalar(dict.lookup("minArea", true))
);
//const scalar maxIntSkew
//(
// readScalar(dict.lookup("maxInternalSkewness", true))
//);
//const scalar maxBounSkew
//(
// readScalar(dict.lookup("maxBoundarySkewness", true))
//);
const scalar maxIntSkew
(
readScalar(dict.lookup("maxInternalSkewness", true))
);
const scalar maxBounSkew
(
readScalar(dict.lookup("maxBoundarySkewness", true))
);
const scalar minWeight
(
readScalar(dict.lookup("minFaceWeight", true))
@ -512,7 +515,6 @@ bool Foam::motionSmootherAlgo::checkMesh
(
readScalar(dict.lookup("minDeterminant", true))
);
label nWrongFaces = 0;
Info<< "Checking faces in error :" << endl;
@ -544,8 +546,8 @@ bool Foam::motionSmootherAlgo::checkMesh
meshGeom.checkFacePyramids
(
report,
minVol,
meshGeom.mesh().points(),
minTetQuality,
points,
checkFaces,
baffles,
&wrongFaces
@ -566,7 +568,7 @@ bool Foam::motionSmootherAlgo::checkMesh
(
report,
minTetQuality,
meshGeom.mesh().points(),
points,
checkFaces,
baffles,
&wrongFaces
@ -587,7 +589,7 @@ bool Foam::motionSmootherAlgo::checkMesh
(
report,
maxConcave,
meshGeom.mesh().points(),
points,
checkFaces,
&wrongFaces
);
@ -604,7 +606,13 @@ bool Foam::motionSmootherAlgo::checkMesh
if (minArea > -SMALL)
{
meshGeom.checkFaceArea(report, minArea, checkFaces, &wrongFaces);
meshGeom.checkFaceArea
(
report,
minArea,
checkFaces,
&wrongFaces
);
label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>());
@ -616,30 +624,32 @@ bool Foam::motionSmootherAlgo::checkMesh
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
// to store them on polyMeshGeometry.
//if (maxIntSkew > 0 || maxBounSkew > 0)
//{
// meshGeom.checkFaceSkewness
// (
// report,
// maxIntSkew,
// 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;
//}
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)
{
@ -691,7 +701,7 @@ bool Foam::motionSmootherAlgo::checkMesh
(
report,
minTwist,
meshGeom.mesh().points(),
points,
checkFaces,
&wrongFaces
);
@ -714,7 +724,7 @@ bool Foam::motionSmootherAlgo::checkMesh
(
report,
minTriangleTwist,
meshGeom.mesh().points(),
points,
checkFaces,
&wrongFaces
);
@ -729,13 +739,13 @@ bool Foam::motionSmootherAlgo::checkMesh
nWrongFaces = nNewWrongFaces;
}
if (minFaceFlatness > -1)
if (minFaceFlatness > -SMALL)
{
meshGeom.checkFaceFlatness
(
report,
minFaceFlatness,
meshGeom.mesh().points(),
points,
checkFaces,
&wrongFaces
);
@ -757,7 +767,7 @@ bool Foam::motionSmootherAlgo::checkMesh
report,
minDet,
checkFaces,
meshGeom.affectedCells(meshGeom.mesh(), checkFaces),
polyMeshGeometry::affectedCells(meshGeom.mesh(), checkFaces),
&wrongFaces
);

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -105,86 +105,82 @@ void Foam::polyMeshGeometry::updateCellCentresAndVols
const labelList& changedFaces
)
{
const labelList& own = mesh().faceOwner();
const cellList& cells = mesh().cells();
// Clear the fields for accumulation
UIndirectList<vector>(cellCentres_, changedCells) = vector::zero;
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
vectorField cEst(mesh_.nCells());
UIndirectList<vector>(cEst, changedCells) = vector::zero;
scalarField nCellFaces(mesh_.nCells());
UIndirectList<scalar>(nCellFaces, changedCells) = 0.0;
forAll(changedFaces, i)
// Re-calculate the changed cell centres and volumes
forAll(changedCells, changedCellI)
{
label faceI = changedFaces[i];
cEst[own[faceI]] += faceCentres_[faceI];
nCellFaces[own[faceI]] += 1;
const label cellI(changedCells[changedCellI]);
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];
nCellFaces[nei[faceI]] += 1;
}
const point& fc = faceCentres_[cFaces[cFaceI]];
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];
cEst[cellI] /= nCellFaces[cellI];
}
const label faceI(cFaces[cFaceI]);
forAll(changedFaces, i)
// Calculate 3* the face-pyramid volume
scalar pyr3Vol = faceAreas_[faceI] & (faceCentres_[faceI] - cEst);
if (own[faceI] != cellI)
{
label faceI = changedFaces[i];
// 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;
pyr3Vol = -pyr3Vol;
}
// Accumulate face-pyramid volume
cellVolumes_[own[faceI]] += pyr3Vol;
cellVolumes_[cellI] += pyr3Vol;
if (mesh_.isInternalFace(faceI))
{
// 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]];
// Calculate the face-pyramid centre
const vector pCtr = (3.0/4.0)*faceCentres_[faceI] + (1.0/4.0)*cEst;
// Accumulate volume-weighted face-pyramid centre
cellCentres_[nei[faceI]] += pyr3Vol*pc;
// Accumulate face-pyramid volume
cellVolumes_[nei[faceI]] += pyr3Vol;
}
cellCentres_[cellI] += pyr3Vol*pCtr;
}
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);
}
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,25 +31,23 @@ License
namespace Foam
{
defineTypeNameAndDebug(displacementMotionSolver, 0);
defineRunTimeSelectionTable(displacementMotionSolver, displacement);
}
// * * * * * * * * * * * * * Protected Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::IOobject Foam::displacementMotionSolver::points0IO
(
const polyMesh& mesh
) const
Foam::IOobject Foam::displacementMotionSolver::points0IO(const polyMesh& mesh)
{
const word instance =
time().findInstance
mesh.time().findInstance
(
mesh.meshDir(),
"points0",
IOobject::READ_IF_PRESENT
);
if (instance != time().constant())
if (instance != mesh.time().constant())
{
// points0 written to a time folder
@ -58,7 +56,7 @@ Foam::IOobject Foam::displacementMotionSolver::points0IO
(
"points0",
instance,
polyMesh::meshSubDir,
mesh.meshDir(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
@ -73,7 +71,7 @@ Foam::IOobject Foam::displacementMotionSolver::points0IO
(
"points0",
instance,
polyMesh::meshSubDir,
mesh.meshDir(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
@ -93,7 +91,7 @@ Foam::IOobject Foam::displacementMotionSolver::points0IO
(
"points",
instance,
polyMesh::meshSubDir,
mesh.meshDir(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
@ -142,12 +140,11 @@ Foam::displacementMotionSolver::displacementMotionSolver
) << "Number of points in mesh " << mesh.nPoints()
<< " differs from number of points " << points0_.size()
<< " read from file "
<<
IOobject
<< IOobject
(
"points",
time().constant(),
polyMesh::meshSubDir,
mesh.meshDir(),
mesh,
IOobject::MUST_READ,
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 * * * * * * * * * * * * * * * //
Foam::displacementMotionSolver::~displacementMotionSolver()

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -68,14 +68,8 @@ protected:
pointIOField points0_;
// Protected Member Functions
//- Return IO object for points0
IOobject points0IO(const polyMesh& mesh) const;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
@ -84,12 +78,49 @@ private:
//- Disallow default bitwise assignment
void operator=(const displacementMotionSolver&);
public:
//- Runtime type information
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
//- Construct from mesh and dictionary
@ -100,6 +131,16 @@ public:
const word& type
);
//- Construct from mesh and dictionary
displacementMotionSolver
(
const polyMesh&,
const IOdictionary&,
const pointVectorField& pointDisplacement,
const pointIOField& points0,
const word& type
);
//- Destructor
virtual ~displacementMotionSolver();

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,7 +67,9 @@ private:
dictionary coeffDict_;
// Private Member Functions
protected:
// Protected Member Functions
//- De-register object if registered and assign to current
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,6 +34,8 @@ License
#include "polyModifyFace.H"
#include "polyAddCell.H"
#include "globalIndex.H"
#include "PatchTools.H"
#include "dummyTransform.H"
// * * * * * * * * * * * * * * 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
(
const indirectPrimitivePatch& pp,
const labelListList& addedCells, // per pp face the new extruded cell
const face& newFace,
const label newPatchID,
const label zoneI,
const bool edgeFlip,
const label inflateFaceI,
const label ownFaceI, // pp face that provides owner
const label nbrFaceI,
@ -238,68 +242,14 @@ Foam::label Foam::addPatchCellLayer::addSideFace
polyTopoChange& meshMod
) 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;
// Is patch edge external edge of indirectPrimitivePatch?
if (nbrFaceI == -1)
{
// 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
// (relevant only for coupled faces). See section for internal edge
// below.
@ -337,12 +287,12 @@ Foam::label Foam::addPatchCellLayer::addSideFace
addedCells[ownFaceI][layerOwn], // owner
-1, // neighbour
-1, // master point
inflateEdgeI, // master edge
-1, // master edge
inflateFaceI, // master face
false, // flux flip
newPatchID, // patch 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;
}
// 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
(
polyAddFace
@ -408,7 +375,7 @@ Foam::label Foam::addPatchCellLayer::addSideFace
false, // flux flip
-1, // patch 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 * * * * * * * * * * * * * * //
// 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 globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID,
labelList& edgePatchID,
label& nPatches,
Map<label>& nbrProcToPatch,
Map<label>& patchToNbrProc
Map<label>& patchToNbrProc,
labelList& edgeZoneID,
boolList& edgeFlip,
labelList& inflateFaceID
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
const globalMeshData& gd = mesh.globalData();
// Precalculate mesh edges for pp.edges.
const labelList meshEdges(pp.meshEdges(mesh.edges(), mesh.pointEdges()));
sidePatchID.setSize(pp.nEdges());
sidePatchID = -1;
edgePatchID.setSize(pp.nEdges());
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:
// - whether face is created from other face or edge
// - what zone&orientation face should have
labelList inflateEdgeI(pp.nEdges(), -1);
labelList inflateFaceI(pp.nEdges(), -1);
labelList sideZoneID(pp.nEdges(), -1);
boolList sideFlip(pp.nEdges(), false);
inflateFaceID.setSize(pp.nEdges(), -1);
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)
{
const labelList& eGlobalFaces = globalEdgeFaces[edgeI];
@ -606,8 +724,7 @@ void Foam::addPatchCellLayer::calcSidePatch
)
{
// Locally but not globally a boundary edge. Hence a coupled
// edge. Find the patch to use if on different
// processors.
// edge. Find the patch to use if on different processors.
label f0 = eGlobalFaces[0];
label f1 = eGlobalFaces[1];
@ -625,18 +742,25 @@ void Foam::addPatchCellLayer::calcSidePatch
if (otherProcI != -1)
{
sidePatchID[edgeI] = findProcPatch(mesh, otherProcI);
if (sidePatchID[edgeI] == -1)
if (findIndex(gd[Pstream::myProcNo()], otherProcI) != -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
// marked for addition
if (nbrProcToPatch.found(otherProcI))
{
sidePatchID[edgeI] = nbrProcToPatch[otherProcI];
edgePatchID[edgeI] = nbrProcToPatch[otherProcI];
}
else
{
sidePatchID[edgeI] = nPatches;
edgePatchID[edgeI] = nPatches;
nbrProcToPatch.insert(otherProcI, nPatches);
patchToNbrProc.insert(nPatches, otherProcI);
nPatches++;
@ -647,9 +771,8 @@ void Foam::addPatchCellLayer::calcSidePatch
}
// Determine face properties for all other boundary edges
// ------------------------------------------------------
// Pass2: determine face properties for all other edges
// ----------------------------------------------------
const labelListList& edgeFaces = pp.edgeFaces();
@ -657,13 +780,10 @@ void Foam::addPatchCellLayer::calcSidePatch
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];
const labelList& meshFaces = mesh.edgeFaces
(
@ -671,43 +791,71 @@ void Foam::addPatchCellLayer::calcSidePatch
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))
{
setFaceProps
label dummyPatchI = -1;
findZoneFace
(
true, // useInternalFaces,
zoneFromAnyFace, // useBoundaryFaces,
mesh,
faceI,
pp,
edgeI,
sidePatchID[edgeI],
sideZoneID[edgeI],
sideFlip[edgeI]
ppFaces, // excludeFaces,
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)
{
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];
//FatalErrorIn("addPatchCellLayer::calcSidePatch(..)")
WarningIn("addPatchCellLayer::calcSidePatch(..)")
<< "Have no sidePatchID for edge " << edgeI << " points "
//FatalErrorIn("addPatchCellLayer::calcExtrudeInfo(..)")
WarningIn("addPatchCellLayer::calcExtrudeInfo(..)")
<< "Have no edgePatchID for edge " << edgeI << " points "
<< pp.points()[pp.meshPoints()[e[0]]]
<< pp.points()[pp.meshPoints()[e[1]]]
//<< abort(FatalError);
@ -718,15 +866,15 @@ void Foam::addPatchCellLayer::calcSidePatch
// Now we have sidepatch see if we have patchface or edge to inflate
// from.
// Pass3: for any faces set in pass1 see if we can find a processor face
// to inherit from (we only have a patch, not a patch face)
forAll(edgeFaces, edgeI)
{
if
(
edgeFaces[edgeI].size() == 1
&& sidePatchID[edgeI] != -1
&& inflateFaceI[edgeI] == -1
&& edgePatchID[edgeI] != -1
&& inflateFaceID[edgeI] == -1
)
{
// 1. Do we have a boundary face to inflate from
@ -745,34 +893,115 @@ void Foam::addPatchCellLayer::calcSidePatch
{
label faceI = meshFaces[k];
if (faceI != myFaceI)
if (faceI != myFaceI && !mesh.isInternalFace(faceI))
{
if (mesh.isInternalFace(faceI))
{
inflateEdgeI[edgeI] = meshEdgeI;
}
else
{
if (patches.whichPatch(faceI) == sidePatchID[edgeI])
if (patches.whichPatch(faceI) == edgePatchID[edgeI])
{
setFaceProps
(
mesh,
pp,
edgeI,
faceI,
sidePatchID[edgeI],
sideZoneID[edgeI],
sideFlip[edgeI]
edgePatchID[edgeI],
edgeZoneID[edgeI],
edgeFlip[edgeI],
inflateFaceID[edgeI]
);
inflateFaceI[edgeI] = faceI;
inflateEdgeI[edgeI] = -1;
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 scalarField& expansionRatio,
const indirectPrimitivePatch& pp,
const labelList& sidePatchID,
const labelList& edgePatchID,
const labelList& edgeZoneID,
const boolList& edgeFlip,
const labelList& inflateFaceID,
const labelList& exposedPatchID,
const labelList& nFaceLayers,
const labelList& nPointLayers,
@ -865,7 +1099,10 @@ void Foam::addPatchCellLayer::setRefinement
<< e.line(pp.localPoints())
<< " which is non-manifold (has "
<< globalEdgeFaces[edgeI].size()
<< " faces using it)"
<< " local or coupled faces using it)"
<< " of which "
<< pp.edgeFaces()[edgeI].size()
<< " local"
<< abort(FatalError);
}
}
@ -1741,13 +1978,25 @@ void Foam::addPatchCellLayer::setRefinement
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
(
pp,
addedCells,
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,
nbrFaceI,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -220,6 +220,9 @@ class addPatchCellLayer
const face& newFace,
const label newPatchID,
const label newZoneI,
const bool newFlip,
const label inflateFaceI,
const label ownFaceI,
const label nbrFaceI,
@ -243,6 +246,39 @@ class addPatchCellLayer
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
addPatchCellLayer(const addPatchCellLayer&);
@ -303,22 +339,37 @@ public:
const indirectPrimitivePatch& pp
);
//- Boundary edges get extruded into boundary faces. Determine patch
// for these faces. This might be a to-be-created processor patch
//- Determine extrude information per patch edge:
// - 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
// nbrProcToPatch, patchToNbrProc give the correspondence. nPatches
// is the new number of patches.
static void calcSidePatch
// nbrProcToPatch, patchToNbrProc give the correspondence.
// nPatches is the new number of patches.
static void calcExtrudeInfo
(
const bool zoneFromAnyFace,
const polyMesh&,
const globalIndex& globalFaces,
const labelListList& globalEdgeFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID,
labelList& edgePatchID, // if extruding a patch edge
label& nPatches,
Map<label>& nbrProcToPatch,
Map<label>& patchToNbrProc
Map<label>& patchToNbrProc,
labelList& edgeZoneID,
boolList& edgeFlip,
labelList& inflateFaceID
);
//- Play commands into polyTopoChange to create layers on top
@ -347,7 +398,12 @@ public:
const labelListList& globalEdgeFaces,
const scalarField& expansionRatio,
const indirectPrimitivePatch& pp,
const labelList& sidePatchID,
const labelList& sideZoneID,
const boolList& sideFlip,
const labelList& inflateFaceID,
const labelList& exposedPatchID,
const labelList& nFaceLayers,
const labelList& nPointLayers,
@ -374,7 +430,12 @@ public:
globalEdgeFaces,
scalarField(pp.nPoints(), 1.0), // expansion ration
pp,
sidePatchID,
labelList(pp.nEdges(), -1), // zoneID
boolList(pp.nEdges(), false), // zoneFlip
labelList(pp.nEdges(), -1), // inflateFaceID
labelList(0),
labelList(pp.size(), nLayers), // nFaceLayers
labelList(pp.nPoints(), nLayers), // nPointLayers

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -795,7 +795,7 @@ Foam::label Foam::hexRef8::findLevel
// 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];
@ -3519,7 +3519,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
for (label faceI = 0; faceI < mesh_.nFaces(); faceI++)
{
faceAnchorLevel[faceI] = getAnchorLevel(faceI);
faceAnchorLevel[faceI] = faceLevel(faceI);
}
// -1 : no need to split face

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -411,7 +411,7 @@ public:
// Refinement
//- 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
// 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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -498,6 +498,21 @@ void Foam::polyTopoChange::makeCells
{
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
(
"polyTopoChange::makeCells\n"
@ -506,7 +521,9 @@ void Foam::polyTopoChange::makeCells
" labelList&,\n"
" labelList&\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"
<< " without modifying exposed faces to be boundary faces."
<< exit(FatalError);

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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.
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_,
nCellsUsingFace,
plusEqOp<label>()
bndValues,
plusEqOp<label>(),
mapDistribute::transform(),
syncPar_
);
}

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -149,7 +149,7 @@ Foam::label Foam::tetDecomposer::triIndex(const label faceI, const label fp)
const
{
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
label thisTriI;
@ -436,7 +436,7 @@ void Foam::tetDecomposer::setRefinement
}
else
{
label fp0 = mesh_.tetBasePtIs()[faceI];
label fp0 = max(mesh_.tetBasePtIs()[faceI], 0);
label fp = f.fcIndex(fp0);
for (label triI = 0; triI < f.size()-2; triI++)

View File

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

View File

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

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,7 +47,6 @@ class removePoints;
class pointSet;
class motionSmoother;
class addPatchCellLayer;
class pointData;
class faceSet;
class layerParameters;
@ -108,7 +107,6 @@ private:
const labelList globalToSlavePatch_;
// Private Member Functions
// Layers
@ -231,14 +229,17 @@ private:
List<extrudeMode>& extrudeStatus
) const;
//- See what patches boundaryedges should be extruded into
//- See what zones and patches edges should be extruded into
void determineSidePatches
(
const globalIndex& globalFaces,
const labelListList& edgeGlobalFaces,
const indirectPrimitivePatch& pp,
labelList& sidePatchID
labelList& edgePatchID,
labelList& edgeZoneID,
boolList& edgeFlip,
labelList& inflateFaceID
);
//- Calculate pointwise wanted and minimum thickness.
@ -370,6 +371,14 @@ private:
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
// for ease of handling
static void getLayerCellsFaces
@ -393,6 +402,15 @@ private:
) const;
//- 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
(
const fvMesh& mesh,
@ -464,13 +482,6 @@ private:
pointVectorField& normals
) const;
bool isMaxEdge
(
const List<pointData>&,
const label edgeI,
const scalar minCos
) const;
//- Stop layer growth where mesh wraps around edge with a
// large feature angle
void handleFeatureAngleLayerTerminations
@ -595,6 +606,7 @@ public:
const dictionary& shrinkDict,
const dictionary& motionDict,
const layerParameters& layerParams,
const bool mergePatchFaces, // merging patch faces
const bool preBalance, // balance before adding?
decompositionMethod& decomposer,
fvMeshDistribute& distributor

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,6 +37,8 @@ License
#include "unitConversion.H"
#include "snapParameters.H"
#include "localPointRegion.H"
#include "IOmanip.H"
#include "labelVector.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -94,7 +96,7 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints(),
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
@ -207,7 +209,7 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints(),
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
@ -341,7 +343,7 @@ Foam::label Foam::autoRefineDriver::gapOnlyRefine
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints(),
refineParams.locationsInMesh(),
refineParams.curvature(),
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
(
const refinementParameters& refineParams,
@ -692,13 +1036,15 @@ void Foam::autoRefineDriver::removeInsideCells
nBufferLayers, // nBufferLayers
globalToMasterPatch_,
globalToSlavePatch_,
refineParams.keepPoints()[0]
refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh()
);
if (debug&meshRefinement::MESH)
{
Pout<< "Writing subsetted mesh to time "
<< meshRefiner_.timeName() << '.' << endl;
<< meshRefiner_.timeName() << endl;
meshRefiner_.write
(
meshRefinement::debugType(debug),
@ -753,7 +1099,7 @@ Foam::label Foam::autoRefineDriver::shellRefine
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints(),
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
@ -913,22 +1259,40 @@ void Foam::autoRefineDriver::baffleAndSplitMesh
false, // perpendicular edge connected cells
scalarField(0), // per region perpendicular angle
// Free standing baffles
!handleSnapProblems, // merge free standing baffles?
refineParams.planarAngle(),
motionDict,
const_cast<Time&>(mesh.time()),
globalToMasterPatch_,
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
(
const refinementParameters& refineParams
const refinementParameters& refineParams,
wordPairHashTable& zonesToFaceZone
)
{
// Mesh is at its finest. Do zoning
@ -940,7 +1304,11 @@ void Foam::autoRefineDriver::zonify
const labelList namedSurfaces =
surfaceZonesInfo::getNamedSurfaces(meshRefiner_.surfaces().surfZones());
if (namedSurfaces.size())
if
(
namedSurfaces.size()
|| refineParams.zonesInMesh().size()
)
{
Info<< nl
<< "Introducing zones for interfaces" << nl
@ -956,14 +1324,16 @@ void Foam::autoRefineDriver::zonify
meshRefiner_.zonify
(
refineParams.keepPoints()[0],
refineParams.allowFreeStandingZoneFaces()
refineParams.allowFreeStandingZoneFaces(),
refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
zonesToFaceZone
);
if (debug&meshRefinement::MESH)
{
Pout<< "Writing zoned mesh to time "
<< meshRefiner_.timeName() << '.' << endl;
<< meshRefiner_.timeName() << endl;
meshRefiner_.write
(
meshRefinement::debugType(debug),
@ -1015,15 +1385,29 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
handleSnapProblems, // remove perp edge connected cells
perpAngle, // perp angle
// Free standing baffles
true, // merge free standing baffles?
refineParams.planarAngle(), // planar angle
motionDict,
const_cast<Time&>(mesh.time()),
globalToMasterPatch_,
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)
@ -1048,7 +1432,7 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
// Actually merge baffles. Note: not exactly parallellized. Should
// convert baffle faces into processor faces if they resulted
// from them.
meshRefiner_.mergeBaffles(couples);
meshRefiner_.mergeBaffles(couples, Map<label>(0));
if (debug)
{
@ -1061,7 +1445,8 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
(
globalToMasterPatch_,
globalToSlavePatch_,
refineParams.keepPoints()[0]
refineParams.locationsInMesh(),
refineParams.locationsOutsideMesh()
);
if (debug)
@ -1077,7 +1462,7 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
if (debug&meshRefinement::MESH)
{
Pout<< "Writing handleProblemCells mesh to time "
<< meshRefiner_.timeName() << '.' << endl;
<< meshRefiner_.timeName() << endl;
meshRefiner_.write
(
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
(
const bool geometricMerge,
const refinementParameters& refineParams,
const dictionary& motionDict
)
@ -1105,6 +1565,8 @@ void Foam::autoRefineDriver::mergePatchFaces
const fvMesh& mesh = meshRefiner_.mesh();
if (geometricMerge)
{
meshRefiner_.mergePatchFacesUndo
(
Foam::cos(degToRad(45.0)),
@ -1113,6 +1575,18 @@ void Foam::autoRefineDriver::mergePatchFaces
motionDict,
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)
{
@ -1134,6 +1608,7 @@ void Foam::autoRefineDriver::doRefine
const refinementParameters& refineParams,
const snapParameters& snapParams,
const bool prepareForSnapping,
const bool doMergePatchFaces,
const dictionary& motionDict
)
{
@ -1145,7 +1620,7 @@ void Foam::autoRefineDriver::doRefine
const fvMesh& mesh = meshRefiner_.mesh();
// Check that all the keep points are inside the mesh.
refineParams.findCells(mesh);
refineParams.findCells(true, mesh, refineParams.locationsInMesh());
// Refine around feature edges
featureEdgeRefine
@ -1196,6 +1671,13 @@ void Foam::autoRefineDriver::doRefine
100 // maxIter
);
// Refine any cells with differing refinement level on either side
refinementInterfaceRefine
(
refineParams,
10 // maxIter
);
// Introduce baffles at surface intersections. Remove sections unreachable
// from keepPoint.
baffleAndSplitMesh
@ -1206,8 +1688,31 @@ void Foam::autoRefineDriver::doRefine
motionDict
);
// Mesh is at its finest. Do optional zoning.
zonify(refineParams);
// Mesh is at its finest. Do optional zoning (cellZones and faceZones)
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
splitAndMergeBaffles
@ -1221,7 +1726,7 @@ void Foam::autoRefineDriver::doRefine
// Do something about cells with refined faces on the boundary
if (prepareForSnapping)
{
mergePatchFaces(refineParams, motionDict);
mergePatchFaces(doMergePatchFaces, refineParams, motionDict);
}
@ -1232,28 +1737,17 @@ void Foam::autoRefineDriver::doRefine
<< "---------------------" << nl
<< endl;
//if (debug)
//{
// const_cast<Time&>(mesh.time())++;
//}
// Do final balancing. Keep zoned faces on one processor since the
// snap phase will convert them to baffles and this only works for
// internal faces.
meshRefiner_.balance
(
true,
false,
scalarField(mesh.nCells(), 1), // dummy weights
true, // keepZoneFaces
false, // keepBaffles
scalarField(mesh.nCells(), 1), // cellWeights
decomposer_,
distributor_
);
if (debug)
{
meshRefiner_.checkZoneFaces();
}
}
}

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,7 +34,8 @@ SourceFiles
#ifndef autoRefineDriver_H
#define autoRefineDriver_H
#include "treeBoundBox.H"
#include "wordPairHashTable.H"
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -105,6 +106,13 @@ class autoRefineDriver
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
void removeInsideCells
(
@ -129,7 +137,11 @@ class autoRefineDriver
);
//- Add zones
void zonify(const refinementParameters& refineParams);
void zonify
(
const refinementParameters& refineParams,
wordPairHashTable& zonesToFaceZone
);
void splitAndMergeBaffles
(
@ -142,11 +154,11 @@ class autoRefineDriver
//- Merge refined boundary faces (from exposing coarser cell)
void mergePatchFaces
(
const bool geometricMerge,
const refinementParameters& refineParams,
const dictionary& motionDict
);
//- Disallow default bitwise copy construct
autoRefineDriver(const autoRefineDriver&);
@ -182,8 +194,18 @@ public:
const refinementParameters& refineParams,
const snapParameters& snapParams,
const bool prepareForSnapping,
const bool mergePatchFaces,
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,6 +37,7 @@ SourceFiles
#define autoSnapDriver_H
#include "meshRefinement.H"
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -45,6 +46,7 @@ namespace Foam
// Forward declaration of classes
class motionSmoother;
class refinementParameters;
class snapParameters;
class pointConstraint;
@ -79,26 +81,34 @@ class autoSnapDriver
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.
// Quite complicated in determining which points to move where.
static pointField smoothPatchDisplacement
static tmp<pointField> smoothPatchDisplacement
(
const motionSmoother&,
const List<labelPair>&
);
//static tmp<pointField> avg
//(
// const indirectPrimitivePatch&,
// const pointField&
//);
static tmp<pointField> avg
(
const indirectPrimitivePatch&,
const pointField&
);
//- Calculate displacement per patch point. Wip.
//static tmp<pointField> smoothLambdaMuPatchDisplacement
//(
// const motionSmoother& meshMover,
// const List<labelPair>& baffles
//);
static pointField smoothLambdaMuPatchDisplacement
(
const motionSmoother& meshMover,
const List<labelPair>& baffles
);
//- Check that face zones are synced
@ -136,6 +146,48 @@ class autoSnapDriver
DynamicList<labelPair>& splits
) 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
//- Is point on two feature edges that make a largish angle?
@ -177,8 +229,8 @@ class autoSnapDriver
const scalarField& faceSnapDist,
vectorField& faceDisp,
vectorField& faceSurfaceNormal,
labelList& faceSurfaceRegion,
vectorField& faceRotation
labelList& faceSurfaceRegion
//vectorField& faceRotation
) const;
void calcNearestFacePointProperties
(
@ -253,6 +305,86 @@ class autoSnapDriver
const label faceI
) 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
// cause face squeeze
void avoidDiagonalAttraction
@ -264,6 +396,14 @@ class autoSnapDriver
List<pointConstraint>& patchConstraints
) 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
pointIndexHit findMultiPatchPoint
(
@ -320,7 +460,6 @@ class autoSnapDriver
void featureAttractionUsingReconstruction
(
const label iter,
const bool avoidSnapProblems,
const scalar featureCos,
const indirectPrimitivePatch& pp,
const scalarField& snapDist,
@ -366,6 +505,7 @@ class autoSnapDriver
void determineBaffleFeatures
(
const label iter,
const bool baffleFeaturePoints,
const scalar featureCos,
const indirectPrimitivePatch& pp,
@ -450,12 +590,20 @@ class autoSnapDriver
void featureAttractionUsingFeatureEdges
(
const label iter,
const bool avoidSnapProblems,
const scalar featureCos,
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 scalarField& snapDist,
const vectorField& nearestDisp,
const vectorField& nearestNormal,
const List<List<point> >& pointFaceSurfNormals,
const List<List<point> >& pointFaceDisp,
@ -465,12 +613,14 @@ class autoSnapDriver
vectorField& patchAttraction,
List<pointConstraint>& patchConstraints
) const;
void preventFaceSqueeze
(
const label iter,
const scalar featureCos,
const indirectPrimitivePatch& pp,
const scalarField& snapDist,
const vectorField& nearestAttraction,
vectorField& patchAttraction,
List<pointConstraint>& patchConstraints
@ -483,15 +633,19 @@ class autoSnapDriver
vectorField calcNearestSurfaceFeature
(
const snapParameters& snapParams,
const bool avoidSnapProblems,
const bool alignMeshEdges,
const label iter,
const scalar featureCos,
const scalar featureAttract,
const scalarField& snapDist,
const vectorField& nearestDisp,
const vectorField& nearestNormal,
motionSmoother& meshMover,
vectorField& patchAttraction,
List<pointConstraint>& patchConstraints
List<pointConstraint>& patchConstraints,
DynamicList<label>& splitFaces,
DynamicList<labelPair>& splits
) const;
@ -545,14 +699,6 @@ public:
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
static tmp<pointField> avgCellCentres
(
@ -575,7 +721,10 @@ public:
// displacement of patch points.
static vectorField calcNearestSurface
(
const bool strictRegionSnap,
const meshRefinement& meshRefiner,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch,
const scalarField& snapDist,
const indirectPrimitivePatch&,
pointField& nearestPoint,
@ -622,6 +771,7 @@ public:
(
const dictionary& snapDict,
const dictionary& motionDict,
const bool mergePatchFaces,
const scalar featureCos,
const scalar planarAngle,
const snapParameters& snapParams
@ -636,6 +786,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "autoSnapDriverTemplates.C"
#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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -124,6 +124,14 @@ Foam::layerParameters::layerParameters
readScalar(dict.lookup("minThickness"))
),
featureAngle_(readScalar(dict.lookup("featureAngle"))),
mergePatchFacesAngle_
(
dict.lookupOrDefault<scalar>
(
"mergePatchFacesAngle",
featureAngle_
)
),
concaveAngle_
(
dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -114,6 +114,8 @@ private:
scalar featureAngle_;
scalar mergePatchFacesAngle_;
scalar concaveAngle_;
label nGrow_;
@ -247,6 +249,11 @@ public:
return featureAngle_;
}
scalar mergePatchFacesAngle() const
{
return mergePatchFacesAngle_;
}
scalar concaveAngle() const
{
return concaveAngle_;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,6 +27,8 @@ License
#include "unitConversion.H"
#include "polyMesh.H"
#include "globalIndex.H"
#include "Tuple2.H"
#include "wallPolyPatch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -44,7 +46,15 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
)
),
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")),
useTopologicalSnapDetection_
(
@ -54,8 +64,35 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
handleSnapProblems_
(
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")));
if (featAngle < 0 || featAngle > 180)
@ -71,8 +108,68 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::refinementParameters::findCells(const polyMesh& mesh)
const
Foam::dictionary Foam::refinementParameters::getZoneInfo
(
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)
(void)mesh.tetBasePtIs();
@ -81,13 +178,13 @@ const
globalIndex globalCells(mesh.nCells());
// 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;
@ -98,12 +195,13 @@ const
reduce(globalCellI, maxOp<label>());
if (globalCellI == -1)
if (checkInsideMesh && globalCellI == -1)
{
FatalErrorIn
(
"refinementParameters::findCells(const polyMesh&) const"
) << "Point " << keepPoint
"refinementParameters::findCells"
"(const polyMesh&, const pointField&) const"
) << "Point " << location
<< " is not inside the mesh or on a face or edge." << nl
<< "Bounding box of the mesh:" << mesh.bounds()
<< exit(FatalError);
@ -113,10 +211,9 @@ const
label procI = globalCells.whichProcID(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;
if (globalCells.isLocal(globalCellI))
{
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,6 +38,8 @@ SourceFiles
#include "dictionary.H"
#include "pointField.H"
#include "Switch.H"
#include "wordPairHashTable.H"
#include "surfaceZonesInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,8 +75,21 @@ class refinementParameters
//- Number of layers between different refinement levels
const label nBufferLayers_;
// Selection of areas
//- Areas not to keep
const pointField locationsOutsideMesh_;
//- 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
// cellZone?
@ -89,6 +104,8 @@ class refinementParameters
Switch handleSnapProblems_;
Switch interfaceRefine_;
// Private Member Functions
//- Disallow default bitwise copy construct
@ -147,9 +164,21 @@ public:
}
//- 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
@ -177,11 +206,39 @@ public:
return handleSnapProblems_;
}
//- Refine cell with opposite faces with different refinement level
bool interfaceRefine() const
{
return interfaceRefine_;
}
// Other
//- Checks that cells are in mesh. Returns cells they are in.
labelList findCells(const polyMesh&) const;
//- Get patchInfo and faceType for faceZone
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,6 +31,7 @@ License
Foam::snapParameters::snapParameters(const dictionary& dict)
:
nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))),
nSmoothInternal_(dict.lookupOrDefault("nSmoothInternal", 0)),
snapTol_(readScalar(dict.lookup("tolerance"))),
nSmoothDispl_(readLabel(dict.lookup("nSolveIter"))),
nSnap_(readLabel(dict.lookup("nRelaxIter"))),
@ -44,7 +45,22 @@ Foam::snapParameters::snapParameters(const dictionary& dict)
detectNearSurfacesSnap_
(
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,8 +44,6 @@ SourceFiles
namespace Foam
{
// Class forward declarations
/*---------------------------------------------------------------------------*\
Class snapParameters Declaration
\*---------------------------------------------------------------------------*/
@ -56,6 +54,8 @@ class snapParameters
const label nSmoothPatch_;
const label nSmoothInternal_;
const scalar snapTol_;
const label nSmoothDispl_;
@ -72,6 +72,28 @@ class snapParameters
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
@ -101,6 +123,13 @@ public:
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
// feature point
// or edge. True distance is this factor times local
@ -123,6 +152,25 @@ public:
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
{
return nFeatureSnap_;
@ -143,11 +191,52 @@ public:
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
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,9 +42,6 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::displacementMeshMoverMotionSolver::displacementMeshMoverMotionSolver

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,8 +25,8 @@ Class
Foam::displacementMeshMoverMotionSolver
Description
Mesh motion solver for an fvMesh. Based on solving the cell-centre
Laplacian for the motion displacement.
Mesh motion solver for an fvMesh. Uses externalDisplacementMeshMover
to do the mesh motion.
SourceFiles
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
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,6 +25,7 @@ License
#include "externalDisplacementMeshMover.H"
#include "mapPolyMesh.H"
#include "zeroFixedValuePointPatchFields.H"
// * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * //
Foam::externalDisplacementMeshMover::externalDisplacementMeshMover

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,6 +67,19 @@ protected:
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 Member Functions
@ -80,6 +93,7 @@ private:
//- Disallow default bitwise assignment
void operator=(const externalDisplacementMeshMover&);
public:
//- 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
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,7 +32,7 @@ License
#include "unitConversion.H"
#include "PatchTools.H"
#include "OBJstream.H"
#include "pointData.H"
#include "PointData.H"
#include "zeroFixedValuePointPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -52,241 +52,11 @@ namespace Foam
// * * * * * * * * * * * * * 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
// wall point for both vertices of edge.
bool Foam::medialAxisMeshMover::isMaxEdge
(
const List<pointData>& pointWallDist,
const List<PointData<vector> >& pointWallDist,
const label edgeI,
const scalar minCos
) const
@ -331,7 +101,7 @@ bool Foam::medialAxisMeshMover::isMaxEdge
//- Detect based on extrusion vector differing for both endpoints
// 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.
if ((pointWallDist[e[0]].v() & pointWallDist[e[1]].v()) < minCos)
if ((pointWallDist[e[0]].data() & pointWallDist[e[1]].data()) < minCos)
{
return true;
}
@ -439,11 +209,12 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
pointField pointNormals(PatchTools::pointNormals(mesh(), pp));
// Smooth patch normal vectors
smoothPatchNormals
fieldSmoother_.smoothPatchNormals
(
nSmoothSurfaceNormals,
isPatchMasterPoint,
isPatchMasterEdge,
pp,
pointNormals
);
@ -452,7 +223,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Distance to wall
List<pointData> pointWallDist(mesh().nPoints());
List<PointData<vector> > pointWallDist(mesh().nPoints());
// Dummy additional info for PointEdgeWave
int dummyTrackData = 0;
@ -461,23 +232,22 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// 1. Calculate distance to points where displacement is specified.
{
// Seed data.
List<pointData> wallInfo(meshPoints.size());
List<PointData<vector> > wallInfo(meshPoints.size());
forAll(meshPoints, patchPointI)
{
label pointI = meshPoints[patchPointI];
wallInfo[patchPointI] = pointData
wallInfo[patchPointI] = PointData<vector>
(
points[pointI],
0.0,
pointI, // passive scalar
pointNormals[patchPointI] // surface normals
);
}
// Do all calculations
List<pointData> edgeWallDist(mesh().nEdges());
PointEdgeWave<pointData> wallDistCalc
List<PointData<vector> > edgeWallDist(mesh().nEdges());
PointEdgeWave<PointData<vector> > wallDistCalc
(
mesh(),
meshPoints,
@ -525,11 +295,11 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// 2. Find points with max distance and transport information back to
// wall.
{
List<pointData> pointMedialDist(mesh().nPoints());
List<pointData> edgeMedialDist(mesh().nEdges());
List<pointEdgePoint> pointMedialDist(mesh().nPoints());
List<pointEdgePoint> edgeMedialDist(mesh().nEdges());
// Seed point data.
DynamicList<pointData> maxInfo(meshPoints.size());
DynamicList<pointEdgePoint> maxInfo(meshPoints.size());
DynamicList<label> maxPoints(meshPoints.size());
// 1. Medial axis points
@ -556,12 +326,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI);
maxInfo.append
(
pointData
pointEdgePoint
(
points[pointI],
0.0,
pointI, // passive data
vector::zero // passive data
0.0
)
);
pointMedialDist[pointI] = maxInfo.last();
@ -612,12 +380,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI);
maxInfo.append
(
pointData
pointEdgePoint
(
medialAxisPt, //points[pointI],
magSqr(points[pointI]-medialAxisPt),//0.0,
pointI, // passive data
vector::zero // passive data
magSqr(points[pointI]-medialAxisPt)//0.0
)
);
pointMedialDist[pointI] = maxInfo.last();
@ -669,12 +435,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI);
maxInfo.append
(
pointData
pointEdgePoint
(
points[pointI],
0.0,
pointI, // passive data
vector::zero // passive data
0.0
)
);
pointMedialDist[pointI] = maxInfo.last();
@ -715,7 +479,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
// Check if angle not too large.
scalar cosAngle =
(
-pointWallDist[pointI].v()
-pointWallDist[pointI].data()
& pointNormals[i]
);
if (cosAngle > slipFeatureAngleCos)
@ -726,12 +490,10 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.append(pointI);
maxInfo.append
(
pointData
pointEdgePoint
(
points[pointI],
0.0,
pointI, // passive data
vector::zero // passive data
0.0
)
);
pointMedialDist[pointI] = maxInfo.last();
@ -751,7 +513,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
maxPoints.shrink();
// Do all calculations
PointEdgeWave<pointData> medialDistCalc
PointEdgeWave<pointEdgePoint> medialDistCalc
(
mesh(),
maxPoints,
@ -794,12 +556,12 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
}
else
{
dispVec_[i] = pointWallDist[i].v();
dispVec_[i] = pointWallDist[i].data();
}
}
// Smooth normal vectors. Do not change normals on pp.meshPoints
smoothNormals
fieldSmoother_.smoothNormals
(
nSmoothNormals,
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
// large feature angle
void Foam::medialAxisMeshMover::
@ -1204,7 +893,8 @@ handleFeatureAngleLayerTerminations
//Info<< "Added "
// << 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 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
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)
{
// Stop layer growth where mesh wraps around edge with a
// large feature angle
if (minCosLayerTermination > -1)
{
handleFeatureAngleLayerTerminations
(
minCosLayerTermination,
@ -1266,7 +952,7 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
);
syncPatchDisplacement(minThickness, patchDisp, extrudeStatus);
}
// Detect either:
@ -1389,11 +1075,6 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
{
nPointCounter++;
nChanged++;
if (str.valid())
{
str().write(pp.points()[meshPoints[patchPointI]]);
}
}
}
}
@ -1483,11 +1164,6 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
)
{
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 * * * * * * * * * * * * * * //
Foam::medialAxisMeshMover::medialAxisMeshMover
@ -1630,6 +1214,7 @@ Foam::medialAxisMeshMover::medialAxisMeshMover
adaptPatchIDs_,
dict
),
fieldSmoother_(mesh()),
dispVec_
(
IOobject
@ -1733,10 +1318,12 @@ void Foam::medialAxisMeshMover::calculateDisplacement
const scalar featureAngle = readScalar(coeffDict.lookup("featureAngle"));
//- 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
const label nSmoothPatchThickness = readLabel
@ -1791,9 +1378,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
);
scalarField thickness(patchDisp.size());
thickness = mag(patchDisp);
scalarField thickness(mag(patchDisp));
forAll(thickness, patchPointI)
{
@ -1860,7 +1445,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
vector n =
patchDisp[patchPointI]
/ (mag(patchDisp[patchPointI]) + VSMALL);
vector mVec = mesh().points()[pointI]-medialVec_[pointI];
vector mVec = medialVec_[pointI]-mesh().points()[pointI];
mVec /= mag(mVec)+VSMALL;
thicknessRatio *= (n&mVec);
@ -1947,14 +1532,17 @@ void Foam::medialAxisMeshMover::calculateDisplacement
}
// smooth layer thickness on moving patch
minSmoothField
// Smooth layer thickness on moving patch. Since some locations will have
// 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,
isPatchMasterPoint,
isPatchMasterEdge,
pp,
minThickness,
thickness
);
@ -1962,34 +1550,33 @@ void Foam::medialAxisMeshMover::calculateDisplacement
// Dummy additional info for PointEdgeWave
int dummyTrackData = 0;
List<pointData> pointWallDist(mesh().nPoints());
List<PointData<scalar> > pointWallDist(mesh().nPoints());
const pointField& points = mesh().points();
// 1. Calculate distance to points where displacement is specified.
// This wave is used to transport layer thickness
{
// Distance to wall and medial axis on edges.
List<pointData> edgeWallDist(mesh().nEdges());
List<PointData<scalar> > edgeWallDist(mesh().nEdges());
labelList wallPoints(meshPoints.size());
// Seed data.
List<pointData> wallInfo(meshPoints.size());
List<PointData<scalar> > wallInfo(meshPoints.size());
forAll(meshPoints, patchPointI)
{
label pointI = meshPoints[patchPointI];
wallPoints[patchPointI] = pointI;
wallInfo[patchPointI] = pointData
wallInfo[patchPointI] = PointData<scalar>
(
points[pointI],
0.0,
thickness[patchPointI], // transport layer thickness
vector::zero // passive vector
thickness[patchPointI] // transport layer thickness
);
}
// Do all calculations
PointEdgeWave<pointData> wallDistCalc
PointEdgeWave<PointData<scalar> > wallDistCalc
(
mesh(),
wallPoints,
@ -2016,12 +1603,12 @@ void Foam::medialAxisMeshMover::calculateDisplacement
{
// 1) displacement on nearest wall point, scaled by medialRatio
// (wall distance / medial distance)
// 2) pointWallDist[pointI].s() is layer thickness transported
// 2) pointWallDist[pointI].data() is layer thickness transported
// from closest wall point.
// 3) shrink in opposite direction of addedPoints
displacement[pointI] =
-medialRatio_[pointI]
*pointWallDist[pointI].s()
*pointWallDist[pointI].data()
*dispVec_[pointI];
}
}
@ -2030,11 +1617,20 @@ void Foam::medialAxisMeshMover::calculateDisplacement
// Smear displacement away from fixed values (medialRatio=0 or 1)
if (nSmoothDisplacement > 0)
{
smoothLambdaMuDisplacement
PackedBoolList isToBeSmoothed(displacement.size(), false);
forAll(displacement, i)
{
isToBeSmoothed[i] =
medialRatio_[i] > SMALL && medialRatio_[i] < 1-SMALL;
}
fieldSmoother_.smoothLambdaMuDisplacement
(
nSmoothDisplacement,
isMeshMasterPoint,
isMeshMasterEdge,
isToBeSmoothed,
displacement
);
}
@ -2052,8 +1648,6 @@ bool Foam::medialAxisMeshMover::shrinkMesh
const label nSnap = readLabel(meshQualityDict.lookup("nRelaxIter"));
// Make sure displacement boundary conditions is uptodate with
// internal field
meshMover_.setDisplacementPatchFields();
@ -2119,14 +1713,6 @@ bool Foam::medialAxisMeshMover::move
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
const indirectPrimitivePatch& pp = adaptPatchPtr_();
@ -2180,13 +1766,10 @@ void Foam::medialAxisMeshMover::movePoints(const pointField& p)
{
externalDisplacementMeshMover::movePoints(p);
// Update local data for new geometry
adaptPatchPtr_().movePoints(p);
// Update motionSmoother for new geometry
// Update motionSmoother for new geometry (moves adaptPatchPtr_)
meshMover_.movePoints();
// Assume corrent mesh location is correct
// Assume corrent mesh location is correct (reset oldPoints, scale)
meshMover_.correct();
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,10 +28,13 @@ Description
Mesh motion solver that uses a medial axis algorithm to work
out a fraction between the (nearest point on a) moving surface
and the (nearest point on a) fixed surface.
This fraction is then used to scale the motion. Use
- fixedValue on all moving patches
- zeroFixedValue on stationary 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
medialAxisMeshMover.C
@ -44,13 +47,15 @@ SourceFiles
#include "externalDisplacementMeshMover.H"
#include "motionSmootherAlgo.H"
#include "autoLayerDriver.H"
#include "fieldSmoother.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class pointData;
template <class DataType>
class PointData;
/*---------------------------------------------------------------------------*\
Class medialAxisMeshMover Declaration
@ -75,6 +80,9 @@ class medialAxisMeshMover
//- Mesh mover algorithm
motionSmootherAlgo meshMover_;
//- Field smoothing
fieldSmoother fieldSmoother_;
// Pre-calculated medial axis information
@ -95,45 +103,16 @@ class medialAxisMeshMover
// Private Member Functions
//- Extract fixed-value patchfields
static labelList getFixedValueBCs(const pointVectorField&);
//- Extract bc types. Replace fixedValue derivatives with fixedValue
wordList getPatchFieldTypes(const pointVectorField& fld);
//- Construct patch on selected patches
static autoPtr<indirectPrimitivePatch> getPatch
(
const polyMesh&,
const labelList&
);
// 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
bool isMaxEdge
(
const List<pointData>& pointWallDist,
const List<PointData<vector> >& pointWallDist,
const label edgeI,
const scalar minCos
) const;
@ -161,23 +140,6 @@ class medialAxisMeshMover
List<autoLayerDriver::extrudeMode>& extrudeStatus
) 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
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,6 +51,8 @@ SourceFiles
#include "pointFieldsFwd.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
#include "wordPairHashTable.H"
#include "surfaceZonesInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -66,14 +68,11 @@ class refinementFeatures;
class shellSurfaces;
class removeCells;
class fvMeshDistribute;
class searchableSurface;
class regionSplit;
class globalIndex;
class removePoints;
class localPointRegion;
class snapParameters;
/*---------------------------------------------------------------------------*\
Class meshRefinement Declaration
\*---------------------------------------------------------------------------*/
@ -183,6 +182,14 @@ private:
//- Per cc-cc vector the index of the surface hit
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.
List<Tuple2<mapType, labelList> > userFaceData_;
@ -190,6 +197,15 @@ private:
// order changes.
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
@ -216,9 +232,6 @@ private:
pointField& neiCc
) const;
//- Find any intersection of surface. Store in surfaceIndex_.
void updateIntersections(const labelList& changedFaces);
//- Remove cells. Put exposedFaces into exposedPatchIDs.
autoPtr<mapPolyMesh> doRemoveCells
(
@ -369,10 +382,25 @@ private:
const labelList& globalToSlavePatch
) 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
void getBafflePatches
(
const labelList& globalToMasterPatch,
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const labelList& neiLevel,
const pointField& neiCc,
labelList& ownPatch,
@ -454,7 +482,9 @@ private:
labelList markFacesOnProblemCellsGeometric
(
const snapParameters& snapParams,
const dictionary& motionDict
const dictionary& motionDict,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch
) const;
@ -494,6 +524,16 @@ private:
labelList& cellToZone
) 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.
bool calcRegionToZone
(
@ -508,7 +548,7 @@ private:
// marked in namedSurfaceIndex regarded as blocked.
void findCellZoneTopo
(
const point& keepPoint,
const pointField& locationsInMesh,
const labelList& namedSurfaceIndex,
const labelList& surfaceToCellZone,
labelList& cellToZone
@ -520,6 +560,26 @@ private:
labelList& namedSurfaceIndex
) 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
void handleSnapProblems
(
@ -667,6 +727,13 @@ public:
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
// topo changes. Every entry is a list over all faces.
// Bit of a hack. Additional flag to say whether to maintain master
@ -829,16 +896,29 @@ public:
const bool useTopologicalSnapDetection,
const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle,
// How to handle free-standing baffles
const bool mergeFreeStanding,
const scalar freeStandingAngle,
const dictionary& motionDict,
Time& runTime,
const labelList& globalToMasterPatch,
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
@ -848,7 +928,10 @@ public:
const label nBufferLayers,
const labelList& globalToMasterPatch,
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
@ -859,6 +942,16 @@ public:
// region and split them.
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.
// External faces get repatched according to ownPatch (neiPatch
// should be -1 for these)
@ -868,28 +961,55 @@ public:
const labelList& neiPatch
);
//- Debug helper: check faceZones are not on processor patches
void checkZoneFaces() const;
//- Create baffles for faces straddling zoned surfaces. Return
// baffles.
autoPtr<mapPolyMesh> createZoneBaffles
//- Get zones of given type
labelList getZones
(
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch,
List<labelPair>&
const List<surfaceZonesInfo::faceZoneType>& fzTypes
) const;
//- 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.
autoPtr<mapPolyMesh> mergeBaffles(const List<labelPair>&);
//- Create baffles for faces on faceZones. Return created baffles
// (= 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.
// Returns null if no zone surfaces present. Region containing
// the keepPoint will not be put into a cellZone.
// Returns null if no zone surfaces present. Regions containing
// 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
(
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.
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
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.
static label findRegion
(
@ -926,19 +1069,44 @@ public:
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
(
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch,
const point& keepPoint
const pointField& locationsInMesh,
const pointField& locationsOutsideMesh
);
//- Split faces into two
autoPtr<mapPolyMesh> splitFaces
void doSplitFaces
(
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
@ -986,6 +1154,16 @@ public:
// 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
// to be preserved
label mergePatchFacesUndo

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,110 +34,115 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//// Merge faces that are in-line.
//Foam::label Foam::meshRefinement::mergePatchFaces
//(
// const scalar minCos,
// const scalar concaveCos,
// const labelList& patchIDs
//)
//{
// // Patch face merging engine
// combineFaces faceCombiner(mesh_);
//
// const polyBoundaryMesh& patches = mesh_.boundaryMesh();
//
// // Pick up all candidate cells on boundary
// labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
//
// forAll(patchIDs, i)
// {
// label patchI = patchIDs[i];
//
// const polyPatch& patch = patches[patchI];
//
// if (!patch.coupled())
// {
// forAll(patch, i)
// {
// boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]);
// }
// }
// }
//
// // Get all sets of faces that can be merged
// labelListList mergeSets
// (
// faceCombiner.getMergeSets
// (
// minCos,
// concaveCos,
// boundaryCells
// )
// );
//
// label nFaceSets = returnReduce(mergeSets.size(), sumOp<label>());
//
// Info<< "mergePatchFaces : Merging " << nFaceSets
// << " sets of faces." << endl;
//
// if (nFaceSets > 0)
// {
// // Topology changes container
// polyTopoChange meshMod(mesh_);
//
// // Merge all faces of a set into the first face of the set. Remove
// // unused points.
// faceCombiner.setRefinement(mergeSets, meshMod);
//
// // Change the mesh (no inflation)
// autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, true);
//
// // Update fields
// mesh_.updateMesh(map);
//
// // Move mesh (since morphing does not do this)
// if (map().hasMotionPoints())
// {
// mesh_.movePoints(map().preMotionPoints());
// }
// else
// {
// // Delete mesh volumes. No other way to do this?
// mesh_.clearOut();
// }
//
//
// // Reset the instance for if in overwrite mode
// mesh_.setInstance(timeName());
//
// faceCombiner.updateMesh(map);
//
// // Get the kept faces that need to be recalculated.
// // Merging two boundary faces might shift the cell centre
// // (unless the faces are absolutely planar)
// labelHashSet retestFaces(6*mergeSets.size());
//
// forAll(mergeSets, setI)
// {
// label oldMasterI = mergeSets[setI][0];
//
// label faceI = map().reverseFaceMap()[oldMasterI];
//
// // faceI is always uncoupled boundary face
// const cell& cFaces = mesh_.cells()[mesh_.faceOwner()[faceI]];
//
// forAll(cFaces, i)
// {
// retestFaces.insert(cFaces[i]);
// }
// }
// updateMesh(map, retestFaces.toc());
// }
//
//
// return nFaceSets;
//}
// Merge faces that are in-line.
Foam::label Foam::meshRefinement::mergePatchFaces
(
const scalar minCos,
const scalar concaveCos,
const label mergeSize,
const labelList& patchIDs
)
{
// Patch face merging engine
combineFaces faceCombiner(mesh_, false);
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Pick up all candidate cells on boundary
labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
forAll(patchIDs, i)
{
label patchI = patchIDs[i];
const polyPatch& patch = patches[patchI];
if (!patch.coupled())
{
forAll(patch, i)
{
boundaryCells.insert(mesh_.faceOwner()[patch.start()+i]);
}
}
}
// Get all sets of faces that can be merged
labelListList mergeSets
(
faceCombiner.getMergeSets
(
minCos,
concaveCos,
boundaryCells
)
);
if (mergeSize != -1)
{
// Keep only those that are mergeSize faces
label compactI = 0;
forAll(mergeSets, setI)
{
if (mergeSets[setI].size() == mergeSize)
{
mergeSets[compactI++] = mergeSets[setI];
}
}
mergeSets.setSize(compactI);
}
label nFaceSets = returnReduce(mergeSets.size(), sumOp<label>());
Info<< "Merging " << nFaceSets << " sets of faces." << nl << endl;
if (nFaceSets > 0)
{
// Topology changes container
polyTopoChange meshMod(mesh_);
// Merge all faces of a set into the first face of the set. Remove
// unused points.
faceCombiner.setRefinement(mergeSets, meshMod);
// Change the mesh (no inflation)
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, true);
// Update fields
mesh_.updateMesh(map);
// Move mesh (since morphing does not do this)
if (map().hasMotionPoints())
{
mesh_.movePoints(map().preMotionPoints());
}
else
{
// Delete mesh volumes. No other way to do this?
mesh_.clearOut();
}
// Reset the instance for if in overwrite mode
mesh_.setInstance(timeName());
faceCombiner.updateMesh(map);
// Get the kept faces that need to be recalculated.
// Merging two boundary faces might shift the cell centre
// (unless the faces are absolutely planar)
labelHashSet retestFaces(2*mergeSets.size());
forAll(mergeSets, setI)
{
label oldMasterI = mergeSets[setI][0];
retestFaces.insert(map().reverseFaceMap()[oldMasterI]);
}
updateMesh(map, growFaceCellFace(retestFaces));
}
return nFaceSets;
}
//
//
//// 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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -1085,7 +1085,9 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
(
const snapParameters& snapParams,
const dictionary& motionDict
const dictionary& motionDict,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch
) const
{
pointField oldPoints(mesh_.points());
@ -1162,7 +1164,10 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
(
autoSnapDriver::calcNearestSurface
(
snapParams.strictRegionSnap(),
*this,
globalToMasterPatch,
globalToSlavePatch,
snapDist, // attraction
pp,
nearestPoint,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -980,6 +980,7 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
labelList surfaceMinLevel;
surfaces_.findHigherIntersection
(
shells_,
start,
end,
minLevel,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,6 +33,91 @@ License
#include "UPtrList.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 * * * * * * * * * * * * * * //
Foam::refinementSurfaces::refinementSurfaces
@ -408,19 +493,19 @@ void Foam::refinementSurfaces::setMinLevelFields
{
const searchableSurface& geom = allGeometry_[surfaces_[surfI]];
// Precalculation only makes sense if there are different regions
// (so different refinement levels possible) and there are some
// Cache the refinement level (max of surface level and shell level)
// on a per-element basis. Only makes sense if there are lots of
// elements. Possibly should have 'enough' elements to have fine
// enough resolution but for now just make sure we don't catch e.g.
// searchableBox (size=6)
if (geom.regions().size() > 1 && geom.globalSize() > 10)
if (geom.globalSize() > 10)
{
// Representative local coordinates and bounding sphere
pointField ctrs;
scalarField 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.
// distributed surface where local indices differ from global
@ -447,10 +532,79 @@ void Foam::refinementSurfaces::setMinLevelFields
labelList 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)
{
if (min(minLevelField[i], shellLevel[i]) < 0)
{
minLevelField[i] = -1;
}
else
{
minLevelField[i] = max(minLevelField[i], shellLevel[i]);
}
}
// Store minLevelField on surface
const_cast<searchableSurface&>(geom).setField(minLevelField);
@ -463,6 +617,8 @@ void Foam::refinementSurfaces::setMinLevelFields
// number.
void Foam::refinementSurfaces::findHigherIntersection
(
const shellSurfaces& shells,
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
@ -494,42 +650,49 @@ void Foam::refinementSurfaces::findHigherIntersection
List<pointIndexHit> intersectionInfo(start.size());
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
(
intersectionInfo.size(),
minLevel(surfI, 0)
);
haveLevelField = true;
}
// Get per intersection the region
labelList region;
geom.getRegion(intersectionInfo, region);
if (haveLevelField)
{
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()
&& minLevelField[i] > currentLevel[i]
findHigherLevel
(
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
surfaceLevel[i] = minLevelField[i];
surfaceLevel[i] = localLevel[i];
}
}
return;
}
}
@ -546,40 +709,48 @@ void Foam::refinementSurfaces::findHigherIntersection
// Do intersection test
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.
label missI = 0;
// Surface-based refinement level
labelList surfaceOnlyLevel(intersectionInfo.size(), -1);
{
// Get per intersection the region
labelList region;
geom.getRegion(intersectionInfo, region);
forAll(intersectionInfo, i)
{
// Get the minLevel for the point
label minLocalLevel = -1;
if (intersectionInfo[i].hit())
{
// Check if minLevelField for this surface.
if (minLevelField.size())
{
minLocalLevel = minLevelField[i];
surfaceOnlyLevel[i] = minLevel(surfI, region[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];
if (minLocalLevel > currentLevel[pointI])
if (localLevel[i] > currentLevel[pointI])
{
// Mark point for refinement
surfaces[pointI] = surfI;
surfaceLevel[pointI] = minLocalLevel;
surfaceLevel[pointI] = localLevel[i];
}
else
{
@ -590,6 +761,7 @@ void Foam::refinementSurfaces::findHigherIntersection
}
}
// All done? Note that this decision should be synchronised
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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,6 +42,7 @@ SourceFiles
#include "vectorList.H"
#include "pointIndexHit.H"
#include "surfaceZonesInfo.H"
#include "pointList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,8 +53,6 @@ class searchableSurfaces;
class shellSurfaces;
class triSurfaceMesh;
typedef List<point> pointList;
/*---------------------------------------------------------------------------*\
Class refinementSurfaces Declaration
\*---------------------------------------------------------------------------*/
@ -95,6 +94,16 @@ class refinementSurfaces
// 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
refinementSurfaces(const refinementSurfaces&);
@ -234,6 +243,8 @@ public:
// Return surface number and level.
void findHigherIntersection
(
const shellSurfaces& shells,
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
@ -354,6 +365,37 @@ public:
const pointField& pt,
labelList& insideSurfaces
) 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
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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 labelList& namedSurfaces,
const word& name,
const labelList& addressing,
polyMesh& mesh
)
{
labelList surfaceToCellZone(surfList.size(), -1);
cellZoneMesh& cellZones = mesh.cellZones();
forAll(namedSurfaces, i)
{
label surfI = namedSurfaces[i];
const word& cellZoneName = surfList[surfI].cellZoneName();
if (cellZoneName != word::null)
{
label zoneI = cellZones.findZoneID(cellZoneName);
label zoneI = cellZones.findZoneID(name);
if (zoneI == -1)
{
@ -371,13 +361,40 @@ Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh
zoneI,
new cellZone
(
cellZoneName, //name
labelList(0), //addressing
name, // name
addressing, // addressing
zoneI, // index
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;
}
@ -385,7 +402,7 @@ Foam::labelList Foam::surfaceZonesInfo::addCellZonesToMesh
// Check they are synced
List<wordList> allCellZones(Pstream::nProcs());
allCellZones[Pstream::myProcNo()] = cellZones.names();
allCellZones[Pstream::myProcNo()] = mesh.cellZones().names();
Pstream::gatherList(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
(
const PtrList<surfaceZonesInfo>& surfList,
@ -426,25 +477,13 @@ Foam::labelList Foam::surfaceZonesInfo::addFaceZonesToMesh
const word& faceZoneName = surfList[surfI].faceZoneName();
label zoneI = faceZones.findZoneID(faceZoneName);
if (zoneI == -1)
{
zoneI = faceZones.size();
faceZones.setSize(zoneI+1);
faceZones.set
(
zoneI,
new faceZone
label zoneI = addFaceZone
(
faceZoneName, //name
labelList(0), //addressing
boolList(0), //flipmap
zoneI, //index
faceZones //faceZoneMesh
)
mesh
);
}
surfaceToFaceZone[surfI] = zoneI;
}

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,6 +39,7 @@ SourceFiles
#include "word.H"
#include "PtrList.H"
#include "labelList.H"
#include "boolList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -222,6 +223,13 @@ public:
const PtrList<surfaceZonesInfo>& surfList
);
static label addCellZone
(
const word& name,
const labelList& addressing,
polyMesh& mesh
);
static labelList addCellZonesToMesh
(
const PtrList<surfaceZonesInfo>& surfList,
@ -229,6 +237,14 @@ public:
polyMesh& mesh
);
static label addFaceZone
(
const word& name,
const labelList& addressing,
const boolList& flipMap,
polyMesh& mesh
);
static labelList addFaceZonesToMesh
(
const PtrList<surfaceZonesInfo>& surfList,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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 * * * * * * * * * * * * * * //
// Set up only. Use setFaceInfo and iterate() to do actual calculation.
@ -823,6 +896,7 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
)
:
mesh_(mesh),
explicitConnections_(0),
allFaceInfo_(allFaceInfo),
allCellInfo_(allCellInfo),
td_(td),
@ -878,6 +952,7 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
)
:
mesh_(mesh),
explicitConnections_(0),
allFaceInfo_(allFaceInfo),
allCellInfo_(allCellInfo),
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 * * * * * * * * * * * * * //
@ -1093,6 +1249,10 @@ Foam::label Foam::FaceCellWave<Type, TrackingData>::cellToFace()
// Handled all changed cells by now
nChangedCells_ = 0;
// Transfer across any explicitly provided internal connections
handleExplicitConnections();
if (hasCyclicPatches_)
{
// Transfer changed faces across cyclic halves

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -50,6 +50,7 @@ SourceFiles
#include "boolList.H"
#include "labelList.H"
#include "primitiveFieldsFwd.H"
#include "labelPair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -81,6 +82,9 @@ class FaceCellWave
//- Reference to mesh
const polyMesh& mesh_;
//- Optional boundary faces that information should travel through
const List<labelPair> explicitConnections_;
//- Information for all faces
UList<Type>& allFaceInfo_;
@ -232,6 +236,10 @@ class FaceCellWave
//- Merge data from across AMI cyclics
void handleAMICyclicPatches();
//- Merge data across explicitly provided local connections (usually
// baffles)
void handleExplicitConnections();
// Private static data
@ -286,6 +294,23 @@ public:
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

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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -188,8 +188,10 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
<< " nearest face:" << faceI;
}
const pointField& points = patch_.localPoints();
const typename PatchType::FaceType& f = patch_.localFaces()[faceI];
const typename PatchType::FaceType& localF = 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
// already have point.
@ -242,7 +244,7 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
return indexedOctree<treeDataPrimitivePatch>::getSide
(
patch_.pointNormals()[f[fp]],
patch_.pointNormals()[localF[fp]],
sample - curPt
);
}
@ -280,8 +282,8 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
{
label edgeI = fEdges[fEdgeI];
const edge& e = patch_.edges()[edgeI];
pointHit edgeHit = e.line(points).nearestDist(sample);
const linePointRef ln(points[mp[e.start()]], points[mp[e.end()]]);
pointHit edgeHit = ln.nearestDist(sample);
if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_)
{
@ -322,11 +324,7 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
forAll(f, fp)
{
pointHit edgeHit = linePointRef
(
points[f[fp]],
fc
).nearestDist(sample);
pointHit edgeHit = linePointRef(points[f[fp]], fc).nearestDist(sample);
if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_)
{
@ -369,7 +367,8 @@ Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType
forAll(f, fp)
{
Pout<< " vertex:" << f[fp] << " coord:" << points[f[fp]]
Pout<< " vertex:" << f[fp]
<< " coord:" << points[f[fp]]
<< endl;
}
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,7 +29,6 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Check if n is in same direction as normals of all faceLabels
bool Foam::meshTools::visNormal
(
const vector& n,
@ -309,7 +308,6 @@ bool Foam::meshTools::edgeOnFace
}
// Return true if faceI part of cellI
bool Foam::meshTools::faceOnCell
(
const primitiveMesh& mesh,
@ -465,7 +463,6 @@ Foam::label Foam::meshTools::getSharedFace
}
// Get the two faces on cellI using edgeI.
void Foam::meshTools::getEdgeFaces
(
const primitiveMesh& mesh,
@ -511,7 +508,6 @@ void Foam::meshTools::getEdgeFaces
}
// Return label of other edge connected to vertex
Foam::label Foam::meshTools::otherEdge
(
const primitiveMesh& mesh,
@ -549,7 +545,6 @@ Foam::label Foam::meshTools::otherEdge
}
// Return face on other side of edgeI
Foam::label Foam::meshTools::otherFace
(
const primitiveMesh& mesh,
@ -574,7 +569,6 @@ Foam::label Foam::meshTools::otherFace
}
// Return face on other side of edgeI
Foam::label Foam::meshTools::otherCell
(
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
(
const primitiveMesh& mesh,
@ -688,7 +680,6 @@ void Foam::meshTools::constrainToMeshCentre
}
//- Set the constrained components of directions/velocity to zero
void Foam::meshTools::constrainDirection
(
const polyMesh& mesh,
@ -814,7 +805,6 @@ Foam::vector Foam::meshTools::edgeToCutDir
}
// Find edges most aligned with cutDir
Foam::label Foam::meshTools::cutDirToEdge
(
const primitiveMesh& mesh,

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -200,7 +200,7 @@ namespace meshTools
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
(
const primitiveMesh&,

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -242,6 +242,7 @@ void Foam::localPointRegion::countPointRegions
void Foam::localPointRegion::calcPointRegions
(
const polyMesh& mesh,
const labelPairList& baffles,
boolList& candidatePoint
)
{
@ -423,6 +424,13 @@ void Foam::localPointRegion::calcPointRegions
minEqOpFace(),
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;
}
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."
<< "This is not allowed." << nl
<< "Face:" << meshFace0
<< " fc:" << mesh.faceCentres()[meshFace0]
<< " is on patch:" << patches[patch0].name()
<< nl
<< "Face:" << meshFace1
<< " fc:" << mesh.faceCentres()[meshFace1]
<< " is on patch:" << patches[patch1].name()
<< abort(FatalError);
}
else
{
baffles.append(labelPair(meshFace0, meshFace1));
}
}
}
return baffles.shrink();
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -101,10 +101,10 @@ class localPointRegion
void calcPointRegions
(
const polyMesh& mesh,
const labelPairList& baffles,
boolList& candidatePoint
);
//- Check if two faces are equal. If forward = false checks f1 in
// reverse order.
static bool isDuplicate
@ -133,6 +133,14 @@ public:
const labelList& candidatePoints
);
//- Construct from mesh and candidate points for duplication
localPointRegion
(
const polyMesh& mesh,
const labelPairList& baffles,
const labelList& candidatePoints
);
// 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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,8 +25,8 @@ Class
Foam::searchableSurfaceCollection
Description
Set of transformed searchableSurfaces. Does not do boolean operations.
So when meshing might find parts 'inside'.
Set of transformed searchableSurfaces. Does not do boolean operations
so when meshing might find parts 'inside'.
SourceFiles
searchableSurfaceCollection.C
@ -47,8 +47,6 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
/*---------------------------------------------------------------------------*\
Class searchableSurfaceCollection Declaration
\*---------------------------------------------------------------------------*/

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,6 +34,22 @@ Description
- extend the test vector slightly (with SMALL) to account for numerical
inaccuracies.
\verbatim
sphere.stl
{
type triSurfaceMesh;
}
sphere
{
type searchableSurfaceWithGaps;
// Underlying surface
surface sphere.stl;
// Perturb distance
gap 1e-3;
}
\endverbatim
SourceFiles
searchableSurfaceWithGaps.C

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,9 +27,7 @@ License
#include "searchableSurfacesQueries.H"
#include "ListOps.H"
#include "Time.H"
//#include "vtkSetWriter.H"
#include "DynamicField.H"
//#include "OBJstream.H"
#include "PatchTools.H"
#include "triSurfaceMesh.H"
@ -405,9 +403,9 @@ void Foam::searchableSurfaces::findNearest
// Find nearest. Return -1 or nearest point
void Foam::searchableSurfaces::findNearest
(
const labelListList& regionIndices,
const pointField& samples,
const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo
) const
@ -416,9 +414,11 @@ void Foam::searchableSurfaces::findNearest
(
*this,
allSurfaces_,
regionIndices,
samples,
nearestDistSqr,
regionIndices,
nearestSurfaces,
nearestInfo
);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -200,9 +200,9 @@ public:
void findNearest
(
const labelListList& regionIndices,
const pointField& samples,
const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo
) const;

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -672,9 +672,11 @@ void Foam::searchableSurfacesQueries::findNearest
(
const PtrList<searchableSurface>& allSurfaces,
const labelList& surfacesToTest,
const labelListList& regionIndices,
const pointField& samples,
const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo
)
@ -707,7 +709,7 @@ void Foam::searchableSurfacesQueries::findNearest
(
samples,
minDistSqr,
regionIndices,
regionIndices[testI],
hitInfo
);

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -183,14 +183,14 @@ public:
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
(
const PtrList<searchableSurface>& allSurfaces,
const labelList& surfacesToTest,
const labelListList& regionIndices,
const pointField& samples,
const scalarField& nearestDistSqr,
const labelList& regionIndices,
labelList& nearestSurfaces,
List<pointIndexHit>& nearestInfo
);

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,6 +39,8 @@ namespace Foam
defineTypeNameAndDebug(triSurfaceMesh, 0);
addToRunTimeSelectionTable(searchableSurface, triSurfaceMesh, dict);
word triSurfaceMesh::meshSubDir = "triSurface";
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -231,7 +233,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
(
io.name(),
io.instance(),
io.local(),
io.local(), //"triSurfaceFields",
io.db(),
io.readOpt(),
io.writeOpt(),
@ -239,9 +241,10 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
)
),
triSurface(s),
triSurfaceRegionSearch(s),
triSurfaceRegionSearch(static_cast<const triSurface&>(*this)),
minQuality_(-1),
surfaceClosed_(-1)
surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{
const pointField& pts = triSurface::points();
@ -272,7 +275,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
(
io.name(),
static_cast<const searchableSurface&>(*this).instance(),
io.local(),
io.local(), //"triSurfaceFields",
io.db(),
io.readOpt(),
io.writeOpt(),
@ -289,7 +292,8 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
),
triSurfaceRegionSearch(static_cast<const triSurface&>(*this)),
minQuality_(-1),
surfaceClosed_(-1)
surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{
const pointField& pts = triSurface::points();
@ -323,7 +327,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
(
io.name(),
static_cast<const searchableSurface&>(*this).instance(),
io.local(),
io.local(), //"triSurfaceFields",
io.db(),
io.readOpt(),
io.writeOpt(),
@ -340,7 +344,8 @@ Foam::triSurfaceMesh::triSurfaceMesh
),
triSurfaceRegionSearch(static_cast<const triSurface&>(*this), dict),
minQuality_(-1),
surfaceClosed_(-1)
surfaceClosed_(-1),
outsideVolType_(volumeType::UNKNOWN)
{
scalar scaleFactor = 0;
@ -377,6 +382,7 @@ Foam::triSurfaceMesh::~triSurfaceMesh()
void Foam::triSurfaceMesh::clearOut()
{
outsideVolType_ = volumeType::UNKNOWN;
triSurfaceRegionSearch::clearOut();
edgeTree_.clear();
triSurface::clearOut();
@ -447,9 +453,22 @@ bool Foam::triSurfaceMesh::overlaps(const boundBox& bb) const
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();
edgeTree_.clear();
triSurface::movePoints(newPoints);
bounds() = boundBox(triSurface::points());
}
@ -713,6 +732,19 @@ void Foam::triSurfaceMesh::getNormal
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
(
@ -722,7 +754,7 @@ void Foam::triSurfaceMesh::setField(const labelList& values)
(
"values",
objectRegistry::time().timeName(), // instance
"triSurface", // local
meshSubDir, // local
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
@ -736,6 +768,7 @@ void Foam::triSurfaceMesh::setField(const labelList& values)
// Store field on triMesh
fldPtr.ptr()->store();
}
}
void Foam::triSurfaceMesh::getField
@ -780,18 +813,27 @@ void Foam::triSurfaceMesh::getVolumeType
const point& pt = points[pointI];
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
volType[pointI] = tree().shapes().getVolumeType(tree(), pt);
}
}
else
{
// - use cached volume type per each tree node
volType[pointI] = tree().getVolumeType(pt);
}
// Info<< "octree : " << pt << " = "
// << volumeType::names[volType[pointI]] << endl;
}
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
@ -806,6 +848,24 @@ bool Foam::triSurfaceMesh::writeObject
IOstream::compressionType cmp
) 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());
if (!mkDir(fullPath.path()))

View File

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

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,7 +47,7 @@ addToRunTimeSelectionTable(topoSetSource, regionToCell, istream);
Foam::topoSetSource::addToUsageTable Foam::regionToCell::usage_
(
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"
" points (pt0..ptn).\n"
);
@ -433,7 +433,7 @@ Foam::regionToCell::regionToCell
topoSetSource(mesh),
setName_(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
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -65,16 +65,16 @@ class surfaceToPoint
static addToUsageTable usage_;
//- Name of surface file
fileName surfName_;
const fileName surfName_;
//- 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.
bool includeInside_;
const bool includeInside_;
//- Include all points on this sign of normal on nearest surface.
bool includeOutside_;
const bool includeOutside_;
// Private Member Functions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,8 +36,24 @@ License
namespace Foam
{
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 * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -170,6 +170,11 @@ public:
// surface. (Produces multiply connected surface)
};
// Static data
static const NamedEnum<booleanOpType, 4> booleanOpTypeNames;
// Constructors

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -716,66 +716,35 @@ Foam::faceList Foam::intersectedSurface::resplitFace
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
// can compare number to facePointEdges.
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)
{
label edgeI = iter.key();
const edge& e = eSurf.edges()[edgeI];
label stat = iter();
if (stat == STARTTOEND || stat == ENDTOSTART)
{
incCount(pointVisited, e[0], 1);
incCount(pointVisited, e[1], 1);
str1 << "l " << e[0]+1 << ' ' << e[1]+1 << nl;
}
else if (stat == BOTH)
{
incCount(pointVisited, e[0], 2);
incCount(pointVisited, e[1], 2);
str2 << "l " << e[0]+1 << ' ' << e[1]+1 << nl;
}
else if (stat == UNVISITED)
{
incCount(pointVisited, e[0], 0);
incCount(pointVisited, e[1], 0);
str0 << "l " << e[0]+1 << ' ' << e[1]+1 << nl;
}
}
}
if (debug)
{
forAllConstIter(Map<label>, pointVisited, iter)
{
@ -838,8 +807,6 @@ Foam::faceList Foam::intersectedSurface::resplitFace
// Find second intersection.
label visitedVert1 = -1;
label unvisitedVert1 = -1;
{
scalar minDist = GREAT;
@ -876,8 +843,6 @@ Foam::faceList Foam::intersectedSurface::resplitFace
if (nearDist < minDist)
{
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
edgeList additionalEdges(1);
additionalEdges[0] = edge(visitedVert0, unvisitedVert0);
eSurf.addIntersectionEdges(faceI, additionalEdges);
if (debug)
{
fileName newFName("face_" + Foam::name(faceI) + "_newEdges.obj");
Pout<< "Dumping face:" << faceI << " to " << newFName << endl;
writeLocalOBJ
@ -911,6 +867,7 @@ Foam::faceList Foam::intersectedSurface::resplitFace
eSurf.faceEdges()[faceI],
newFName
);
}
// Retry splitFace. Use recursion since is rare situation.
return splitFace(surf, faceI, eSurf);
@ -1085,20 +1042,6 @@ Foam::faceList Foam::intersectedSurface::splitFace
}
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
// should be one nearest to any fully visited edge.
return resplitFace
@ -1220,34 +1163,6 @@ Foam::intersectedSurface::intersectedSurface
forAll(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 label region = surf[faceI].region();

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -54,7 +54,6 @@ void Foam::edgeIntersections::checkEdges(const triSurface& surf)
{
const pointField& localPoints = surf.localPoints();
const edgeList& edges = surf.edges();
const labelListList& edgeFaces = surf.edgeFaces();
treeBoundBox bb(localPoints);
@ -78,19 +77,6 @@ void Foam::edgeIntersections::checkEdges(const triSurface& surf)
<< "This might lead to problems in intersection"
<< 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
(
const triSurface& surf1,
@ -478,16 +463,9 @@ Foam::edgeIntersections::edgeIntersections
classification_(surf1.nEdges())
{
checkEdges(surf1);
checkEdges(query2.surface());
// Current set of edges to test
labelList edgesToTest(surf1.nEdges());
// Start off with all edges
forAll(edgesToTest, i)
{
edgesToTest[i] = i;
}
labelList edgesToTest(identity(surf1.nEdges()));
// Determine intersections for edgesToTest
intersectEdges

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -242,9 +242,9 @@ void Foam::surfaceIntersection::storeIntersection
WarningIn
(
"Foam::surfaceIntersection::storeIntersection"
"(const bool isFirstSurf, const labelList& facesA,"
"const label faceB, DynamicList<edge>& allCutEdges,"
"DynamicList<point>& allCutPoints)"
"(const bool, const labelList&,"
"const label, DynamicList<edge>&,"
"DynamicList<point>&)"
) << "Encountered degenerate edge between face "
<< twoFaces[0] << " on first 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
(
const triSurface& surf1,

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -163,7 +163,7 @@ Foam::triSurfaceRegionSearch::treeByRegion() const
(
treeDataIndirectTriSurface
(
true,
false, //true,
indirectRegionPatches_[regionI],
tolerance()
),
@ -211,6 +211,7 @@ void Foam::triSurfaceRegionSearch::findNearest
}
const treeType& octree = octrees[treeI];
const treeDataIndirectTriSurface::findNearestOp nearOp(octree);
forAll(samples, i)
{
@ -223,7 +224,7 @@ void Foam::triSurfaceRegionSearch::findNearest
(
samples[i],
nearestDistSqr[i],
treeDataIndirectTriSurface::findNearestOp(octree)
nearOp
);
if

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -234,7 +234,7 @@ Foam::triSurfaceSearch::tree() const
(
new indexedOctree<treeDataTriSurface>
(
treeDataTriSurface(true, surface_, tolerance_),
treeDataTriSurface(false, surface_, tolerance_),
bb,
maxTreeDepth_, // maxLevel
10, // leafsize
@ -290,15 +290,17 @@ void Foam::triSurfaceSearch::findNearest
const indexedOctree<treeDataTriSurface>& octree = tree();
const treeDataTriSurface::findNearestOp fOp(octree);
info.setSize(samples.size());
forAll(samples, i)
{
static_cast<pointIndexHit&>(info[i]) = octree.findNearest
info[i] = octree.findNearest
(
samples[i],
nearestDistSqr[i],
treeDataTriSurface::findNearestOp(octree)
fOp
);
}
@ -335,11 +337,7 @@ void Foam::triSurfaceSearch::findLine
forAll(start, i)
{
static_cast<pointIndexHit&>(info[i]) = octree.findLine
(
start[i],
end[i]
);
info[i] = octree.findLine(start[i], end[i]);
}
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
@ -362,11 +360,7 @@ void Foam::triSurfaceSearch::findLineAny
forAll(start, i)
{
static_cast<pointIndexHit&>(info[i]) = octree.findLineAny
(
start[i],
end[i]
);
info[i] = octree.findLineAny(start[i], end[i]);
}
indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;

View File

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