mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' of ssh://noisy/home/noisy2/OpenFOAM/OpenFOAM-dev
This commit is contained in:
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -33,12 +33,86 @@ Description
|
|||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "autoHexMeshDriver.H"
|
#include "autoRefineDriver.H"
|
||||||
|
#include "autoSnapDriver.H"
|
||||||
|
#include "autoLayerDriver.H"
|
||||||
|
#include "searchableSurfaces.H"
|
||||||
|
#include "refinementSurfaces.H"
|
||||||
|
#include "shellSurfaces.H"
|
||||||
|
#include "decompositionMethod.H"
|
||||||
|
#include "fvMeshDistribute.H"
|
||||||
|
#include "wallPolyPatch.H"
|
||||||
|
#include "refinementParameters.H"
|
||||||
|
#include "snapParameters.H"
|
||||||
|
#include "layerParameters.H"
|
||||||
|
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Check writing tolerance before doing any serious work
|
||||||
|
scalar getMergeDistance(const polyMesh& mesh, const scalar mergeTol)
|
||||||
|
{
|
||||||
|
const boundBox& meshBb = mesh.bounds();
|
||||||
|
scalar mergeDist = mergeTol*mag(meshBb.max() - meshBb.min());
|
||||||
|
scalar writeTol = std::pow
|
||||||
|
(
|
||||||
|
scalar(10.0),
|
||||||
|
-scalar(IOstream::defaultPrecision())
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Overall mesh bounding box : " << meshBb << nl
|
||||||
|
<< "Relative tolerance : " << mergeTol << nl
|
||||||
|
<< "Absolute matching distance : " << mergeDist << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (mesh.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol)
|
||||||
|
{
|
||||||
|
FatalErrorIn("getMergeDistance(const polyMesh&, const scalar)")
|
||||||
|
<< "Your current settings specify ASCII writing with "
|
||||||
|
<< IOstream::defaultPrecision() << " digits precision." << endl
|
||||||
|
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
|
||||||
|
<< endl
|
||||||
|
<< "Please change your writeFormat to binary"
|
||||||
|
<< " or increase the writePrecision" << endl
|
||||||
|
<< "or adjust the merge tolerance (-mergeTol)."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergeDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Write mesh and additional information
|
||||||
|
void writeMesh
|
||||||
|
(
|
||||||
|
const string& msg,
|
||||||
|
const meshRefinement& meshRefiner,
|
||||||
|
const label debug
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner.mesh();
|
||||||
|
|
||||||
|
meshRefiner.printMeshInfo(debug, msg);
|
||||||
|
Info<< "Writing mesh to time " << mesh.time().timeName() << endl;
|
||||||
|
|
||||||
|
meshRefiner.write(meshRefinement::MESH|meshRefinement::SCALARLEVELS, "");
|
||||||
|
if (debug & meshRefinement::OBJINTERSECTIONS)
|
||||||
|
{
|
||||||
|
meshRefiner.write
|
||||||
|
(
|
||||||
|
meshRefinement::OBJINTERSECTIONS,
|
||||||
|
mesh.time().path()/mesh.time().timeName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Info<< "Written mesh in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
@ -49,6 +123,11 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Read mesh in = "
|
Info<< "Read mesh in = "
|
||||||
<< runTime.cpuTimeIncrement() << " s" << endl;
|
<< runTime.cpuTimeIncrement() << " s" << endl;
|
||||||
|
|
||||||
|
// Check patches and faceZones are synchronised
|
||||||
|
mesh.boundaryMesh().checkParallelSync(true);
|
||||||
|
meshRefinement::checkCoupledFaceZones(mesh);
|
||||||
|
|
||||||
|
|
||||||
// Read decomposePar dictionary
|
// Read decomposePar dictionary
|
||||||
IOdictionary decomposeDict
|
IOdictionary decomposeDict
|
||||||
(
|
(
|
||||||
@ -75,47 +154,282 @@ int main(int argc, char *argv[])
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// refinement parameters
|
// all surface geometry
|
||||||
const dictionary& refineDict = meshDict.subDict("refineDict");
|
const dictionary& geometryDict = meshDict.subDict("geometry");
|
||||||
|
|
||||||
// snap-to-surface parameters
|
// refinement parameters
|
||||||
const dictionary& snapDict = meshDict.subDict("snapDict");
|
const dictionary& refineDict = meshDict.subDict("castellatedMeshControls");
|
||||||
|
|
||||||
// mesh motion and mesh quality parameters
|
// mesh motion and mesh quality parameters
|
||||||
const dictionary& motionDict = meshDict.subDict("motionDict");
|
const dictionary& motionDict = meshDict.subDict("meshQualityControls");
|
||||||
|
|
||||||
|
// snap-to-surface parameters
|
||||||
|
const dictionary& snapDict = meshDict.subDict("snapControls");
|
||||||
|
|
||||||
// layer addition parameters
|
// layer addition parameters
|
||||||
const dictionary& layerDict = meshDict.subDict("layerDict");
|
const dictionary& layerDict = meshDict.subDict("addLayersControls");
|
||||||
|
|
||||||
|
|
||||||
// Main meshing driver. Read surfaces. Determine initial intersections.
|
|
||||||
autoHexMeshDriver meshEngine
|
// Debug
|
||||||
|
// ~~~~~
|
||||||
|
|
||||||
|
const label debug(readLabel(meshDict.lookup("debug")));
|
||||||
|
if (debug > 0)
|
||||||
|
{
|
||||||
|
meshRefinement::debug = debug;
|
||||||
|
autoRefineDriver::debug = debug;
|
||||||
|
autoSnapDriver::debug = debug;
|
||||||
|
autoLayerDriver::debug = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read geometry
|
||||||
|
// ~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
searchableSurfaces allGeometry
|
||||||
(
|
(
|
||||||
mesh,
|
IOobject
|
||||||
meshDict, // global control parameters
|
(
|
||||||
refineDict, // refinement parameters
|
"abc", // dummy name
|
||||||
decomposeDict
|
mesh.time().constant(), // directory
|
||||||
|
"triSurface", // instance
|
||||||
|
mesh.time(), // registry
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
geometryDict
|
||||||
);
|
);
|
||||||
|
|
||||||
Switch wantRefine(meshDict.lookup("doRefine"));
|
|
||||||
Switch wantSnap(meshDict.lookup("doSnap"));
|
// Read refinement surfaces
|
||||||
Switch wantLayers(meshDict.lookup("doLayers"));
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Info<< "Reading refinement surfaces." << endl;
|
||||||
|
refinementSurfaces surfaces
|
||||||
|
(
|
||||||
|
allGeometry,
|
||||||
|
refineDict.subDict("refinementSurfaces")
|
||||||
|
);
|
||||||
|
Info<< "Read refinement surfaces in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Read refinement shells
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Info<< "Reading refinement shells." << endl;
|
||||||
|
shellSurfaces shells
|
||||||
|
(
|
||||||
|
allGeometry,
|
||||||
|
refineDict.subDict("refinementRegions")
|
||||||
|
);
|
||||||
|
Info<< "Read refinement shells in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Setting refinement level of surface to be consistent"
|
||||||
|
<< " with shells." << endl;
|
||||||
|
surfaces.setMinLevelFields(shells);
|
||||||
|
Info<< "Checked shell refinement in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add all the surface regions as patches
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelList globalToPatch;
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Adding patches for surface regions" << nl
|
||||||
|
<< "----------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
// From global region number to mesh patch.
|
||||||
|
globalToPatch.setSize(surfaces.nRegions(), -1);
|
||||||
|
|
||||||
|
Info<< "Patch\tRegion" << nl
|
||||||
|
<< "-----\t------"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const labelList& surfaceGeometry = surfaces.surfaces();
|
||||||
|
forAll(surfaceGeometry, surfI)
|
||||||
|
{
|
||||||
|
label geomI = surfaceGeometry[surfI];
|
||||||
|
|
||||||
|
const wordList& regNames = allGeometry.regionNames()[geomI];
|
||||||
|
|
||||||
|
Info<< surfaces.names()[surfI] << ':' << nl << nl;
|
||||||
|
|
||||||
|
forAll(regNames, i)
|
||||||
|
{
|
||||||
|
label patchI = meshRefinement::addPatch
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
regNames[i],
|
||||||
|
wallPolyPatch::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< patchI << '\t' << regNames[i] << nl;
|
||||||
|
|
||||||
|
globalToPatch[surfaces.globalRegion(surfI, i)] = patchI;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl;
|
||||||
|
}
|
||||||
|
Info<< "Added patches in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parallel
|
||||||
|
// ~~~~~~~~
|
||||||
|
|
||||||
|
// Decomposition
|
||||||
|
autoPtr<decompositionMethod> decomposerPtr
|
||||||
|
(
|
||||||
|
decompositionMethod::New
|
||||||
|
(
|
||||||
|
decomposeDict,
|
||||||
|
mesh
|
||||||
|
)
|
||||||
|
);
|
||||||
|
decompositionMethod& decomposer = decomposerPtr();
|
||||||
|
|
||||||
|
if (Pstream::parRun() && !decomposer.parallelAware())
|
||||||
|
{
|
||||||
|
FatalErrorIn(args.executable())
|
||||||
|
<< "You have selected decomposition method "
|
||||||
|
<< decomposer.typeName
|
||||||
|
<< " which is not parallel aware." << endl
|
||||||
|
<< "Please select one that is (hierarchical, parMetis)"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalar mergeDist = getMergeDistance
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
readScalar(meshDict.lookup("mergeTolerance"))
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Mesh distribution engine (uses tolerance to reconstruct meshes)
|
||||||
|
fvMeshDistribute distributor(mesh, mergeDist);
|
||||||
|
|
||||||
|
|
||||||
|
// Refinement engine
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Determining initial surface intersections" << nl
|
||||||
|
<< "-----------------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
// Main refinement engine
|
||||||
|
meshRefinement meshRefiner
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
mergeDist, // tolerance used in sorting coordinates
|
||||||
|
surfaces, // for surface intersection refinement
|
||||||
|
shells // for volume (inside/outside) refinement
|
||||||
|
);
|
||||||
|
Info<< "Calculated surface intersections in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||||
|
|
||||||
|
// Some stats
|
||||||
|
meshRefiner.printMeshInfo(debug, "Initial mesh");
|
||||||
|
|
||||||
|
meshRefiner.write
|
||||||
|
(
|
||||||
|
debug&meshRefinement::OBJINTERSECTIONS,
|
||||||
|
mesh.time().path()/mesh.time().timeName()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Now do the real work -refinement -snapping -layers
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Switch wantRefine(meshDict.lookup("castellatedMesh"));
|
||||||
|
Switch wantSnap(meshDict.lookup("snap"));
|
||||||
|
Switch wantLayers(meshDict.lookup("addLayers"));
|
||||||
|
|
||||||
if (wantRefine)
|
if (wantRefine)
|
||||||
{
|
{
|
||||||
meshEngine.doRefine(refineDict, wantSnap);
|
autoRefineDriver refineDriver
|
||||||
|
(
|
||||||
|
meshRefiner,
|
||||||
|
decomposer,
|
||||||
|
distributor,
|
||||||
|
globalToPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
// Refinement parameters
|
||||||
|
refinementParameters refineParams(refineDict);
|
||||||
|
|
||||||
|
refineDriver.doRefine(refineDict, refineParams, wantSnap);
|
||||||
|
|
||||||
|
writeMesh
|
||||||
|
(
|
||||||
|
"Refined mesh",
|
||||||
|
meshRefiner,
|
||||||
|
debug
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantSnap)
|
if (wantSnap)
|
||||||
{
|
{
|
||||||
meshEngine.doSnap(snapDict, motionDict);
|
autoSnapDriver snapDriver
|
||||||
|
(
|
||||||
|
meshRefiner,
|
||||||
|
globalToPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
// Snap parameters
|
||||||
|
snapParameters snapParams(snapDict);
|
||||||
|
|
||||||
|
snapDriver.doSnap(snapDict, motionDict, snapParams);
|
||||||
|
|
||||||
|
writeMesh
|
||||||
|
(
|
||||||
|
"Snapped mesh",
|
||||||
|
meshRefiner,
|
||||||
|
debug
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantLayers)
|
if (wantLayers)
|
||||||
{
|
{
|
||||||
meshEngine.doLayers(layerDict, motionDict);
|
autoLayerDriver layerDriver
|
||||||
|
(
|
||||||
|
meshRefiner,
|
||||||
|
globalToPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
// Layer addition parameters
|
||||||
|
layerParameters layerParams(layerDict, mesh.boundaryMesh());
|
||||||
|
|
||||||
|
layerDriver.doLayers
|
||||||
|
(
|
||||||
|
layerDict,
|
||||||
|
motionDict,
|
||||||
|
layerParams,
|
||||||
|
decomposer,
|
||||||
|
distributor
|
||||||
|
);
|
||||||
|
|
||||||
|
writeMesh
|
||||||
|
(
|
||||||
|
"Layer mesh",
|
||||||
|
meshRefiner,
|
||||||
|
debug
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Info<< "Finished meshing in = "
|
Info<< "Finished meshing in = "
|
||||||
<< runTime.elapsedCpuTime() << " s." << endl;
|
<< runTime.elapsedCpuTime() << " s." << endl;
|
||||||
|
|
||||||
|
|||||||
@ -22,70 +22,88 @@ FoamFile
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Which phases to run.
|
// Which of the steps to run
|
||||||
doRefine true;
|
castellatedMesh true;
|
||||||
doSnap true;
|
snap true;
|
||||||
doLayers true; // includes autoMergeFaces
|
addLayers false;
|
||||||
|
|
||||||
|
|
||||||
// Whether to dump intermediate meshes and print lots
|
// Geometry. Definition of all surfaces. All surfaces are of class
|
||||||
// 1 : write mesh
|
// searchableSurface.
|
||||||
// 2 : write volScalarField with cellLevel for postprocessing
|
// Surfaces are used
|
||||||
// 4 : write current intersections as .obj files
|
// - to specify refinement for any mesh cell intersecting it
|
||||||
debug 0;
|
// - to specify refinement for any mesh cell inside/outside/near
|
||||||
|
// - to 'snap' the mesh boundary to the surface
|
||||||
refineDict
|
geometry
|
||||||
{
|
{
|
||||||
// Which part to keep.
|
box1x1x1
|
||||||
// NOTE: This point should never be on a face, always inside a cell, even
|
{
|
||||||
// after refinement.
|
type searchableBox;
|
||||||
keepPoints ((3 0.28 0.43));
|
min (1.5 1 -0.5);
|
||||||
|
max (3.5 2 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
// Whether to remove/split cells likely to give problems when snapping
|
sphere.stl
|
||||||
handleSnapProblems on;
|
{
|
||||||
|
type triSurfaceMesh;
|
||||||
|
|
||||||
// Merge tolerance. Is fraction of overall bounding box of initial mesh
|
// Per region the patchname. If not provided will be <name>_<region>.
|
||||||
mergeTolerance 1E-6;
|
regions
|
||||||
|
{
|
||||||
|
secondSolid
|
||||||
|
{
|
||||||
|
name mySecondPatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sphere2
|
||||||
|
{
|
||||||
|
type searchableSphere;
|
||||||
|
centre (1.5 1.5 1.5);
|
||||||
|
radius 1.03;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Settings for the castellatedMesh generation.
|
||||||
|
castellatedMeshControls
|
||||||
|
{
|
||||||
|
|
||||||
|
// Refinement parameters
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// While refining maximum number of cells per processor. This is basically
|
// While refining maximum number of cells per processor. This is basically
|
||||||
// the number of cells that fit on a processor. If you choose this too small
|
// the number of cells that fit on a processor. If you choose this too small
|
||||||
// it will do just more refinement iterations to obtain a similar mesh.
|
// it will do just more refinement iterations to obtain a similar mesh.
|
||||||
procCellLimit 1000000;
|
maxLocalCells 1000000;
|
||||||
|
|
||||||
|
|
||||||
// Overall cell limit (approximately). Refinement will stop immediately
|
// Overall cell limit (approximately). Refinement will stop immediately
|
||||||
// upon reaching this number so a refinement level might not complete.
|
// upon reaching this number so a refinement level might not complete.
|
||||||
// Note that this is the number of cells before removing the part which
|
// Note that this is the number of cells before removing the part which
|
||||||
// is not 'visible' from the keepPoint. The final number of cells might actually
|
// is not 'visible' from the keepPoint. The final number of cells might
|
||||||
// be a lot less.
|
// actually be a lot less.
|
||||||
cellLimit 2000000;
|
maxGlobalCells 2000000;
|
||||||
|
|
||||||
|
|
||||||
// The surface refinement loop might spend lots of iterations refining just a
|
// The surface refinement loop might spend lots of iterations refining just a
|
||||||
// few cells. This setting will cause refinement to stop if <= minimumRefine
|
// few cells. This setting will cause refinement to stop if <= minimumRefine
|
||||||
// are selected for refinement. Note: it will at least do one iteration
|
// are selected for refinement. Note: it will at least do one iteration
|
||||||
// (unless the number of cells to refine is 0)
|
// (unless the number of cells to refine is 0)
|
||||||
minimumRefine 0;
|
minRefinementCells 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Number of buffer layers between different levels.
|
// Number of buffer layers between different levels.
|
||||||
// 1 means normal 2:1 refinement restriction, larger means slower
|
// 1 means normal 2:1 refinement restriction, larger means slower
|
||||||
// refinement.
|
// refinement.
|
||||||
nBufferLayers 1;
|
nCellsBetweenLevels 1;
|
||||||
|
|
||||||
|
|
||||||
// Feature Edge Refinement
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
// External feature file. Read from constant/triSurface for now.
|
// Explicit feature edge refinement
|
||||||
// Limitations:
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// - either start or edge of any feature line has to be inside domain
|
|
||||||
// and be visible from keepPoint on starting mesh.
|
// Specifies a level for any cell intersected by its edges.
|
||||||
// - refining cells containing features is separate phase before refining
|
// This is a featureEdgeMesh, read from constant/triSurface for now.
|
||||||
// based on surface.
|
|
||||||
// - no load balancing, no check for cellLimit is done while doing this.
|
|
||||||
features
|
features
|
||||||
(
|
(
|
||||||
//{
|
//{
|
||||||
@ -95,88 +113,80 @@ refineDict
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Internal Mesh Refinement
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
// Specifies the areas where the refinement has to be a certain level.
|
|
||||||
// These surfaces have to be closed. Refinement is either inside
|
|
||||||
// (refineInside = true) or outside. (note:insideness or outsideness
|
|
||||||
// is with respect to far away)
|
|
||||||
// Note:that even using these the transition can never be faster than
|
|
||||||
// nBufferLayers!
|
|
||||||
// Note:the refinement level can never be higher than any of the surfaces
|
|
||||||
// they overlap with. See below for the surface refinement level specification.
|
|
||||||
refinementShells
|
|
||||||
(
|
|
||||||
{
|
|
||||||
//type triSurfaceMesh;
|
|
||||||
//name cube1x1x1.stl;
|
|
||||||
type searchableBox;
|
|
||||||
name box1x1x1;
|
|
||||||
min (2.5 -0.5 -0.5);
|
|
||||||
max (3.5 0.5 0.5);
|
|
||||||
|
|
||||||
level 4;
|
|
||||||
refineInside true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Surface based refinement
|
// Surface based refinement
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Curvature. Cosine of angle between two neighbouring surface intersections.
|
// Specifies two levels for every surface. The first is the minimum level,
|
||||||
// Only used if cell level > minLevel and < maxLevel.
|
// every cell intersecting a surface gets refined up to the minimum level.
|
||||||
curvature 0.5;
|
// The second level is the maximum level. Cells that 'see' multiple
|
||||||
|
// intersections where the intersections make an
|
||||||
|
// angle > resolveFeatureAngle get refined up to the maximum level.
|
||||||
|
|
||||||
|
refinementSurfaces
|
||||||
// Overall the refinement is according to the following rules:
|
|
||||||
// - if the cell-cell vector intersects a surface any cell that
|
|
||||||
// is less refined than the minRefinementLevel of the surface gets refined.
|
|
||||||
// - else if the refinement level of the cell is between the
|
|
||||||
// minRefinementLevel and maxRefinementLevel the cell gets refined if
|
|
||||||
// - the normal of neighbouring surface intersections differ by more
|
|
||||||
// than above curvature
|
|
||||||
// - or if neighbouring surface intersections are on different surfaces or
|
|
||||||
// different surface regions.
|
|
||||||
|
|
||||||
|
|
||||||
// surfaces
|
|
||||||
surfaces
|
|
||||||
(
|
|
||||||
{
|
{
|
||||||
name sphere;
|
sphere.stl
|
||||||
file "sphere.stl";
|
{
|
||||||
|
// Surface-wise min and max refinement level
|
||||||
|
level (2 2);
|
||||||
|
|
||||||
// Surface wide refinement level
|
// Optional region-wise level specification
|
||||||
minRefinementLevel 1;
|
|
||||||
maxRefinementLevel 1;
|
|
||||||
|
|
||||||
// Layers
|
|
||||||
surfaceLayers 1;
|
|
||||||
|
|
||||||
// Region specific refinement level
|
|
||||||
regions
|
regions
|
||||||
(
|
|
||||||
{
|
{
|
||||||
name firstSolid;
|
secondSolid
|
||||||
minRefinementLevel 3;
|
|
||||||
maxRefinementLevel 3;
|
|
||||||
surfaceLayers 2;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name secondSolid;
|
level (3 3);
|
||||||
minRefinementLevel 1;
|
}
|
||||||
maxRefinementLevel 1;
|
|
||||||
surfaceLayers 1;
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For snapping
|
resolveFeatureAngle 30;
|
||||||
snapDict
|
|
||||||
|
|
||||||
|
// Region-wise refinement
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Specifies refinement level for cells in relation to a surface. One of
|
||||||
|
// three modes
|
||||||
|
// - distance. 'levels' specifies per distance to the surface the
|
||||||
|
// wanted refinement level. The distances need to be specified in
|
||||||
|
// descending order.
|
||||||
|
// - inside. 'levels' is only one entry and only the level is used. All
|
||||||
|
// cells inside the surface get refined up to the level. The surface
|
||||||
|
// needs to be closed for this to be possible.
|
||||||
|
// - outside. Same but cells outside.
|
||||||
|
|
||||||
|
refinementRegions
|
||||||
|
{
|
||||||
|
box1x1x1
|
||||||
|
{
|
||||||
|
mode inside;
|
||||||
|
levels ((1.0 4));
|
||||||
|
}
|
||||||
|
//sphere.stl
|
||||||
|
//{
|
||||||
|
// mode distance;
|
||||||
|
// levels ((1.0 5) (2.0 3));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mesh selection
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// NOTE: This point should never be on a face, always inside a cell, even
|
||||||
|
// after refinement.
|
||||||
|
locationInMesh (5 0.28 0.43);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Settings for the snapping.
|
||||||
|
snapControls
|
||||||
{
|
{
|
||||||
//- Number of patch smoothing iterations before finding correspondence
|
//- Number of patch smoothing iterations before finding correspondence
|
||||||
// to surface
|
// to surface
|
||||||
@ -185,47 +195,64 @@ snapDict
|
|||||||
//- Relative distance for points to be attracted by surface feature point
|
//- Relative distance for points to be attracted by surface feature point
|
||||||
// or edge. True distance is this factor times local
|
// or edge. True distance is this factor times local
|
||||||
// maximum edge length.
|
// maximum edge length.
|
||||||
snapTol 4.0;
|
tolerance 4.0;
|
||||||
|
|
||||||
//- Whether to move internal mesh as well as boundary
|
//- Number of mesh displacement relaxation iterations.
|
||||||
smoothMesh true;
|
nSolveIter 30;
|
||||||
|
|
||||||
//- Number of mesh displacement smoothing iterations.
|
|
||||||
nSmoothDispl 30;
|
|
||||||
|
|
||||||
//- Maximum number of snapping relaxation iterations. Should stop
|
//- Maximum number of snapping relaxation iterations. Should stop
|
||||||
// before upon reaching a correct mesh.
|
// before upon reaching a correct mesh.
|
||||||
nSnap 5;
|
nRelaxIter 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// For cell layers
|
|
||||||
layerDict
|
// Settings for the layer addition.
|
||||||
|
addLayersControls
|
||||||
{
|
{
|
||||||
|
// Per final patch (so not geometry!) the layer information
|
||||||
|
layers
|
||||||
|
{
|
||||||
|
sphere.stl_firstSolid
|
||||||
|
{
|
||||||
|
nSurfaceLayers 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
maxY
|
||||||
|
{
|
||||||
|
nSurfaceLayers 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expansion factor for layer mesh
|
||||||
|
expansionRatio 1.0;
|
||||||
|
|
||||||
|
//- Wanted thickness of final added cell layer. If multiple layers
|
||||||
|
// is the
|
||||||
|
// thickness of the layer furthest away from the wall.
|
||||||
|
// Relative to undistorted size of cell outside layer.
|
||||||
|
finalLayerRatio 0.3;
|
||||||
|
|
||||||
|
//- Minimum thickness of cell layer. If for any reason layer
|
||||||
|
// cannot be above minThickness do not add layer.
|
||||||
|
// Relative to undistorted size of cell outside layer.
|
||||||
|
minThickness 0.25;
|
||||||
|
|
||||||
|
//- If points get not extruded do nGrow layers of connected faces that are
|
||||||
|
// also not grown. This helps convergence of the layer addition process
|
||||||
|
// close to features.
|
||||||
|
nGrow 1;
|
||||||
|
|
||||||
|
|
||||||
|
// Advanced settings
|
||||||
|
|
||||||
//- When not to extrude surface. 0 is flat surface, 90 is when two faces
|
//- When not to extrude surface. 0 is flat surface, 90 is when two faces
|
||||||
// make straight angle.
|
// make straight angle.
|
||||||
featureAngle 60;
|
featureAngle 60;
|
||||||
|
|
||||||
//- Maximum number of snapping relaxation iterations. Should stop
|
//- Maximum number of snapping relaxation iterations. Should stop
|
||||||
// before upon reaching a correct mesh.
|
// before upon reaching a correct mesh.
|
||||||
nSnap 5;
|
nRelaxIter 5;
|
||||||
|
|
||||||
|
|
||||||
//- Minimum thickness of cell layer. If for any reason layer cannot be
|
|
||||||
// above minThickness do not add layer if thickness below minThickNess.
|
|
||||||
// Relative to undistorted cell size
|
|
||||||
minThickness 0.25;
|
|
||||||
|
|
||||||
//- If points get not extruded do nGrow layers of connected faces that are
|
|
||||||
// not grown. Is used to not do layers at all close to features.
|
|
||||||
nGrow 1;
|
|
||||||
|
|
||||||
// Expansion factor for layer mesh
|
|
||||||
expansionRatio 1.3;
|
|
||||||
|
|
||||||
// Ratio of cell size in final added cell layer to cell size
|
|
||||||
// outside layer
|
|
||||||
finalLayerRatio 0.3;
|
|
||||||
|
|
||||||
// Number of smoothing iterations of surface normals
|
// Number of smoothing iterations of surface normals
|
||||||
nSmoothSurfaceNormals 1;
|
nSmoothSurfaceNormals 1;
|
||||||
@ -248,20 +275,14 @@ layerDict
|
|||||||
|
|
||||||
// Create buffer region for new layer terminations
|
// Create buffer region for new layer terminations
|
||||||
nBufferCellsNoExtrude 0;
|
nBufferCellsNoExtrude 0;
|
||||||
|
|
||||||
thickness 0.5;
|
|
||||||
nSmoothDispl 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// For mesh motion
|
|
||||||
motionDict
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Mesh Quality Parameters. Decide when mesh is good enough to stop
|
|
||||||
// smoothing.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
// Generic mesh quality settings. At any undoable phase these determine
|
||||||
|
// where to undo.
|
||||||
|
meshQualityControls
|
||||||
|
{
|
||||||
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||||
maxNonOrtho 65;
|
maxNonOrtho 65;
|
||||||
|
|
||||||
@ -298,10 +319,10 @@ motionDict
|
|||||||
//- minVolRatio (0 -> 1)
|
//- minVolRatio (0 -> 1)
|
||||||
minVolRatio 0.01;
|
minVolRatio 0.01;
|
||||||
|
|
||||||
|
|
||||||
//must be >0 for Fluent compatibility
|
//must be >0 for Fluent compatibility
|
||||||
minTriangleTwist -1;
|
minTriangleTwist -1;
|
||||||
|
|
||||||
|
|
||||||
// Advanced
|
// Advanced
|
||||||
|
|
||||||
//- Number of error distribution iterations
|
//- Number of error distribution iterations
|
||||||
@ -311,4 +332,19 @@ motionDict
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Advanced
|
||||||
|
|
||||||
|
// Flags for optional output
|
||||||
|
// 0 : only write final meshes
|
||||||
|
// 1 : write intermediate meshes
|
||||||
|
// 2 : write volScalarField with cellLevel for postprocessing
|
||||||
|
// 4 : write current intersections as .obj files
|
||||||
|
debug 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Merge tolerance. Is fraction of overall bounding box of initial mesh.
|
||||||
|
// Note: the write tolerance needs to be higher than this.
|
||||||
|
mergeTolerance 1E-6;
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -73,13 +73,16 @@ find -H $packDir \
|
|||||||
-a ! -name "core" \
|
-a ! -name "core" \
|
||||||
-a ! -name "core.[1-9]*" \
|
-a ! -name "core.[1-9]*" \
|
||||||
-a ! -name "log[0-9]*" \
|
-a ! -name "log[0-9]*" \
|
||||||
|
-a ! -name "libccmio*" \
|
||||||
-a ! -name "\.ebrowse" \
|
-a ! -name "\.ebrowse" \
|
||||||
| sed \
|
| sed \
|
||||||
-e "\@$packDir/.git/@d" \
|
-e "\@$packDir/.git/@d" \
|
||||||
-e "\@$packDir/lib/@d" \
|
-e "\@$packDir/lib/@d" \
|
||||||
|
-e "\@libccmio.*/@d" \
|
||||||
-e '\@applications/bin/@d' \
|
-e '\@applications/bin/@d' \
|
||||||
-e '\@/t/@d' \
|
-e '\@/t/@d' \
|
||||||
-e '\@Make[.A-Za-z]*/[^/]*/@d'\
|
-e '\@Make[.A-Za-z]*/[^/]*/@d'\
|
||||||
|
-e '\@/platforms/@d' \
|
||||||
> $tmpFile
|
> $tmpFile
|
||||||
|
|
||||||
tar czpf $packFile --files-from $tmpFile
|
tar czpf $packFile --files-from $tmpFile
|
||||||
|
|||||||
78
bin/foamPackThirdPartyBin
Executable file
78
bin/foamPackThirdPartyBin
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# ========= |
|
||||||
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
# \\ / O peration |
|
||||||
|
# \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
# \\/ M anipulation |
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# 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 2 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, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# Script
|
||||||
|
# foamPackThirdPartyBin <archOptions> [outputDir]
|
||||||
|
#
|
||||||
|
# Description
|
||||||
|
# Packs and compresses binary version of OpenFOAM ThirdParty for release
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ $# = 0 ]
|
||||||
|
then
|
||||||
|
echo "Error: archOptionsitecture type expected, exiting"
|
||||||
|
echo
|
||||||
|
echo "Usage : ${0##*/} <archOptions> [outputDir]"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
archOptions=$1
|
||||||
|
arch=${archOptions%%G*}
|
||||||
|
arch3264=$(echo "$arch" | sed 's@64@-64@')
|
||||||
|
|
||||||
|
timeStamp=$(date +%Y-%m-%d)
|
||||||
|
packDir=ThirdParty
|
||||||
|
packFile=${packDir}.${archOptions}_${timeStamp}.gtgz
|
||||||
|
|
||||||
|
# add optional output directory
|
||||||
|
if [ -d "$2" ]
|
||||||
|
then
|
||||||
|
packFile="$2/$packFile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $packFile ]
|
||||||
|
then
|
||||||
|
echo "Error: $packFile already exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get list of directories
|
||||||
|
dirList=`find $packDir -type d -name $arch -o -type d -name $archOptions -o -type l -name $arch3264`
|
||||||
|
echo
|
||||||
|
echo "Packing $archOptions port of $packDir into $packFile"
|
||||||
|
echo
|
||||||
|
|
||||||
|
tar czpf $packFile $dirList
|
||||||
|
|
||||||
|
if [ $? = 0 ]
|
||||||
|
then
|
||||||
|
echo "Finished packing and compressing file $packFile"
|
||||||
|
else
|
||||||
|
echo "Error: failure packing $packFile"
|
||||||
|
rm -f $packFile 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
70
bin/foamPackThirdPartyGeneral
Executable file
70
bin/foamPackThirdPartyGeneral
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# ========= |
|
||||||
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
# \\ / O peration |
|
||||||
|
# \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
# \\/ M anipulation |
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# 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 2 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, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# Script
|
||||||
|
# foamPackThirdPartyGeneral [outputDir]
|
||||||
|
#
|
||||||
|
# Description
|
||||||
|
# Packs and compresses the OpenFOAM ThirdParty directory for release
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
timeStamp=$(date +%Y-%m-%d)
|
||||||
|
packDir=ThirdParty
|
||||||
|
packFile=${packDir}.General_${timeStamp}.gtgz
|
||||||
|
|
||||||
|
if [ ! -d $packDir ]
|
||||||
|
then
|
||||||
|
echo "Error: directory $packDir does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add optional output directory
|
||||||
|
if [ -d "$1" ]
|
||||||
|
then
|
||||||
|
packFile="$1/$packFile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $packFile ]
|
||||||
|
then
|
||||||
|
echo "Error: $packFile already exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create time stamp file
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
echo $timeStamp 2>/dev/null > $packDir/.timeStamp
|
||||||
|
|
||||||
|
# Pack and compress the packFile
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Packing $packDir into $packFile"
|
||||||
|
echo
|
||||||
|
|
||||||
|
foamPackSource $packDir $packFile
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
@ -26,40 +26,14 @@ License
|
|||||||
|
|
||||||
#include "interpolationTable.H"
|
#include "interpolationTable.H"
|
||||||
#include "IFstream.H"
|
#include "IFstream.H"
|
||||||
#include "objectRegistry.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::interpolationTable<Type>::interpolationTable()
|
void Foam::interpolationTable<Type>::readTable()
|
||||||
:
|
|
||||||
List<Tuple2<scalar, Type> >(),
|
|
||||||
dict_(dictionary::null),
|
|
||||||
boundAction_(interpolationTable::WARN),
|
|
||||||
fileName_("undefined_fileName")
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::interpolationTable<Type>::interpolationTable
|
|
||||||
(
|
|
||||||
const objectRegistry& obr,
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
List<Tuple2<scalar, Type> >(),
|
|
||||||
dict_(dict),
|
|
||||||
boundAction_(wordToBoundAction(dict.lookup("boundAction"))),
|
|
||||||
fileName_(dict.lookup("fileName"))
|
|
||||||
{
|
{
|
||||||
fileName_.expand();
|
fileName_.expand();
|
||||||
|
|
||||||
// Correct for relative path
|
|
||||||
if (fileName_[0] != '/')
|
|
||||||
{
|
|
||||||
fileName_ = obr.db().path()/fileName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read data from file
|
// Read data from file
|
||||||
IFstream(fileName_)() >> *this;
|
IFstream(fileName_)() >> *this;
|
||||||
|
|
||||||
@ -78,6 +52,39 @@ Foam::interpolationTable<Type>::interpolationTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::interpolationTable<Type>::interpolationTable()
|
||||||
|
:
|
||||||
|
List<Tuple2<scalar, Type> >(),
|
||||||
|
boundAction_(interpolationTable::WARN),
|
||||||
|
fileName_("undefined_fileName")
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::interpolationTable<Type>::interpolationTable(const fileName& fn)
|
||||||
|
:
|
||||||
|
List<Tuple2<scalar, Type> >(),
|
||||||
|
boundAction_(interpolationTable::WARN),
|
||||||
|
fileName_(fn)
|
||||||
|
{
|
||||||
|
readTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::interpolationTable<Type>::interpolationTable(const dictionary& dict)
|
||||||
|
:
|
||||||
|
List<Tuple2<scalar, Type> >(),
|
||||||
|
boundAction_(wordToBoundAction(dict.lookup("boundAction"))),
|
||||||
|
fileName_(dict.lookup("fileName"))
|
||||||
|
{
|
||||||
|
readTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::interpolationTable<Type>::interpolationTable
|
Foam::interpolationTable<Type>::interpolationTable
|
||||||
(
|
(
|
||||||
@ -85,18 +92,11 @@ Foam::interpolationTable<Type>::interpolationTable
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
List<Tuple2<scalar, Type> >(interpTable),
|
List<Tuple2<scalar, Type> >(interpTable),
|
||||||
dict_(interpTable.dict_),
|
|
||||||
boundAction_(interpTable.boundAction_),
|
boundAction_(interpTable.boundAction_),
|
||||||
fileName_(interpTable.fileName_)
|
fileName_(interpTable.fileName_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::interpolationTable<Type>::~interpolationTable()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ Foam::interpolationTable<Type>::wordToBoundAction
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::interpolationTable<Type>::check() const
|
void Foam::interpolationTable<Type>::check() const
|
||||||
{
|
{
|
||||||
label n = size();
|
label n = this->size();
|
||||||
scalar prevValue = List<Tuple2<scalar, Type> >::operator[](0).first();
|
scalar prevValue = List<Tuple2<scalar, Type> >::operator[](0).first();
|
||||||
|
|
||||||
for (label i=1; i<n; ++i)
|
for (label i=1; i<n; ++i)
|
||||||
@ -227,7 +227,7 @@ const Foam::Tuple2<Foam::scalar, Type>&
|
|||||||
Foam::interpolationTable<Type>::operator[](const label i) const
|
Foam::interpolationTable<Type>::operator[](const label i) const
|
||||||
{
|
{
|
||||||
label ii = i;
|
label ii = i;
|
||||||
label n = size();
|
label n = this->size();
|
||||||
|
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
{
|
{
|
||||||
@ -321,7 +321,7 @@ Foam::interpolationTable<Type>::operator[](const label i) const
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
Type Foam::interpolationTable<Type>::operator()(const scalar value) const
|
Type Foam::interpolationTable<Type>::operator()(const scalar value) const
|
||||||
{
|
{
|
||||||
label n = size();
|
label n = this->size();
|
||||||
|
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -84,9 +84,6 @@ private:
|
|||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- Parent dictionary
|
|
||||||
const dictionary& dict_;
|
|
||||||
|
|
||||||
//- Enumeration for handling out-of-bound values
|
//- Enumeration for handling out-of-bound values
|
||||||
boundActions boundAction_;
|
boundActions boundAction_;
|
||||||
|
|
||||||
@ -94,6 +91,12 @@ private:
|
|||||||
fileName fileName_;
|
fileName fileName_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Read the table of data from file
|
||||||
|
void readTable();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
@ -101,47 +104,37 @@ public:
|
|||||||
//- Construct null
|
//- Construct null
|
||||||
interpolationTable();
|
interpolationTable();
|
||||||
|
|
||||||
//- Construct from objectRegistry and dictionary
|
//- Construct given the name of the file containing the table of data
|
||||||
interpolationTable(const objectRegistry& obr, const dictionary& dict);
|
interpolationTable(const fileName& fn);
|
||||||
|
|
||||||
|
//- Construct by reading the fileName and boundAction from dictionary
|
||||||
|
// and read the table from that file.
|
||||||
|
// This is a specialised constructor used by patchFields
|
||||||
|
interpolationTable(const dictionary& dict);
|
||||||
|
|
||||||
//- Construct copy
|
//- Construct copy
|
||||||
interpolationTable(const interpolationTable& interpTable);
|
interpolationTable(const interpolationTable& interpTable);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~interpolationTable();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
//- Return the size
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return List<Tuple2<scalar, Type> >::size();
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the out-of-bounds treatment as a word
|
//- Return the out-of-bounds treatment as a word
|
||||||
word boundActionToWord(const boundActions& bound) const;
|
word boundActionToWord(const boundActions& bound) const;
|
||||||
|
|
||||||
//- Return the out-of-bounds treatment as an enumeration
|
//- Return the out-of-bounds treatment as an enumeration
|
||||||
boundActions wordToBoundAction(const word& bound) const;
|
boundActions wordToBoundAction(const word& bound) const;
|
||||||
|
|
||||||
|
|
||||||
// Check
|
|
||||||
|
|
||||||
//- Check that list is monotonically increasing
|
//- Check that list is monotonically increasing
|
||||||
// Exit with a FatalError if there is a problem
|
// Exit with a FatalError if there is a problem
|
||||||
void check() const;
|
void check() const;
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
|
||||||
|
|
||||||
//- Set the out-of-bounds treatment from enum, return previous
|
//- Set the out-of-bounds treatment from enum, return previous
|
||||||
// setting
|
// setting
|
||||||
boundActions boundAction(const boundActions& bound);
|
boundActions boundAction(const boundActions& bound);
|
||||||
|
|
||||||
|
//- Write
|
||||||
|
void write(Ostream& os) const;
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
@ -150,12 +143,6 @@ public:
|
|||||||
|
|
||||||
//- Return an interpolated value
|
//- Return an interpolated value
|
||||||
Type operator()(const scalar) const;
|
Type operator()(const scalar) const;
|
||||||
|
|
||||||
|
|
||||||
// I-O
|
|
||||||
|
|
||||||
//- Write
|
|
||||||
void write(Ostream& os) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -169,6 +156,8 @@ public:
|
|||||||
# include "interpolationTable.C"
|
# include "interpolationTable.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -1,15 +1,23 @@
|
|||||||
autoHexMesh = autoHexMesh
|
autoHexMesh = autoHexMesh
|
||||||
|
autoHexMeshDriver = $(autoHexMesh)/autoHexMeshDriver
|
||||||
|
|
||||||
|
$(autoHexMeshDriver)/autoLayerDriver.C
|
||||||
|
$(autoHexMeshDriver)/autoLayerDriverShrink.C
|
||||||
|
$(autoHexMeshDriver)/autoSnapDriver.C
|
||||||
|
$(autoHexMeshDriver)/autoRefineDriver.C
|
||||||
|
$(autoHexMeshDriver)/autoHexMeshDriver.C
|
||||||
|
|
||||||
|
$(autoHexMeshDriver)/layerParameters/layerParameters.C
|
||||||
|
$(autoHexMeshDriver)/refinementParameters/refinementParameters.C
|
||||||
|
$(autoHexMeshDriver)/snapParameters/snapParameters.C
|
||||||
|
$(autoHexMeshDriver)/pointData/pointData.C
|
||||||
|
|
||||||
$(autoHexMesh)/autoHexMeshDriver/autoHexMeshDriver.C
|
|
||||||
$(autoHexMesh)/autoHexMeshDriver/autoHexMeshDriverLayers.C
|
|
||||||
$(autoHexMesh)/autoHexMeshDriver/autoHexMeshDriverShrink.C
|
|
||||||
$(autoHexMesh)/autoHexMeshDriver/autoHexMeshDriverSnap.C
|
|
||||||
$(autoHexMesh)/autoHexMeshDriver/pointData/pointData.C
|
|
||||||
$(autoHexMesh)/meshRefinement/meshRefinementBaffles.C
|
$(autoHexMesh)/meshRefinement/meshRefinementBaffles.C
|
||||||
$(autoHexMesh)/meshRefinement/meshRefinement.C
|
$(autoHexMesh)/meshRefinement/meshRefinement.C
|
||||||
$(autoHexMesh)/meshRefinement/meshRefinementMerge.C
|
$(autoHexMesh)/meshRefinement/meshRefinementMerge.C
|
||||||
$(autoHexMesh)/meshRefinement/meshRefinementRefine.C
|
$(autoHexMesh)/meshRefinement/meshRefinementRefine.C
|
||||||
$(autoHexMesh)/refinementSurfaces/refinementSurfaces.C
|
$(autoHexMesh)/refinementSurfaces/refinementSurfaces.C
|
||||||
|
$(autoHexMesh)/shellSurfaces/shellSurfaces.C
|
||||||
$(autoHexMesh)/trackedParticle/trackedParticle.C
|
$(autoHexMesh)/trackedParticle/trackedParticle.C
|
||||||
$(autoHexMesh)/trackedParticle/trackedParticleCloud.C
|
$(autoHexMesh)/trackedParticle/trackedParticleCloud.C
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -30,10 +30,6 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
autoHexMeshDriver.C
|
autoHexMeshDriver.C
|
||||||
autoHexMeshDriverSnap.C
|
|
||||||
autoHexMeshDriverLayers.C
|
|
||||||
autoHexMeshDriverShrink.C
|
|
||||||
autoHexMeshDriverTemplates.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -44,13 +40,10 @@ SourceFiles
|
|||||||
#include "dictionary.H"
|
#include "dictionary.H"
|
||||||
#include "pointField.H"
|
#include "pointField.H"
|
||||||
#include "boolList.H"
|
#include "boolList.H"
|
||||||
#include "Switch.H"
|
|
||||||
#include "PackedList.H"
|
|
||||||
#include "wallPoint.H"
|
#include "wallPoint.H"
|
||||||
#include "indirectPrimitivePatch.H"
|
#include "searchableSurfaces.H"
|
||||||
#include "featureEdgeMesh.H"
|
|
||||||
#include "searchableSurface.H"
|
|
||||||
#include "refinementSurfaces.H"
|
#include "refinementSurfaces.H"
|
||||||
|
#include "shellSurfaces.H"
|
||||||
#include "meshRefinement.H"
|
#include "meshRefinement.H"
|
||||||
#include "decompositionMethod.H"
|
#include "decompositionMethod.H"
|
||||||
#include "fvMeshDistribute.H"
|
#include "fvMeshDistribute.H"
|
||||||
@ -62,14 +55,6 @@ namespace Foam
|
|||||||
|
|
||||||
// Class forward declarations
|
// Class forward declarations
|
||||||
class fvMesh;
|
class fvMesh;
|
||||||
class pointMesh;
|
|
||||||
class motionSmoother;
|
|
||||||
class removePoints;
|
|
||||||
class pointSet;
|
|
||||||
class pointData;
|
|
||||||
class faceSet;
|
|
||||||
class addPatchCellLayer;
|
|
||||||
class mapDistributePolyMesh;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class autoHexMeshDriver Declaration
|
Class autoHexMeshDriver Declaration
|
||||||
@ -79,15 +64,13 @@ class autoHexMeshDriver
|
|||||||
{
|
{
|
||||||
// Static data members
|
// Static data members
|
||||||
|
|
||||||
//- Default angle for faces to be convcave
|
|
||||||
static const scalar defaultConcaveAngle;
|
|
||||||
|
|
||||||
//- Extrusion controls
|
//- Extrusion controls
|
||||||
enum extrudeMode
|
enum extrudeMode
|
||||||
{
|
{
|
||||||
NOEXTRUDE, /*!< Do not extrude. No layers added. */
|
NOEXTRUDE, /*!< Do not extrude. No layers added. */
|
||||||
EXTRUDE, /*!< Extrude */
|
EXTRUDE, /*!< Extrude */
|
||||||
EXTRUDEREMOVE /*!< Extrude but afterwards remove added faces locally */
|
EXTRUDEREMOVE /*!< Extrude but afterwards remove added */
|
||||||
|
/*!< faces locally */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -141,42 +124,17 @@ class autoHexMeshDriver
|
|||||||
//- Debug level
|
//- Debug level
|
||||||
const label debug_;
|
const label debug_;
|
||||||
|
|
||||||
//- Total number of cells
|
|
||||||
const label maxGlobalCells_;
|
|
||||||
|
|
||||||
//- Per processor max number of cells
|
|
||||||
const label maxLocalCells_;
|
|
||||||
|
|
||||||
//- When to stop refining
|
|
||||||
const label minRefineCells_;
|
|
||||||
|
|
||||||
//- Curvature
|
|
||||||
const scalar curvature_;
|
|
||||||
|
|
||||||
//- Number of layers between different refinement levels
|
|
||||||
const label nBufferLayers_;
|
|
||||||
|
|
||||||
//- Areas to keep
|
|
||||||
const pointField keepPoints_;
|
|
||||||
|
|
||||||
//- Merge distance
|
//- Merge distance
|
||||||
const scalar mergeDist_;
|
const scalar mergeDist_;
|
||||||
|
|
||||||
|
|
||||||
|
//- All surface based geometry
|
||||||
|
autoPtr<searchableSurfaces> allGeometryPtr_;
|
||||||
|
|
||||||
//- Explicit features
|
//- Shells (geometry for inside/outside refinement)
|
||||||
PtrList<featureEdgeMesh> featureMeshes_;
|
autoPtr<shellSurfaces> shellsPtr_;
|
||||||
//- Per feature the refinement level
|
|
||||||
labelList featureLevels_;
|
|
||||||
|
|
||||||
//- Shells
|
//- Surfaces (geometry for intersection based refinement)
|
||||||
PtrList<searchableSurface> shells_;
|
|
||||||
//- Per shell the refinement level
|
|
||||||
labelList shellLevels_;
|
|
||||||
//- Per shell whether to refine inside or outside
|
|
||||||
boolList shellRefineInside_;
|
|
||||||
|
|
||||||
//- Surfaces with refinement levels built-in
|
|
||||||
autoPtr<refinementSurfaces> surfacesPtr_;
|
autoPtr<refinementSurfaces> surfacesPtr_;
|
||||||
|
|
||||||
//- Per refinement surface region the patch
|
//- Per refinement surface region the patch
|
||||||
@ -195,434 +153,10 @@ class autoHexMeshDriver
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
// Refinement
|
|
||||||
|
|
||||||
//- Calculate merge distance. Check against writing tolerance.
|
//- Calculate merge distance. Check against writing tolerance.
|
||||||
scalar getMergeDistance(const scalar mergeTol) const;
|
scalar getMergeDistance(const scalar mergeTol) const;
|
||||||
|
|
||||||
// Return per keeppoint -1 or the local cell label the point is in.
|
//static void orientOutside(PtrList<searchableSurface>&);
|
||||||
// Guaranteed to be only on one processor.
|
|
||||||
labelList findCells(const pointField&) const;
|
|
||||||
|
|
||||||
static void orientOutside(PtrList<searchableSurface>&);
|
|
||||||
|
|
||||||
//- Read feature edges
|
|
||||||
label readFeatureEdges(const PtrList<dictionary>&);
|
|
||||||
|
|
||||||
// Snapping
|
|
||||||
|
|
||||||
//- Split surfaces into non-zoned and zones ones
|
|
||||||
void getZonedSurfaces(labelList&, labelList&) const;
|
|
||||||
|
|
||||||
//- Get faces to repatch. Returns map from face to patch.
|
|
||||||
Map<label> getZoneBafflePatches(const bool allowBoundary) const;
|
|
||||||
|
|
||||||
//- Calculates (geometric) shared points
|
|
||||||
static label getCollocatedPoints
|
|
||||||
(
|
|
||||||
const scalar tol,
|
|
||||||
const pointField&,
|
|
||||||
PackedList<1>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Calculate displacement per patch point to smooth out patch.
|
|
||||||
// Quite complicated in determining which points to move where.
|
|
||||||
pointField smoothPatchDisplacement(const motionSmoother&) const;
|
|
||||||
|
|
||||||
//- Check that face zones are synced
|
|
||||||
void checkCoupledFaceZones() const;
|
|
||||||
|
|
||||||
//- Per edge distance to patch
|
|
||||||
static tmp<scalarField> edgePatchDist
|
|
||||||
(
|
|
||||||
const pointMesh&,
|
|
||||||
const indirectPrimitivePatch&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Write displacement as .obj file.
|
|
||||||
static void dumpMove
|
|
||||||
(
|
|
||||||
const fileName&,
|
|
||||||
const pointField&,
|
|
||||||
const pointField&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Check displacement is outwards pointing
|
|
||||||
static bool outwardsDisplacement
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch&,
|
|
||||||
const vectorField&
|
|
||||||
);
|
|
||||||
|
|
||||||
// Face merging
|
|
||||||
|
|
||||||
//- Merge patch faces. Undo until no checkMesh errors.
|
|
||||||
label mergePatchFacesUndo
|
|
||||||
(
|
|
||||||
const scalar minCos,
|
|
||||||
const scalar concaveCos,
|
|
||||||
const dictionary&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Remove points.
|
|
||||||
autoPtr<mapPolyMesh> doRemovePoints
|
|
||||||
(
|
|
||||||
removePoints& pointRemover,
|
|
||||||
const boolList& pointCanBeDeleted
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Restore faces (which contain removed points)
|
|
||||||
autoPtr<mapPolyMesh> doRestorePoints
|
|
||||||
(
|
|
||||||
removePoints& pointRemover,
|
|
||||||
const labelList& facesToRestore
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Return candidateFaces that are also in set.
|
|
||||||
labelList collectFaces
|
|
||||||
(
|
|
||||||
const labelList& candidateFaces,
|
|
||||||
const labelHashSet& set
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Pick up faces of cells of faces in set.
|
|
||||||
labelList growFaceCellFace(const labelHashSet&) const;
|
|
||||||
|
|
||||||
//- Remove points not used by any face or points used by only
|
|
||||||
// two faces where the edges are in line
|
|
||||||
label mergeEdgesUndo(const scalar minCos, const dictionary&);
|
|
||||||
|
|
||||||
|
|
||||||
// Layers
|
|
||||||
|
|
||||||
//- For debugging: Dump displacement to .obj files
|
|
||||||
static void dumpDisplacement
|
|
||||||
(
|
|
||||||
const fileName&,
|
|
||||||
const indirectPrimitivePatch&,
|
|
||||||
const vectorField&,
|
|
||||||
const List<extrudeMode>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Check that primitivePatch is not multiply connected.
|
|
||||||
// Collect non-manifold points in pointSet.
|
|
||||||
static void checkManifold
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch&,
|
|
||||||
pointSet& nonManifoldPoints
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Static extrusion setup
|
|
||||||
|
|
||||||
//- Unset extrusion on point. Returns true if anything unset.
|
|
||||||
static bool unmarkExtrusion
|
|
||||||
(
|
|
||||||
const label patchPointI,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Unset extrusion on face. Returns true if anything unset.
|
|
||||||
static bool unmarkExtrusion
|
|
||||||
(
|
|
||||||
const face& localFace,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
//- No extrusion at non-manifold points.
|
|
||||||
void handleNonManifolds
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- No extrusion on feature edges. Assumes non-manifold
|
|
||||||
// edges already handled.
|
|
||||||
void handleFeatureAngle
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
const scalar minCos,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- No extrusion on warped faces
|
|
||||||
void handleWarpedFaces
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const scalar faceRatio,
|
|
||||||
const scalar edge0Len,
|
|
||||||
const labelList& cellLevel,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Determine the number of layers per point from the number of
|
|
||||||
// layers per surface.
|
|
||||||
void setNumLayers
|
|
||||||
(
|
|
||||||
const labelList& patchIDs,
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Grow no-extrusion layer.
|
|
||||||
static void growNoExtrusion
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Calculate pointwise wanted and minimum thickness.
|
|
||||||
// thickness: wanted thickness
|
|
||||||
// minthickness: when to give up and not extrude
|
|
||||||
void calculateLayerThickness
|
|
||||||
(
|
|
||||||
const scalar expansionRatio,
|
|
||||||
const scalar finalLayerRatio,
|
|
||||||
const scalar relMinThickness,
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const labelList& cellLevel,
|
|
||||||
const labelList& patchNLayers,
|
|
||||||
const scalar edge0Len,
|
|
||||||
scalarField& thickness,
|
|
||||||
scalarField& minThickness
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Extrusion execution
|
|
||||||
|
|
||||||
//- Synchronize displacement among coupled patches.
|
|
||||||
void syncPatchDisplacement
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const scalarField& minThickness,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Get nearest point on surface to snap to
|
|
||||||
void getPatchDisplacement
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const scalarField& thickness,
|
|
||||||
const scalarField& minThickness,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Truncates displacement
|
|
||||||
// - for all patchFaces in the faceset displacement gets set
|
|
||||||
// to zero
|
|
||||||
// - all displacement < minThickness gets set to zero
|
|
||||||
label truncateDisplacement
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const scalarField& minThickness,
|
|
||||||
const faceSet& illegalPatchFaces,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Setup layer information (at points and faces) to
|
|
||||||
// modify mesh topology in
|
|
||||||
// regions where layer mesh terminates. Guarantees an
|
|
||||||
// optional slow decreasing of the number of layers.
|
|
||||||
// Returns the number of layers per face and per point
|
|
||||||
// to go into the actual layer addition engine.
|
|
||||||
void setupLayerInfoTruncation
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const labelList& patchNLayers,
|
|
||||||
const List<extrudeMode>& extrudeStatus,
|
|
||||||
const label nBufferCellsNoExtrude,
|
|
||||||
labelList& nPatchPointLayers,
|
|
||||||
labelList& nPatchFaceLayers
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does any of the cells use a face from faces?
|
|
||||||
static bool cellsUseFace
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const labelList& cellLabels,
|
|
||||||
const labelHashSet& faces
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Checks the newly added cells and locally unmarks points
|
|
||||||
// so they will not get extruded next time round. Returns
|
|
||||||
// global number of unmarked points (0 if all was fine)
|
|
||||||
static label checkAndUnmark
|
|
||||||
(
|
|
||||||
const addPatchCellLayer& addLayer,
|
|
||||||
const dictionary& motionDict,
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const fvMesh&,
|
|
||||||
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
List<extrudeMode>& extrudeStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Count global number of extruded faces
|
|
||||||
static label countExtrusion
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const List<extrudeMode>& extrudeStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Collect layer faces and layer cells into bools
|
|
||||||
// for ease of handling
|
|
||||||
static void getLayerCellsFaces
|
|
||||||
(
|
|
||||||
const polyMesh&,
|
|
||||||
const addPatchCellLayer&,
|
|
||||||
boolList&,
|
|
||||||
boolList&
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mesh shrinking (to create space for layers)
|
|
||||||
|
|
||||||
//- Average field (over all subset of mesh points) by
|
|
||||||
// summing contribution from edges. Global parallel since only
|
|
||||||
// does master edges for coupled edges.
|
|
||||||
template<class Type>
|
|
||||||
void averageNeighbours
|
|
||||||
(
|
|
||||||
const PackedList<1>& isMasterEdge,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
const labelList& meshPoints,
|
|
||||||
const edgeList& edges,
|
|
||||||
const scalarField& invSumWeight,
|
|
||||||
const Field<Type>& data,
|
|
||||||
Field<Type>& average
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculate inverse sum of edge weights (currently always 1.0)
|
|
||||||
void sumWeights
|
|
||||||
(
|
|
||||||
const PackedList<1>& isMasterEdge,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
const labelList& meshPoints,
|
|
||||||
const edgeList& edges,
|
|
||||||
scalarField& invSumWeight
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Smooth scalar field on patch
|
|
||||||
void smoothField
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const PackedList<1>& isMasterEdge,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
const scalarField& fieldMin,
|
|
||||||
const label& nSmoothDisp,
|
|
||||||
scalarField& field
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Smooth normals on patch.
|
|
||||||
void smoothPatchNormals
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const PackedList<1>& isMasterEdge,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
const label nSmoothDisp,
|
|
||||||
pointField& normals
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Smooth normals in interior.
|
|
||||||
void smoothNormals
|
|
||||||
(
|
|
||||||
const label nSmoothDisp,
|
|
||||||
const PackedList<1>& isMasterEdge,
|
|
||||||
const labelList& fixedPoints,
|
|
||||||
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
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const scalar minCos,
|
|
||||||
List<extrudeMode>& extrudeStatus,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers,
|
|
||||||
label& nPointCounter
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find isolated islands (points, edges and faces and
|
|
||||||
// layer terminations)
|
|
||||||
// in the layer mesh and stop any layer growth at these points.
|
|
||||||
void findIsolatedRegions
|
|
||||||
(
|
|
||||||
const indirectPrimitivePatch& pp,
|
|
||||||
const PackedList<1>& isMasterEdge,
|
|
||||||
const labelList& meshEdges,
|
|
||||||
const scalar minCosLayerTermination,
|
|
||||||
scalarField& field,
|
|
||||||
List<extrudeMode>& extrudeStatus,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers
|
|
||||||
) const;
|
|
||||||
|
|
||||||
// Calculate medial axis fields
|
|
||||||
void medialAxisSmoothingInfo
|
|
||||||
(
|
|
||||||
const motionSmoother& meshMover,
|
|
||||||
const label nSmoothNormals,
|
|
||||||
const label nSmoothSurfaceNormals,
|
|
||||||
const scalar minMedianAxisAngleCos,
|
|
||||||
|
|
||||||
pointVectorField& dispVec,
|
|
||||||
pointScalarField& medialRatio,
|
|
||||||
pointScalarField& medialDist
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Main routine to shrink mesh
|
|
||||||
void shrinkMeshMedialDistance
|
|
||||||
(
|
|
||||||
motionSmoother& meshMover,
|
|
||||||
const label nSmoothThickness,
|
|
||||||
const scalar maxThicknessToMedialRatio,
|
|
||||||
const label nAllowableErrors,
|
|
||||||
const label nSnap,
|
|
||||||
const scalar minCosLayerTermination,
|
|
||||||
|
|
||||||
const scalarField& layerThickness,
|
|
||||||
const scalarField& minThickness,
|
|
||||||
|
|
||||||
const pointVectorField& dispVec,
|
|
||||||
const pointScalarField& medialRatio,
|
|
||||||
const pointScalarField& medialDist,
|
|
||||||
|
|
||||||
List<extrudeMode>& extrudeStatus,
|
|
||||||
pointField& patchDisp,
|
|
||||||
labelList& patchNLayers
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
autoHexMeshDriver(const autoHexMeshDriver&);
|
autoHexMeshDriver(const autoHexMeshDriver&);
|
||||||
@ -646,16 +180,6 @@ public:
|
|||||||
const dictionary& decomposeDict
|
const dictionary& decomposeDict
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Alternative constructor from top-level controldictionary and
|
|
||||||
// refinement specific dictionary
|
|
||||||
autoHexMeshDriver
|
|
||||||
(
|
|
||||||
fvMesh& mesh,
|
|
||||||
const dictionary& controlDict,
|
|
||||||
const dictionary& refineDict,
|
|
||||||
const dictionary& decomposeDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
@ -677,6 +201,12 @@ public:
|
|||||||
return surfacesPtr_();
|
return surfacesPtr_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Surfaces to volume refinement on
|
||||||
|
const shellSurfaces& shells() const
|
||||||
|
{
|
||||||
|
return shellsPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
//- Per refinementsurface, per region the patch
|
//- Per refinementsurface, per region the patch
|
||||||
const labelList& globalToPatch() const
|
const labelList& globalToPatch() const
|
||||||
{
|
{
|
||||||
@ -684,153 +214,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Refinement
|
// Meshing
|
||||||
|
|
||||||
//- Refine around explicit feature edges
|
|
||||||
label featureEdgeRefine
|
|
||||||
(
|
|
||||||
const PtrList<dictionary>& featDicts,
|
|
||||||
const label maxIter,
|
|
||||||
const label minRefine
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Refine at surface intersections
|
|
||||||
label surfaceOnlyRefine(const label maxIter);
|
|
||||||
|
|
||||||
//- Remove cells not reachable from keep points
|
|
||||||
void removeInsideCells(const label nBufferLayers);
|
|
||||||
|
|
||||||
//- Refine volume regions (interior of shells)
|
|
||||||
label shellRefine(const label maxIter);
|
|
||||||
|
|
||||||
//- Introduce baffles; remove unreachable mesh parts
|
|
||||||
// handleSnapProblems : whether to remove free floating cells
|
|
||||||
void baffleAndSplitMesh(const bool handleSnapProblems);
|
|
||||||
|
|
||||||
//- Move cells to zones
|
|
||||||
void zonify();
|
|
||||||
|
|
||||||
//- Split and recombine baffles to get rid of single face baffles.
|
|
||||||
void splitAndMergeBaffles(const bool handleSnapProblems);
|
|
||||||
|
|
||||||
//- Merge multiple boundary faces on single cell
|
|
||||||
void mergePatchFaces();
|
|
||||||
|
|
||||||
//- Redecompose according to cell count
|
|
||||||
// keepZoneFaces : find all faceZones from zoned surfaces and keep
|
|
||||||
// owner and neighbour together
|
|
||||||
// keepBaffles : find all baffles and keep them together
|
|
||||||
autoPtr<mapDistributePolyMesh> balance
|
|
||||||
(
|
|
||||||
const bool keepZoneFaces,
|
|
||||||
const bool keepBaffles
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Write mesh
|
//- Write mesh
|
||||||
void writeMesh(const string&) const;
|
void writeMesh(const string&) const;
|
||||||
|
|
||||||
|
|
||||||
// Snapping
|
|
||||||
|
|
||||||
//- Create baffles for faces straddling zoned surfaces. Return
|
|
||||||
// baffles.
|
|
||||||
autoPtr<mapPolyMesh> createZoneBaffles(List<labelPair>&);
|
|
||||||
|
|
||||||
//- Merge baffles.
|
|
||||||
autoPtr<mapPolyMesh> mergeZoneBaffles(const List<labelPair>&);
|
|
||||||
|
|
||||||
//- Calculate edge length per patch point.
|
|
||||||
scalarField calcSnapDistance
|
|
||||||
(
|
|
||||||
const dictionary& snapDict,
|
|
||||||
const indirectPrimitivePatch&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Get patches generated for surfaces.
|
|
||||||
labelList getSurfacePatches() const;
|
|
||||||
|
|
||||||
//- Smooth the mesh (patch and internal) to increase visibility
|
|
||||||
// of surface points (on castellated mesh) w.r.t. surface.
|
|
||||||
void preSmoothPatch
|
|
||||||
(
|
|
||||||
const dictionary& snapDict,
|
|
||||||
const label nInitErrors,
|
|
||||||
const List<labelPair>& baffles,
|
|
||||||
motionSmoother&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Per patch point calculate point on nearest surface. Set as
|
|
||||||
// boundary conditions of motionSmoother displacement field. Return
|
|
||||||
// displacement of patch points.
|
|
||||||
vectorField calcNearestSurface
|
|
||||||
(
|
|
||||||
const scalarField& snapDist,
|
|
||||||
motionSmoother& meshMover
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Smooth the displacement field to the internal.
|
|
||||||
void smoothDisplacement
|
|
||||||
(
|
|
||||||
const dictionary& snapDict,
|
|
||||||
motionSmoother&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Do the hard work: move the mesh according to displacement,
|
|
||||||
// locally relax the displacement.
|
|
||||||
void scaleMesh
|
|
||||||
(
|
|
||||||
const dictionary& snapDict,
|
|
||||||
const label nInitErrors,
|
|
||||||
const List<labelPair>& baffles,
|
|
||||||
motionSmoother&
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Layers
|
|
||||||
|
|
||||||
//- Merge patch faces on same cell.
|
|
||||||
void mergePatchFacesUndo
|
|
||||||
(
|
|
||||||
const dictionary& shrinkDict,
|
|
||||||
const dictionary& motionDict
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Check that mesh outside is not multiply connected.
|
|
||||||
void checkMeshManifold() const;
|
|
||||||
|
|
||||||
//- Add cell layers
|
|
||||||
void addLayers
|
|
||||||
(
|
|
||||||
const dictionary& shrinkDict,
|
|
||||||
const dictionary& motionDict,
|
|
||||||
const label nAllowableErrors,
|
|
||||||
motionSmoother&
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Other
|
|
||||||
|
|
||||||
//- Do all refinement.
|
|
||||||
void doRefine
|
|
||||||
(
|
|
||||||
const dictionary& refineDict,
|
|
||||||
const bool prepareForSnapping
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Do all snapping.
|
|
||||||
void doSnap
|
|
||||||
(
|
|
||||||
const dictionary& snapDict,
|
|
||||||
const dictionary& motionDict
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Do alllayer addition.
|
|
||||||
void doLayers
|
|
||||||
(
|
|
||||||
const dictionary& shrinkDict,
|
|
||||||
const dictionary& motionDict
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Do all : refine, snap, layers
|
//- Do all : refine, snap, layers
|
||||||
void doMesh();
|
void doMesh();
|
||||||
};
|
};
|
||||||
@ -842,12 +230,6 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "autoHexMeshDriverTemplates.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
562
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
Normal file
562
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
Normal file
@ -0,0 +1,562 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::autoLayerDriver
|
||||||
|
|
||||||
|
Description
|
||||||
|
All to do with adding layers
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
autoLayerDriver.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef autoLayerDriver_H
|
||||||
|
#define autoLayerDriver_H
|
||||||
|
|
||||||
|
#include "meshRefinement.H"
|
||||||
|
#include "wallPoint.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class removePoints;
|
||||||
|
class pointSet;
|
||||||
|
class motionSmoother;
|
||||||
|
class addPatchCellLayer;
|
||||||
|
class pointData;
|
||||||
|
class wallPoint;
|
||||||
|
class faceSet;
|
||||||
|
class layerParameters;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class autoLayerDriver Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class autoLayerDriver
|
||||||
|
{
|
||||||
|
// Static data members
|
||||||
|
|
||||||
|
//- Extrusion controls
|
||||||
|
enum extrudeMode
|
||||||
|
{
|
||||||
|
NOEXTRUDE, /*!< Do not extrude. No layers added. */
|
||||||
|
EXTRUDE, /*!< Extrude */
|
||||||
|
EXTRUDEREMOVE /*!< Extrude but afterwards remove added */
|
||||||
|
/*!< faces locally */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Private classes
|
||||||
|
|
||||||
|
//- Combine operator class to combine normal with other normal.
|
||||||
|
class nomalsCombine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void operator()(vector& x, const vector& y) const
|
||||||
|
{
|
||||||
|
if (y != wallPoint::greatPoint)
|
||||||
|
{
|
||||||
|
if (x == wallPoint::greatPoint)
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x *= (x&y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Mesh+surface
|
||||||
|
meshRefinement& meshRefiner_;
|
||||||
|
|
||||||
|
//- From surface region to patch
|
||||||
|
const labelList globalToPatch_;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
|
||||||
|
// Face merging
|
||||||
|
|
||||||
|
//- Merge patch faces. Undo until no checkMesh errors.
|
||||||
|
label mergePatchFacesUndo
|
||||||
|
(
|
||||||
|
const scalar minCos,
|
||||||
|
const scalar concaveCos,
|
||||||
|
const dictionary&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Remove points.
|
||||||
|
autoPtr<mapPolyMesh> doRemovePoints
|
||||||
|
(
|
||||||
|
removePoints& pointRemover,
|
||||||
|
const boolList& pointCanBeDeleted
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Restore faces (which contain removed points)
|
||||||
|
autoPtr<mapPolyMesh> doRestorePoints
|
||||||
|
(
|
||||||
|
removePoints& pointRemover,
|
||||||
|
const labelList& facesToRestore
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Return candidateFaces that are also in set.
|
||||||
|
labelList collectFaces
|
||||||
|
(
|
||||||
|
const labelList& candidateFaces,
|
||||||
|
const labelHashSet& set
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Pick up faces of cells of faces in set.
|
||||||
|
labelList growFaceCellFace(const labelHashSet&) const;
|
||||||
|
|
||||||
|
//- Remove points not used by any face or points used by only
|
||||||
|
// two faces where the edges are in line
|
||||||
|
label mergeEdgesUndo(const scalar minCos, const dictionary&);
|
||||||
|
|
||||||
|
|
||||||
|
// Layers
|
||||||
|
|
||||||
|
//- For debugging: Dump displacement to .obj files
|
||||||
|
static void dumpDisplacement
|
||||||
|
(
|
||||||
|
const fileName&,
|
||||||
|
const indirectPrimitivePatch&,
|
||||||
|
const vectorField&,
|
||||||
|
const List<extrudeMode>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Check that primitivePatch is not multiply connected.
|
||||||
|
// Collect non-manifold points in pointSet.
|
||||||
|
static void checkManifold
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch&,
|
||||||
|
pointSet& nonManifoldPoints
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Check that mesh outside is not multiply connected.
|
||||||
|
void checkMeshManifold() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Static extrusion setup
|
||||||
|
|
||||||
|
//- Unset extrusion on point. Returns true if anything unset.
|
||||||
|
static bool unmarkExtrusion
|
||||||
|
(
|
||||||
|
const label patchPointI,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Unset extrusion on face. Returns true if anything unset.
|
||||||
|
static bool unmarkExtrusion
|
||||||
|
(
|
||||||
|
const face& localFace,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
//- No extrusion at non-manifold points.
|
||||||
|
void handleNonManifolds
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- No extrusion on feature edges. Assumes non-manifold
|
||||||
|
// edges already handled.
|
||||||
|
void handleFeatureAngle
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
const scalar minCos,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- No extrusion on warped faces
|
||||||
|
void handleWarpedFaces
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const scalar faceRatio,
|
||||||
|
const scalar edge0Len,
|
||||||
|
const labelList& cellLevel,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Determine the number of layers per point from the number of
|
||||||
|
// layers per surface.
|
||||||
|
void setNumLayers
|
||||||
|
(
|
||||||
|
const labelList& patchToNLayers,
|
||||||
|
const labelList& patchIDs,
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Grow no-extrusion layer.
|
||||||
|
static void growNoExtrusion
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate pointwise wanted and minimum thickness.
|
||||||
|
// thickness: wanted thickness
|
||||||
|
// minthickness: when to give up and not extrude
|
||||||
|
// Gets per patch parameters and determine pp pointwise
|
||||||
|
// parameters.
|
||||||
|
void calculateLayerThickness
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const labelList& patchIDs,
|
||||||
|
const scalarField& patchExpansionRatio,
|
||||||
|
const scalarField& patchFinalLayerRatio,
|
||||||
|
const scalarField& patchRelMinThickness,
|
||||||
|
const labelList& cellLevel,
|
||||||
|
const labelList& patchNLayers,
|
||||||
|
const scalar edge0Len,
|
||||||
|
|
||||||
|
scalarField& thickness,
|
||||||
|
scalarField& minThickness,
|
||||||
|
scalarField& expansionRatio
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Extrusion execution
|
||||||
|
|
||||||
|
//- Synchronize displacement among coupled patches.
|
||||||
|
void syncPatchDisplacement
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const scalarField& minThickness,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Get nearest point on surface to snap to
|
||||||
|
void getPatchDisplacement
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const scalarField& thickness,
|
||||||
|
const scalarField& minThickness,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Truncates displacement
|
||||||
|
// - for all patchFaces in the faceset displacement gets set
|
||||||
|
// to zero
|
||||||
|
// - all displacement < minThickness gets set to zero
|
||||||
|
label truncateDisplacement
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const scalarField& minThickness,
|
||||||
|
const faceSet& illegalPatchFaces,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Setup layer information (at points and faces) to
|
||||||
|
// modify mesh topology in
|
||||||
|
// regions where layer mesh terminates. Guarantees an
|
||||||
|
// optional slow decreasing of the number of layers.
|
||||||
|
// Returns the number of layers per face and per point
|
||||||
|
// to go into the actual layer addition engine.
|
||||||
|
void setupLayerInfoTruncation
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const labelList& patchNLayers,
|
||||||
|
const List<extrudeMode>& extrudeStatus,
|
||||||
|
const label nBufferCellsNoExtrude,
|
||||||
|
labelList& nPatchPointLayers,
|
||||||
|
labelList& nPatchFaceLayers
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Does any of the cells use a face from faces?
|
||||||
|
static bool cellsUseFace
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const labelList& cellLabels,
|
||||||
|
const labelHashSet& faces
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Checks the newly added cells and locally unmarks points
|
||||||
|
// so they will not get extruded next time round. Returns
|
||||||
|
// global number of unmarked points (0 if all was fine)
|
||||||
|
static label checkAndUnmark
|
||||||
|
(
|
||||||
|
const addPatchCellLayer& addLayer,
|
||||||
|
const dictionary& motionDict,
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const fvMesh&,
|
||||||
|
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Count global number of extruded faces
|
||||||
|
static label countExtrusion
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const List<extrudeMode>& extrudeStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Collect layer faces and layer cells into bools
|
||||||
|
// for ease of handling
|
||||||
|
static void getLayerCellsFaces
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const addPatchCellLayer&,
|
||||||
|
boolList&,
|
||||||
|
boolList&
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mesh shrinking (to create space for layers)
|
||||||
|
|
||||||
|
//- Average field (over all subset of mesh points) by
|
||||||
|
// summing contribution from edges. Global parallel since only
|
||||||
|
// does master edges for coupled edges.
|
||||||
|
template<class Type>
|
||||||
|
static void averageNeighbours
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const PackedList<1>& isMasterEdge,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
const labelList& meshPoints,
|
||||||
|
const edgeList& edges,
|
||||||
|
const scalarField& invSumWeight,
|
||||||
|
const Field<Type>& data,
|
||||||
|
Field<Type>& average
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate inverse sum of edge weights (currently always 1.0)
|
||||||
|
void sumWeights
|
||||||
|
(
|
||||||
|
const PackedList<1>& isMasterEdge,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
const labelList& meshPoints,
|
||||||
|
const edgeList& edges,
|
||||||
|
scalarField& invSumWeight
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Smooth scalar field on patch
|
||||||
|
void smoothField
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const PackedList<1>& isMasterEdge,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
const scalarField& fieldMin,
|
||||||
|
const label& nSmoothDisp,
|
||||||
|
scalarField& field
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Smooth normals on patch.
|
||||||
|
void smoothPatchNormals
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const PackedList<1>& isMasterEdge,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
const label nSmoothDisp,
|
||||||
|
pointField& normals
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Smooth normals in interior.
|
||||||
|
void smoothNormals
|
||||||
|
(
|
||||||
|
const label nSmoothDisp,
|
||||||
|
const PackedList<1>& isMasterEdge,
|
||||||
|
const labelList& fixedPoints,
|
||||||
|
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
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const scalar minCos,
|
||||||
|
List<extrudeMode>& extrudeStatus,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
label& nPointCounter
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Find isolated islands (points, edges and faces and
|
||||||
|
// layer terminations)
|
||||||
|
// in the layer mesh and stop any layer growth at these points.
|
||||||
|
void findIsolatedRegions
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const PackedList<1>& isMasterEdge,
|
||||||
|
const labelList& meshEdges,
|
||||||
|
const scalar minCosLayerTermination,
|
||||||
|
scalarField& field,
|
||||||
|
List<extrudeMode>& extrudeStatus,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Calculate medial axis fields
|
||||||
|
void medialAxisSmoothingInfo
|
||||||
|
(
|
||||||
|
const motionSmoother& meshMover,
|
||||||
|
const label nSmoothNormals,
|
||||||
|
const label nSmoothSurfaceNormals,
|
||||||
|
const scalar minMedianAxisAngleCos,
|
||||||
|
|
||||||
|
pointVectorField& dispVec,
|
||||||
|
pointScalarField& medialRatio,
|
||||||
|
pointScalarField& medialDist
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Main routine to shrink mesh
|
||||||
|
void shrinkMeshMedialDistance
|
||||||
|
(
|
||||||
|
motionSmoother& meshMover,
|
||||||
|
const label nSmoothThickness,
|
||||||
|
const scalar maxThicknessToMedialRatio,
|
||||||
|
const label nAllowableErrors,
|
||||||
|
const label nSnap,
|
||||||
|
const scalar minCosLayerTermination,
|
||||||
|
|
||||||
|
const scalarField& layerThickness,
|
||||||
|
const scalarField& minThickness,
|
||||||
|
|
||||||
|
const pointVectorField& dispVec,
|
||||||
|
const pointScalarField& medialRatio,
|
||||||
|
const pointScalarField& medialDist,
|
||||||
|
|
||||||
|
List<extrudeMode>& extrudeStatus,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
autoLayerDriver(const autoLayerDriver&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const autoLayerDriver&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
ClassName("autoLayerDriver");
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
autoLayerDriver
|
||||||
|
(
|
||||||
|
meshRefinement& meshRefiner,
|
||||||
|
const labelList& globalToPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Merge patch faces on same cell.
|
||||||
|
void mergePatchFacesUndo
|
||||||
|
(
|
||||||
|
const layerParameters& layerParams,
|
||||||
|
const dictionary& motionDict
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Add cell layers
|
||||||
|
void addLayers
|
||||||
|
(
|
||||||
|
const layerParameters& layerParams,
|
||||||
|
const dictionary& motionDict,
|
||||||
|
const label nAllowableErrors,
|
||||||
|
motionSmoother& meshMover,
|
||||||
|
decompositionMethod& decomposer,
|
||||||
|
fvMeshDistribute& distributor
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Add layers according to the dictionary settings
|
||||||
|
void doLayers
|
||||||
|
(
|
||||||
|
const dictionary& shrinkDict,
|
||||||
|
const dictionary& motionDict,
|
||||||
|
const layerParameters& layerParams,
|
||||||
|
decompositionMethod& decomposer,
|
||||||
|
fvMeshDistribute& distributor
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
# include "autoLayerDriverTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -27,7 +27,7 @@ Description
|
|||||||
|
|
||||||
\*----------------------------------------------------------------------------*/
|
\*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "autoHexMeshDriver.H"
|
#include "autoLayerDriver.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "pointFields.H"
|
#include "pointFields.H"
|
||||||
@ -41,7 +41,7 @@ Description
|
|||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
// Calculate inverse sum of edge weights (currently always 1.0)
|
// Calculate inverse sum of edge weights (currently always 1.0)
|
||||||
void Foam::autoHexMeshDriver::sumWeights
|
void Foam::autoLayerDriver::sumWeights
|
||||||
(
|
(
|
||||||
const PackedList<1>& isMasterEdge,
|
const PackedList<1>& isMasterEdge,
|
||||||
const labelList& meshEdges,
|
const labelList& meshEdges,
|
||||||
@ -67,7 +67,7 @@ void Foam::autoHexMeshDriver::sumWeights
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
meshRefiner_.mesh(),
|
||||||
meshPoints,
|
meshPoints,
|
||||||
invSumWeight,
|
invSumWeight,
|
||||||
plusEqOp<scalar>(),
|
plusEqOp<scalar>(),
|
||||||
@ -88,7 +88,7 @@ void Foam::autoHexMeshDriver::sumWeights
|
|||||||
|
|
||||||
|
|
||||||
// Smooth field on moving patch
|
// Smooth field on moving patch
|
||||||
void Foam::autoHexMeshDriver::smoothField
|
void Foam::autoLayerDriver::smoothField
|
||||||
(
|
(
|
||||||
const motionSmoother& meshMover,
|
const motionSmoother& meshMover,
|
||||||
const PackedList<1>& isMasterEdge,
|
const PackedList<1>& isMasterEdge,
|
||||||
@ -120,6 +120,7 @@ void Foam::autoHexMeshDriver::smoothField
|
|||||||
scalarField average(pp.nPoints());
|
scalarField average(pp.nPoints());
|
||||||
averageNeighbours
|
averageNeighbours
|
||||||
(
|
(
|
||||||
|
meshMover.mesh(),
|
||||||
isMasterEdge,
|
isMasterEdge,
|
||||||
meshEdges,
|
meshEdges,
|
||||||
meshPoints,
|
meshPoints,
|
||||||
@ -159,7 +160,7 @@ void Foam::autoHexMeshDriver::smoothField
|
|||||||
|
|
||||||
|
|
||||||
// Smooth normals on moving patch.
|
// Smooth normals on moving patch.
|
||||||
void Foam::autoHexMeshDriver::smoothPatchNormals
|
void Foam::autoLayerDriver::smoothPatchNormals
|
||||||
(
|
(
|
||||||
const motionSmoother& meshMover,
|
const motionSmoother& meshMover,
|
||||||
const PackedList<1>& isMasterEdge,
|
const PackedList<1>& isMasterEdge,
|
||||||
@ -192,6 +193,7 @@ void Foam::autoHexMeshDriver::smoothPatchNormals
|
|||||||
vectorField average(pp.nPoints());
|
vectorField average(pp.nPoints());
|
||||||
averageNeighbours
|
averageNeighbours
|
||||||
(
|
(
|
||||||
|
meshMover.mesh(),
|
||||||
isMasterEdge,
|
isMasterEdge,
|
||||||
meshEdges,
|
meshEdges,
|
||||||
meshPoints,
|
meshPoints,
|
||||||
@ -223,7 +225,7 @@ void Foam::autoHexMeshDriver::smoothPatchNormals
|
|||||||
|
|
||||||
|
|
||||||
// Smooth normals in interior.
|
// Smooth normals in interior.
|
||||||
void Foam::autoHexMeshDriver::smoothNormals
|
void Foam::autoLayerDriver::smoothNormals
|
||||||
(
|
(
|
||||||
const label nSmoothDisp,
|
const label nSmoothDisp,
|
||||||
const PackedList<1>& isMasterEdge,
|
const PackedList<1>& isMasterEdge,
|
||||||
@ -234,10 +236,11 @@ void Foam::autoHexMeshDriver::smoothNormals
|
|||||||
// Get smoothly varying internal normals field.
|
// Get smoothly varying internal normals field.
|
||||||
Info<< "shrinkMeshDistance : Smoothing normals ..." << endl;
|
Info<< "shrinkMeshDistance : Smoothing normals ..." << endl;
|
||||||
|
|
||||||
const edgeList& edges = mesh_.edges();
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
const edgeList& edges = mesh.edges();
|
||||||
|
|
||||||
// Points that do not change.
|
// Points that do not change.
|
||||||
PackedList<1> isFixedPoint(mesh_.nPoints(), 0);
|
PackedList<1> isFixedPoint(mesh.nPoints(), 0);
|
||||||
|
|
||||||
// Internal points that are fixed
|
// Internal points that are fixed
|
||||||
forAll(fixedPoints, i)
|
forAll(fixedPoints, i)
|
||||||
@ -247,12 +250,12 @@ void Foam::autoHexMeshDriver::smoothNormals
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Correspondence between local edges/points and mesh edges/points
|
// Correspondence between local edges/points and mesh edges/points
|
||||||
const labelList meshEdges(identity(mesh_.nEdges()));
|
const labelList meshEdges(identity(mesh.nEdges()));
|
||||||
const labelList meshPoints(identity(mesh_.nPoints()));
|
const labelList meshPoints(identity(mesh.nPoints()));
|
||||||
|
|
||||||
// Calculate inverse sum of weights
|
// Calculate inverse sum of weights
|
||||||
|
|
||||||
scalarField invSumWeight(mesh_.nPoints(), 0);
|
scalarField invSumWeight(mesh.nPoints(), 0);
|
||||||
sumWeights
|
sumWeights
|
||||||
(
|
(
|
||||||
isMasterEdge,
|
isMasterEdge,
|
||||||
@ -266,9 +269,10 @@ void Foam::autoHexMeshDriver::smoothNormals
|
|||||||
|
|
||||||
for (label iter = 0; iter < nSmoothDisp; iter++)
|
for (label iter = 0; iter < nSmoothDisp; iter++)
|
||||||
{
|
{
|
||||||
vectorField average(mesh_.nPoints());
|
vectorField average(mesh.nPoints());
|
||||||
averageNeighbours
|
averageNeighbours
|
||||||
(
|
(
|
||||||
|
mesh,
|
||||||
isMasterEdge,
|
isMasterEdge,
|
||||||
meshEdges,
|
meshEdges,
|
||||||
meshPoints,
|
meshPoints,
|
||||||
@ -305,18 +309,19 @@ void Foam::autoHexMeshDriver::smoothNormals
|
|||||||
|
|
||||||
// Tries and find a medial axis point. Done by comparing vectors to nearest
|
// Tries and find a medial axis point. Done by comparing vectors to nearest
|
||||||
// wall point for both vertices of edge.
|
// wall point for both vertices of edge.
|
||||||
bool Foam::autoHexMeshDriver::isMaxEdge
|
bool Foam::autoLayerDriver::isMaxEdge
|
||||||
(
|
(
|
||||||
const List<pointData>& pointWallDist,
|
const List<pointData>& pointWallDist,
|
||||||
const label edgeI,
|
const label edgeI,
|
||||||
const scalar minCos
|
const scalar minCos
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const pointField& points = mesh_.points();
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
const pointField& points = mesh.points();
|
||||||
|
|
||||||
// Do not mark edges with one side on moving wall.
|
// Do not mark edges with one side on moving wall.
|
||||||
|
|
||||||
const edge& e = mesh_.edges()[edgeI];
|
const edge& e = mesh.edges()[edgeI];
|
||||||
|
|
||||||
vector v0(points[e[0]] - pointWallDist[e[0]].origin());
|
vector v0(points[e[0]] - pointWallDist[e[0]].origin());
|
||||||
scalar magV0(mag(v0));
|
scalar magV0(mag(v0));
|
||||||
@ -351,7 +356,7 @@ bool Foam::autoHexMeshDriver::isMaxEdge
|
|||||||
|
|
||||||
// Stop layer growth where mesh wraps around edge with a
|
// Stop layer growth where mesh wraps around edge with a
|
||||||
// large feature angle
|
// large feature angle
|
||||||
void Foam::autoHexMeshDriver::handleFeatureAngleLayerTerminations
|
void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
|
||||||
(
|
(
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const scalar minCos,
|
const scalar minCos,
|
||||||
@ -444,7 +449,7 @@ void Foam::autoHexMeshDriver::handleFeatureAngleLayerTerminations
|
|||||||
|
|
||||||
// Find isolated islands (points, edges and faces and layer terminations)
|
// Find isolated islands (points, edges and faces and layer terminations)
|
||||||
// in the layer mesh and stop any layer growth at these points.
|
// in the layer mesh and stop any layer growth at these points.
|
||||||
void Foam::autoHexMeshDriver::findIsolatedRegions
|
void Foam::autoLayerDriver::findIsolatedRegions
|
||||||
(
|
(
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const PackedList<1>& isMasterEdge,
|
const PackedList<1>& isMasterEdge,
|
||||||
@ -456,6 +461,8 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
|
|||||||
labelList& patchNLayers
|
labelList& patchNLayers
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
Info<< "shrinkMeshDistance : Removing isolated regions ..." << endl;
|
Info<< "shrinkMeshDistance : Removing isolated regions ..." << endl;
|
||||||
|
|
||||||
// Keep count of number of points unextruded
|
// Keep count of number of points unextruded
|
||||||
@ -514,7 +521,7 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
pp.meshPoints(),
|
pp.meshPoints(),
|
||||||
keptPoints,
|
keptPoints,
|
||||||
orEqOp<bool>(),
|
orEqOp<bool>(),
|
||||||
@ -582,7 +589,7 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
pp.meshPoints(),
|
pp.meshPoints(),
|
||||||
isolatedPoint,
|
isolatedPoint,
|
||||||
plusEqOp<label>(),
|
plusEqOp<label>(),
|
||||||
@ -650,7 +657,7 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
|
|||||||
// medialDist : distance to medial axis
|
// medialDist : distance to medial axis
|
||||||
// medialRatio : ratio of medial distance to wall distance.
|
// medialRatio : ratio of medial distance to wall distance.
|
||||||
// (1 at wall, 0 at medial axis)
|
// (1 at wall, 0 at medial axis)
|
||||||
void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
void Foam::autoLayerDriver::medialAxisSmoothingInfo
|
||||||
(
|
(
|
||||||
const motionSmoother& meshMover,
|
const motionSmoother& meshMover,
|
||||||
const label nSmoothNormals,
|
const label nSmoothNormals,
|
||||||
@ -666,7 +673,8 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
Info<< "medialAxisSmoothingInfo :"
|
Info<< "medialAxisSmoothingInfo :"
|
||||||
<< " Calculate distance to Medial Axis ..." << endl;
|
<< " Calculate distance to Medial Axis ..." << endl;
|
||||||
|
|
||||||
const pointField& points = mesh_.points();
|
const polyMesh& mesh = meshMover.mesh();
|
||||||
|
const pointField& points = mesh.points();
|
||||||
const pointMesh& pMesh = meshMover.pMesh();
|
const pointMesh& pMesh = meshMover.pMesh();
|
||||||
|
|
||||||
const indirectPrimitivePatch& pp = meshMover.patch();
|
const indirectPrimitivePatch& pp = meshMover.patch();
|
||||||
@ -677,7 +685,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Precalulate master edge (only relevant for shared edges)
|
// Precalulate master edge (only relevant for shared edges)
|
||||||
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh_));
|
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh));
|
||||||
// Precalculate meshEdge per pp edge
|
// Precalculate meshEdge per pp edge
|
||||||
labelList meshEdges(pp.nEdges());
|
labelList meshEdges(pp.nEdges());
|
||||||
|
|
||||||
@ -689,8 +697,8 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
label v1 = pp.meshPoints()[e[1]];
|
label v1 = pp.meshPoints()[e[1]];
|
||||||
meshEdges[patchEdgeI] = meshTools::findEdge
|
meshEdges[patchEdgeI] = meshTools::findEdge
|
||||||
(
|
(
|
||||||
mesh_.edges(),
|
mesh.edges(),
|
||||||
mesh_.pointEdges()[v0],
|
mesh.pointEdges()[v0],
|
||||||
v0,
|
v0,
|
||||||
v1
|
v1
|
||||||
);
|
);
|
||||||
@ -717,7 +725,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
meshPoints,
|
meshPoints,
|
||||||
pointNormals,
|
pointNormals,
|
||||||
plusEqOp<vector>(),
|
plusEqOp<vector>(),
|
||||||
@ -727,7 +735,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
meshPoints,
|
meshPoints,
|
||||||
nPointFaces,
|
nPointFaces,
|
||||||
plusEqOp<label>(),
|
plusEqOp<label>(),
|
||||||
@ -756,7 +764,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Distance to wall
|
// Distance to wall
|
||||||
List<pointData> pointWallDist(mesh_.nPoints());
|
List<pointData> pointWallDist(mesh.nPoints());
|
||||||
|
|
||||||
|
|
||||||
// 1. Calculate distance to points where displacement is specified.
|
// 1. Calculate distance to points where displacement is specified.
|
||||||
@ -777,7 +785,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do all calculations
|
// Do all calculations
|
||||||
List<pointData> edgeWallDist(mesh_.nEdges());
|
List<pointData> edgeWallDist(mesh.nEdges());
|
||||||
PointEdgeWave<pointData> wallDistCalc
|
PointEdgeWave<pointData> wallDistCalc
|
||||||
(
|
(
|
||||||
pMesh,
|
pMesh,
|
||||||
@ -785,15 +793,15 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
wallInfo,
|
wallInfo,
|
||||||
pointWallDist,
|
pointWallDist,
|
||||||
edgeWallDist,
|
edgeWallDist,
|
||||||
mesh_.nPoints() // max iterations
|
mesh.nPoints() // max iterations
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Find points with max distance and transport information back to
|
// 2. Find points with max distance and transport information back to
|
||||||
// wall.
|
// wall.
|
||||||
{
|
{
|
||||||
List<pointData> pointMedialDist(mesh_.nPoints());
|
List<pointData> pointMedialDist(mesh.nPoints());
|
||||||
List<pointData> edgeMedialDist(mesh_.nEdges());
|
List<pointData> edgeMedialDist(mesh.nEdges());
|
||||||
|
|
||||||
// Seed point data.
|
// Seed point data.
|
||||||
DynamicList<pointData> maxInfo(meshPoints.size());
|
DynamicList<pointData> maxInfo(meshPoints.size());
|
||||||
@ -801,7 +809,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
|
|
||||||
// 1. Medial axis points
|
// 1. Medial axis points
|
||||||
|
|
||||||
const edgeList& edges = mesh_.edges();
|
const edgeList& edges = mesh.edges();
|
||||||
|
|
||||||
forAll(edges, edgeI)
|
forAll(edges, edgeI)
|
||||||
{
|
{
|
||||||
@ -836,7 +844,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
|
|
||||||
|
|
||||||
// 2. Seed non-adapt patches
|
// 2. Seed non-adapt patches
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
labelHashSet adaptPatches(meshMover.adaptPatchIDs());
|
labelHashSet adaptPatches(meshMover.adaptPatchIDs());
|
||||||
|
|
||||||
@ -890,7 +898,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
|
|
||||||
pointMedialDist,
|
pointMedialDist,
|
||||||
edgeMedialDist,
|
edgeMedialDist,
|
||||||
mesh_.nPoints() // max iterations
|
mesh.nPoints() // max iterations
|
||||||
);
|
);
|
||||||
|
|
||||||
// Extract medial axis distance as pointScalarField
|
// Extract medial axis distance as pointScalarField
|
||||||
@ -925,7 +933,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_)
|
if (debug)
|
||||||
{
|
{
|
||||||
Info<< "medialAxisSmoothingInfo :"
|
Info<< "medialAxisSmoothingInfo :"
|
||||||
<< " Writing:" << nl
|
<< " Writing:" << nl
|
||||||
@ -943,7 +951,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::autoHexMeshDriver::shrinkMeshMedialDistance
|
void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
||||||
(
|
(
|
||||||
motionSmoother& meshMover,
|
motionSmoother& meshMover,
|
||||||
const label nSmoothThickness,
|
const label nSmoothThickness,
|
||||||
@ -973,7 +981,7 @@ void Foam::autoHexMeshDriver::shrinkMeshMedialDistance
|
|||||||
const labelList& meshPoints = pp.meshPoints();
|
const labelList& meshPoints = pp.meshPoints();
|
||||||
|
|
||||||
// Precalulate master edge (only relevant for shared edges)
|
// Precalulate master edge (only relevant for shared edges)
|
||||||
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh_));
|
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh));
|
||||||
// Precalculate meshEdge per pp edge
|
// Precalculate meshEdge per pp edge
|
||||||
labelList meshEdges(pp.nEdges());
|
labelList meshEdges(pp.nEdges());
|
||||||
|
|
||||||
@ -985,8 +993,8 @@ void Foam::autoHexMeshDriver::shrinkMeshMedialDistance
|
|||||||
label v1 = pp.meshPoints()[e[1]];
|
label v1 = pp.meshPoints()[e[1]];
|
||||||
meshEdges[patchEdgeI] = meshTools::findEdge
|
meshEdges[patchEdgeI] = meshTools::findEdge
|
||||||
(
|
(
|
||||||
mesh_.edges(),
|
mesh.edges(),
|
||||||
mesh_.pointEdges()[v0],
|
mesh.pointEdges()[v0],
|
||||||
v0,
|
v0,
|
||||||
v1
|
v1
|
||||||
);
|
);
|
||||||
@ -24,14 +24,15 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "autoHexMeshDriver.H"
|
#include "autoLayerDriver.H"
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::autoHexMeshDriver::averageNeighbours
|
void Foam::autoLayerDriver::averageNeighbours
|
||||||
(
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
const PackedList<1>& isMasterEdge,
|
const PackedList<1>& isMasterEdge,
|
||||||
const labelList& meshEdges,
|
const labelList& meshEdges,
|
||||||
const labelList& meshPoints,
|
const labelList& meshPoints,
|
||||||
@ -39,7 +40,7 @@ void Foam::autoHexMeshDriver::averageNeighbours
|
|||||||
const scalarField& invSumWeight,
|
const scalarField& invSumWeight,
|
||||||
const Field<Type>& data,
|
const Field<Type>& data,
|
||||||
Field<Type>& average
|
Field<Type>& average
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
average = pTraits<Type>::zero;
|
average = pTraits<Type>::zero;
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ void Foam::autoHexMeshDriver::averageNeighbours
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
meshPoints,
|
meshPoints,
|
||||||
average,
|
average,
|
||||||
plusEqOp<Type>(),
|
plusEqOp<Type>(),
|
||||||
776
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
Normal file
776
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
Normal file
@ -0,0 +1,776 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "autoRefineDriver.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "boundBox.H"
|
||||||
|
#include "mapDistributePolyMesh.H"
|
||||||
|
#include "cellSet.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
#include "refinementParameters.H"
|
||||||
|
#include "featureEdgeMesh.H"
|
||||||
|
#include "refinementSurfaces.H"
|
||||||
|
#include "shellSurfaces.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(autoRefineDriver, 0);
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Read explicit feature edges
|
||||||
|
Foam::label Foam::autoRefineDriver::readFeatureEdges
|
||||||
|
(
|
||||||
|
const PtrList<dictionary>& featDicts,
|
||||||
|
PtrList<featureEdgeMesh>& featureMeshes,
|
||||||
|
labelList& featureLevels
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
Info<< "Reading external feature lines." << endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
featureMeshes.setSize(featDicts.size());
|
||||||
|
featureLevels.setSize(featDicts.size());
|
||||||
|
|
||||||
|
forAll(featDicts, i)
|
||||||
|
{
|
||||||
|
const dictionary& dict = featDicts[i];
|
||||||
|
|
||||||
|
fileName featFileName(dict.lookup("file"));
|
||||||
|
|
||||||
|
featureMeshes.set
|
||||||
|
(
|
||||||
|
i,
|
||||||
|
new featureEdgeMesh
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
featFileName, // name
|
||||||
|
mesh.time().constant(), // directory
|
||||||
|
"triSurface", // instance
|
||||||
|
mesh.db(), // registry
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
featureMeshes[i].mergePoints(meshRefiner_.mergeDistance());
|
||||||
|
featureLevels[i] = readLabel(dict.lookup("level"));
|
||||||
|
|
||||||
|
Info<< "Refinement level " << featureLevels[i]
|
||||||
|
<< " for all cells crossed by feature " << featFileName
|
||||||
|
<< " (" << featureMeshes[i].points().size() << " points, "
|
||||||
|
<< featureMeshes[i].edges().size() << ")." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Read feature lines in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||||
|
|
||||||
|
return featureMeshes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Construct from components
|
||||||
|
Foam::autoRefineDriver::autoRefineDriver
|
||||||
|
(
|
||||||
|
meshRefinement& meshRefiner,
|
||||||
|
decompositionMethod& decomposer,
|
||||||
|
fvMeshDistribute& distributor,
|
||||||
|
const labelList& globalToPatch
|
||||||
|
)
|
||||||
|
:
|
||||||
|
meshRefiner_(meshRefiner),
|
||||||
|
decomposer_(decomposer),
|
||||||
|
distributor_(distributor),
|
||||||
|
globalToPatch_(globalToPatch)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::autoRefineDriver::featureEdgeRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const PtrList<dictionary>& featDicts,
|
||||||
|
const label maxIter,
|
||||||
|
const label minRefine
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
// Read explicit feature edges
|
||||||
|
PtrList<featureEdgeMesh> featureMeshes;
|
||||||
|
// Per feature the refinement level
|
||||||
|
labelList featureLevels;
|
||||||
|
readFeatureEdges(featDicts, featureMeshes, featureLevels);
|
||||||
|
|
||||||
|
|
||||||
|
label iter = 0;
|
||||||
|
|
||||||
|
if (featureMeshes.size() > 0 && maxIter > 0)
|
||||||
|
{
|
||||||
|
for (; iter < maxIter; iter++)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Feature refinement iteration " << iter << nl
|
||||||
|
<< "------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
labelList candidateCells
|
||||||
|
(
|
||||||
|
meshRefiner_.refineCandidates
|
||||||
|
(
|
||||||
|
refineParams.keepPoints()[0], // For now only use one.
|
||||||
|
refineParams.curvature(),
|
||||||
|
|
||||||
|
featureMeshes,
|
||||||
|
featureLevels,
|
||||||
|
|
||||||
|
true, // featureRefinement
|
||||||
|
false, // internalRefinement
|
||||||
|
false, // surfaceRefinement
|
||||||
|
false, // curvatureRefinement
|
||||||
|
refineParams.maxGlobalCells(),
|
||||||
|
refineParams.maxLocalCells()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
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 feature refinement : " << nCellsToRefine
|
||||||
|
<< " cells (out of " << mesh.globalData().nTotalCells()
|
||||||
|
<< ')' << endl;
|
||||||
|
|
||||||
|
if (nCellsToRefine <= minRefine)
|
||||||
|
{
|
||||||
|
Info<< "Stopping refining since too few cells selected."
|
||||||
|
<< nl << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug > 0)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.refineAndBalance
|
||||||
|
(
|
||||||
|
"feature refinement iteration " + name(iter),
|
||||||
|
decomposer_,
|
||||||
|
distributor_,
|
||||||
|
cellsToRefine
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label maxIter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
// Determine the maximum refinement level over all surfaces. This
|
||||||
|
// determines the minumum number of surface refinement iterations.
|
||||||
|
label overallMaxLevel = max(meshRefiner_.surfaces().maxLevel());
|
||||||
|
|
||||||
|
label iter;
|
||||||
|
for (iter = 0; iter < maxIter; iter++)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Surface refinement iteration " << iter << nl
|
||||||
|
<< "------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Determine cells to refine
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Only look at surface intersections (minLevel and surface curvature),
|
||||||
|
// do not do internal refinement (refinementShells)
|
||||||
|
|
||||||
|
labelList candidateCells
|
||||||
|
(
|
||||||
|
meshRefiner_.refineCandidates
|
||||||
|
(
|
||||||
|
refineParams.keepPoints()[0],
|
||||||
|
refineParams.curvature(),
|
||||||
|
|
||||||
|
PtrList<featureEdgeMesh>(0), // dummy featureMeshes;
|
||||||
|
labelList(0), // dummy featureLevels;
|
||||||
|
|
||||||
|
false, // featureRefinement
|
||||||
|
false, // internalRefinement
|
||||||
|
true, // surfaceRefinement
|
||||||
|
true, // curvatureRefinement
|
||||||
|
refineParams.maxGlobalCells(),
|
||||||
|
refineParams.maxLocalCells()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
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 or have done minimum nessecary
|
||||||
|
// iterations and not enough cells to refine.
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nCellsToRefine == 0
|
||||||
|
|| (
|
||||||
|
iter >= overallMaxLevel
|
||||||
|
&& nCellsToRefine <= refineParams.minRefineCells()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Stopping refining since too few cells selected."
|
||||||
|
<< nl << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.refineAndBalance
|
||||||
|
(
|
||||||
|
"surface refinement iteration " + name(iter),
|
||||||
|
decomposer_,
|
||||||
|
distributor_,
|
||||||
|
cellsToRefine
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoRefineDriver::removeInsideCells
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label nBufferLayers
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Removing mesh beyond surface intersections" << nl
|
||||||
|
<< "------------------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.splitMesh
|
||||||
|
(
|
||||||
|
nBufferLayers, // nBufferLayers
|
||||||
|
globalToPatch_,
|
||||||
|
refineParams.keepPoints()[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "Writing subsetted mesh to time "
|
||||||
|
<< mesh.time().timeName() << '.' << endl;
|
||||||
|
meshRefiner_.write(debug, mesh.time().path()/mesh.time().timeName());
|
||||||
|
Pout<< "Dumped mesh in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::autoRefineDriver::shellRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label maxIter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
// Mark current boundary faces with 0. Have meshRefiner maintain them.
|
||||||
|
meshRefiner_.userFaceData().setSize(1);
|
||||||
|
|
||||||
|
// mark list to remove any refined faces
|
||||||
|
meshRefiner_.userFaceData()[0].first() = meshRefinement::REMOVE;
|
||||||
|
meshRefiner_.userFaceData()[0].second() = createWithValues<labelList>
|
||||||
|
(
|
||||||
|
mesh.nFaces(),
|
||||||
|
-1,
|
||||||
|
meshRefiner_.intersectedFaces(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Determine the maximum refinement level over all volume refinement
|
||||||
|
// regions. This determines the minumum number of shell refinement
|
||||||
|
// iterations.
|
||||||
|
label overallMaxShellLevel = meshRefiner_.shells().maxLevel();
|
||||||
|
|
||||||
|
label iter;
|
||||||
|
for (iter = 0; iter < maxIter; iter++)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Shell refinement iteration " << iter << nl
|
||||||
|
<< "----------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
labelList candidateCells
|
||||||
|
(
|
||||||
|
meshRefiner_.refineCandidates
|
||||||
|
(
|
||||||
|
refineParams.keepPoints()[0],
|
||||||
|
refineParams.curvature(),
|
||||||
|
|
||||||
|
PtrList<featureEdgeMesh>(0), // dummy featureMeshes;
|
||||||
|
labelList(0), // dummy featureLevels;
|
||||||
|
|
||||||
|
false, // featureRefinement
|
||||||
|
true, // internalRefinement
|
||||||
|
false, // surfaceRefinement
|
||||||
|
false, // curvatureRefinement
|
||||||
|
refineParams.maxGlobalCells(),
|
||||||
|
refineParams.maxLocalCells()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "Dumping " << candidateCells.size()
|
||||||
|
<< " cells to cellSet candidateCellsFromShells." << endl;
|
||||||
|
|
||||||
|
cellSet(mesh, "candidateCellsFromShells", candidateCells).write();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Problem choosing starting faces for bufferlayers (bFaces)
|
||||||
|
// - we can't use the current intersected boundary faces
|
||||||
|
// (intersectedFaces) since this grows indefinitely
|
||||||
|
// - if we use 0 faces we don't satisfy bufferLayers from the
|
||||||
|
// surface.
|
||||||
|
// - possibly we want to have bFaces only the initial set of faces
|
||||||
|
// and maintain the list while doing the refinement.
|
||||||
|
labelList bFaces
|
||||||
|
(
|
||||||
|
findIndices(meshRefiner_.userFaceData()[0].second(), 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
//Info<< "Collected boundary faces : "
|
||||||
|
// << returnReduce(bFaces.size(), sumOp<label>()) << endl;
|
||||||
|
|
||||||
|
labelList cellsToRefine;
|
||||||
|
|
||||||
|
if (refineParams.nBufferLayers() <= 2)
|
||||||
|
{
|
||||||
|
cellsToRefine = meshRefiner_.meshCutter().consistentSlowRefinement
|
||||||
|
(
|
||||||
|
refineParams.nBufferLayers(),
|
||||||
|
candidateCells, // cells to refine
|
||||||
|
bFaces, // faces for nBufferLayers
|
||||||
|
1, // point difference
|
||||||
|
meshRefiner_.intersectedPoints() // points to check
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cellsToRefine = meshRefiner_.meshCutter().consistentSlowRefinement2
|
||||||
|
(
|
||||||
|
refineParams.nBufferLayers(),
|
||||||
|
candidateCells, // cells to refine
|
||||||
|
bFaces // faces for nBufferLayers
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Determined cells to refine in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s" << endl;
|
||||||
|
|
||||||
|
|
||||||
|
label nCellsToRefine = cellsToRefine.size();
|
||||||
|
reduce(nCellsToRefine, sumOp<label>());
|
||||||
|
|
||||||
|
Info<< "Selected for internal refinement : " << nCellsToRefine
|
||||||
|
<< " cells (out of " << mesh.globalData().nTotalCells()
|
||||||
|
<< ')' << endl;
|
||||||
|
|
||||||
|
// Stop when no cells to refine or have done minimum nessecary
|
||||||
|
// iterations and not enough cells to refine.
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nCellsToRefine == 0
|
||||||
|
|| (
|
||||||
|
iter >= overallMaxShellLevel
|
||||||
|
&& nCellsToRefine <= refineParams.minRefineCells()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Stopping refining since too few cells selected."
|
||||||
|
<< nl << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.refineAndBalance
|
||||||
|
(
|
||||||
|
"shell refinement iteration " + name(iter),
|
||||||
|
decomposer_,
|
||||||
|
distributor_,
|
||||||
|
cellsToRefine
|
||||||
|
);
|
||||||
|
}
|
||||||
|
meshRefiner_.userFaceData().clear();
|
||||||
|
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoRefineDriver::baffleAndSplitMesh
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const bool handleSnapProblems
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Splitting mesh at surface intersections" << nl
|
||||||
|
<< "---------------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
// Introduce baffles at surface intersections. Note:
|
||||||
|
// meshRefiment::surfaceIndex() will
|
||||||
|
// be like boundary face from now on so not coupled anymore.
|
||||||
|
meshRefiner_.baffleAndSplitMesh
|
||||||
|
(
|
||||||
|
handleSnapProblems,
|
||||||
|
!handleSnapProblems, // merge free standing baffles?
|
||||||
|
const_cast<Time&>(mesh.time()),
|
||||||
|
globalToPatch_,
|
||||||
|
refineParams.keepPoints()[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoRefineDriver::zonify
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Mesh is at its finest. Do zoning
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// This puts all faces with intersection across a zoneable surface
|
||||||
|
// into that surface's faceZone. All cells inside faceZone get given the
|
||||||
|
// same cellZone.
|
||||||
|
|
||||||
|
if (meshRefiner_.surfaces().getNamedSurfaces().size() > 0)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Introducing zones for interfaces" << nl
|
||||||
|
<< "--------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.zonify(refineParams.keepPoints()[0]);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "Writing zoned mesh to time "
|
||||||
|
<< mesh.time().timeName() << '.' << endl;
|
||||||
|
meshRefiner_.write
|
||||||
|
(
|
||||||
|
debug,
|
||||||
|
mesh.time().path()/mesh.time().timeName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all faces are synced
|
||||||
|
meshRefinement::checkCoupledFaceZones(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoRefineDriver::splitAndMergeBaffles
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const bool handleSnapProblems
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Handling cells with snap problems" << nl
|
||||||
|
<< "---------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
// Introduce baffles and split mesh
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.baffleAndSplitMesh
|
||||||
|
(
|
||||||
|
handleSnapProblems,
|
||||||
|
false, // merge free standing baffles?
|
||||||
|
const_cast<Time&>(mesh.time()),
|
||||||
|
globalToPatch_,
|
||||||
|
refineParams.keepPoints()[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicate points on baffles that are on more than one cell
|
||||||
|
// region. This will help snapping pull them to separate surfaces.
|
||||||
|
meshRefiner_.dupNonManifoldPoints();
|
||||||
|
|
||||||
|
|
||||||
|
// Merge all baffles that are still remaining after duplicating points.
|
||||||
|
List<labelPair> couples
|
||||||
|
(
|
||||||
|
meshRefiner_.getDuplicateFaces // get all baffles
|
||||||
|
(
|
||||||
|
identity(mesh.nFaces()-mesh.nInternalFaces())
|
||||||
|
+ mesh.nInternalFaces()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
label nCouples = returnReduce(couples.size(), sumOp<label>());
|
||||||
|
|
||||||
|
Info<< "Detected unsplittable baffles : "
|
||||||
|
<< nCouples << endl;
|
||||||
|
|
||||||
|
if (nCouples > 0)
|
||||||
|
{
|
||||||
|
// Actually merge baffles. Note: not exactly parallellized. Should
|
||||||
|
// convert baffle faces into processor faces if they resulted
|
||||||
|
// from them.
|
||||||
|
meshRefiner_.mergeBaffles(couples);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
// Debug:test all is still synced across proc patches
|
||||||
|
meshRefiner_.checkData();
|
||||||
|
}
|
||||||
|
Info<< "Merged free-standing baffles in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "Writing handleProblemCells mesh to time "
|
||||||
|
<< mesh.time().timeName() << '.' << endl;
|
||||||
|
meshRefiner_.write(debug, mesh.time().path()/mesh.time().timeName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoRefineDriver::mergePatchFaces
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Merge refined boundary faces" << nl
|
||||||
|
<< "----------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.mergePatchFaces
|
||||||
|
(
|
||||||
|
Foam::cos(45*mathematicalConstant::pi/180.0),
|
||||||
|
Foam::cos(45*mathematicalConstant::pi/180.0),
|
||||||
|
meshRefinement::addedPatches(globalToPatch_)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
meshRefiner_.checkData();
|
||||||
|
}
|
||||||
|
|
||||||
|
meshRefiner_.mergeEdges(Foam::cos(45*mathematicalConstant::pi/180.0));
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
meshRefiner_.checkData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoRefineDriver::doRefine
|
||||||
|
(
|
||||||
|
const dictionary& refineDict,
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const bool prepareForSnapping
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Refinement phase" << nl
|
||||||
|
<< "----------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
|
||||||
|
|
||||||
|
// Check that all the keep points are inside the mesh.
|
||||||
|
refineParams.findCells(mesh);
|
||||||
|
|
||||||
|
PtrList<dictionary> featDicts(refineDict.lookup("features"));
|
||||||
|
|
||||||
|
// Refine around feature edges
|
||||||
|
featureEdgeRefine
|
||||||
|
(
|
||||||
|
refineParams,
|
||||||
|
featDicts,
|
||||||
|
100, // maxIter
|
||||||
|
0 // min cells to refine
|
||||||
|
);
|
||||||
|
|
||||||
|
// Refine based on surface
|
||||||
|
surfaceOnlyRefine
|
||||||
|
(
|
||||||
|
refineParams,
|
||||||
|
100 // maxIter
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove cells (a certain distance) beyond surface intersections
|
||||||
|
removeInsideCells
|
||||||
|
(
|
||||||
|
refineParams,
|
||||||
|
1 // nBufferLayers
|
||||||
|
);
|
||||||
|
|
||||||
|
// Internal mesh refinement
|
||||||
|
shellRefine
|
||||||
|
(
|
||||||
|
refineParams,
|
||||||
|
100 // maxIter
|
||||||
|
);
|
||||||
|
|
||||||
|
// Introduce baffles at surface intersections
|
||||||
|
baffleAndSplitMesh(refineParams, prepareForSnapping);
|
||||||
|
|
||||||
|
// Mesh is at its finest. Do optional zoning.
|
||||||
|
zonify(refineParams);
|
||||||
|
|
||||||
|
// Pull baffles apart
|
||||||
|
splitAndMergeBaffles(refineParams, prepareForSnapping);
|
||||||
|
|
||||||
|
// Do something about cells with refined faces on the boundary
|
||||||
|
if (prepareForSnapping)
|
||||||
|
{
|
||||||
|
mergePatchFaces(refineParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Doing final balancing" << nl
|
||||||
|
<< "---------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do final balancing. Keep zoned faces on one processor.
|
||||||
|
meshRefiner_.balance
|
||||||
|
(
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
decomposer_,
|
||||||
|
distributor_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
179
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H
Normal file
179
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.H
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::autoRefineDriver
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
autoRefineDriver.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef autoRefineDriver_H
|
||||||
|
#define autoRefineDriver_H
|
||||||
|
|
||||||
|
#include "meshRefinement.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class featureEdgeMesh;
|
||||||
|
class refinementParameters;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class autoRefineDriver Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class autoRefineDriver
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Mesh+surface
|
||||||
|
meshRefinement& meshRefiner_;
|
||||||
|
|
||||||
|
//- Reference to decomposition method
|
||||||
|
decompositionMethod& decomposer_;
|
||||||
|
|
||||||
|
//- Reference to mesh distribution engine
|
||||||
|
fvMeshDistribute& distributor_;
|
||||||
|
|
||||||
|
//- From surface region to patch
|
||||||
|
const labelList globalToPatch_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Read explicit feature edges
|
||||||
|
label readFeatureEdges
|
||||||
|
(
|
||||||
|
const PtrList<dictionary>& featDicts,
|
||||||
|
PtrList<featureEdgeMesh>& featureMeshes,
|
||||||
|
labelList& featureLevel
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Refine all cells pierced by explicit feature edges
|
||||||
|
label featureEdgeRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const PtrList<dictionary>& featDicts,
|
||||||
|
const label maxIter,
|
||||||
|
const label minRefine
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Refine all cells interacting with the surface
|
||||||
|
label surfaceOnlyRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label maxIter
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Remove all cells within intersected region
|
||||||
|
void removeInsideCells
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label nBufferLayers
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Remove all cells inside/outside shell
|
||||||
|
label shellRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label maxIter
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Add baffles and remove unreachable cells
|
||||||
|
void baffleAndSplitMesh
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const bool handleSnapProblems
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Add zones
|
||||||
|
void zonify(const refinementParameters& refineParams);
|
||||||
|
|
||||||
|
void splitAndMergeBaffles
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const bool handleSnapProblems
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Merge refined boundary faces (from exposing coarser cell)
|
||||||
|
void mergePatchFaces
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
autoRefineDriver(const autoRefineDriver&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const autoRefineDriver&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
ClassName("autoRefineDriver");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
autoRefineDriver
|
||||||
|
(
|
||||||
|
meshRefinement& meshRefiner,
|
||||||
|
decompositionMethod& decomposer,
|
||||||
|
fvMeshDistribute& distributor,
|
||||||
|
const labelList& globalToPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Do all the refinement
|
||||||
|
void doRefine
|
||||||
|
(
|
||||||
|
const dictionary& refineDict,
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const bool prepareForSnapping
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -27,7 +27,12 @@ Description
|
|||||||
|
|
||||||
\*----------------------------------------------------------------------------*/
|
\*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "autoHexMeshDriver.H"
|
#include "autoSnapDriver.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "pointFields.H"
|
||||||
|
#include "motionSmoother.H"
|
||||||
|
#include "polyTopoChange.H"
|
||||||
|
#include "OFstream.H"
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
@ -37,16 +42,29 @@ Description
|
|||||||
#include "pointEdgePoint.H"
|
#include "pointEdgePoint.H"
|
||||||
#include "PointEdgeWave.H"
|
#include "PointEdgeWave.H"
|
||||||
#include "mergePoints.H"
|
#include "mergePoints.H"
|
||||||
|
#include "snapParameters.H"
|
||||||
|
#include "refinementSurfaces.H"
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(autoSnapDriver, 0);
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::autoHexMeshDriver::getZonedSurfaces
|
void Foam::autoSnapDriver::getZonedSurfaces
|
||||||
(
|
(
|
||||||
labelList& zonedSurfaces,
|
labelList& zonedSurfaces,
|
||||||
labelList& unzonedSurfaces
|
labelList& unzonedSurfaces
|
||||||
) const
|
) const
|
||||||
{ // Surfaces with zone information
|
{ // Surfaces with zone information
|
||||||
const wordList& faceZoneNames = surfaces().faceZoneNames();
|
const wordList& faceZoneNames = meshRefiner_.surfaces().faceZoneNames();
|
||||||
|
|
||||||
zonedSurfaces.setSize(faceZoneNames.size());
|
zonedSurfaces.setSize(faceZoneNames.size());
|
||||||
label zonedI = 0;
|
label zonedI = 0;
|
||||||
@ -70,15 +88,18 @@ void Foam::autoHexMeshDriver::getZonedSurfaces
|
|||||||
|
|
||||||
|
|
||||||
// Get faces to repatch. Returns map from face to patch.
|
// Get faces to repatch. Returns map from face to patch.
|
||||||
Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
|
Foam::Map<Foam::label> Foam::autoSnapDriver::getZoneBafflePatches
|
||||||
(
|
(
|
||||||
const bool allowBoundary
|
const bool allowBoundary
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
Map<label> bafflePatch(mesh_.nFaces()/1000);
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
const refinementSurfaces& surfaces = meshRefiner_.surfaces();
|
||||||
|
|
||||||
const wordList& faceZoneNames = surfaces().faceZoneNames();
|
Map<label> bafflePatch(mesh.nFaces()/1000);
|
||||||
const faceZoneMesh& fZones = mesh_.faceZones();
|
|
||||||
|
const wordList& faceZoneNames = surfaces.faceZoneNames();
|
||||||
|
const faceZoneMesh& fZones = mesh.faceZones();
|
||||||
|
|
||||||
forAll(faceZoneNames, surfI)
|
forAll(faceZoneNames, surfI)
|
||||||
{
|
{
|
||||||
@ -92,13 +113,12 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
|
|||||||
//// Get patch allocated for zone
|
//// Get patch allocated for zone
|
||||||
//label patchI = surfaceToCyclicPatch_[surfI];
|
//label patchI = surfaceToCyclicPatch_[surfI];
|
||||||
// Get patch of (first region) of surface
|
// Get patch of (first region) of surface
|
||||||
label patchI = globalToPatch_[surfaces().globalRegion(surfI, 0)];
|
label patchI = globalToPatch_[surfaces.globalRegion(surfI, 0)];
|
||||||
|
|
||||||
Info<< "For surface "
|
Info<< "For surface "
|
||||||
<< surfaces()[surfI].IOobject::name()
|
<< surfaces.names()[surfI]
|
||||||
//<< surfaces().names()[surfI]
|
|
||||||
<< " found faceZone " << fZone.name()
|
<< " found faceZone " << fZone.name()
|
||||||
<< " and patch " << mesh_.boundaryMesh()[patchI].name()
|
<< " and patch " << mesh.boundaryMesh()[patchI].name()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
@ -106,7 +126,7 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
|
|||||||
{
|
{
|
||||||
label faceI = fZone[i];
|
label faceI = fZone[i];
|
||||||
|
|
||||||
if (allowBoundary || mesh_.isInternalFace(faceI))
|
if (allowBoundary || mesh.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
if (!bafflePatch.insert(faceI, patchI))
|
if (!bafflePatch.insert(faceI, patchI))
|
||||||
{
|
{
|
||||||
@ -116,11 +136,11 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
|
|||||||
{
|
{
|
||||||
FatalErrorIn("getZoneBafflePatches(const bool)")
|
FatalErrorIn("getZoneBafflePatches(const bool)")
|
||||||
<< "Face " << faceI
|
<< "Face " << faceI
|
||||||
<< " fc:" << mesh_.faceCentres()[faceI]
|
<< " fc:" << mesh.faceCentres()[faceI]
|
||||||
<< " is in faceZone "
|
<< " is in faceZone "
|
||||||
<< mesh_.boundaryMesh()[oldPatchI].name()
|
<< mesh.boundaryMesh()[oldPatchI].name()
|
||||||
<< " and in faceZone "
|
<< " and in faceZone "
|
||||||
<< mesh_.boundaryMesh()[patchI].name()
|
<< mesh.boundaryMesh()[patchI].name()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +154,7 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
|
|||||||
|
|
||||||
// Calculate geometrically collocated points, Requires PackedList to be
|
// Calculate geometrically collocated points, Requires PackedList to be
|
||||||
// sizes and initalised!
|
// sizes and initalised!
|
||||||
Foam::label Foam::autoHexMeshDriver::getCollocatedPoints
|
Foam::label Foam::autoSnapDriver::getCollocatedPoints
|
||||||
(
|
(
|
||||||
const scalar tol,
|
const scalar tol,
|
||||||
const pointField& points,
|
const pointField& points,
|
||||||
@ -196,7 +216,7 @@ Foam::label Foam::autoHexMeshDriver::getCollocatedPoints
|
|||||||
|
|
||||||
|
|
||||||
// Calculate displacement as average of patch points.
|
// Calculate displacement as average of patch points.
|
||||||
Foam::pointField Foam::autoHexMeshDriver::smoothPatchDisplacement
|
Foam::pointField Foam::autoSnapDriver::smoothPatchDisplacement
|
||||||
(
|
(
|
||||||
const motionSmoother& meshMover
|
const motionSmoother& meshMover
|
||||||
) const
|
) const
|
||||||
@ -483,7 +503,7 @@ Foam::pointField Foam::autoHexMeshDriver::smoothPatchDisplacement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::autoHexMeshDriver::edgePatchDist
|
Foam::tmp<Foam::scalarField> Foam::autoSnapDriver::edgePatchDist
|
||||||
(
|
(
|
||||||
const pointMesh& pMesh,
|
const pointMesh& pMesh,
|
||||||
const indirectPrimitivePatch& pp
|
const indirectPrimitivePatch& pp
|
||||||
@ -565,7 +585,7 @@ Foam::tmp<Foam::scalarField> Foam::autoHexMeshDriver::edgePatchDist
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::autoHexMeshDriver::dumpMove
|
void Foam::autoSnapDriver::dumpMove
|
||||||
(
|
(
|
||||||
const fileName& fName,
|
const fileName& fName,
|
||||||
const pointField& meshPts,
|
const pointField& meshPts,
|
||||||
@ -596,7 +616,7 @@ void Foam::autoHexMeshDriver::dumpMove
|
|||||||
|
|
||||||
// Check whether all displacement vectors point outwards of patch. Return true
|
// Check whether all displacement vectors point outwards of patch. Return true
|
||||||
// if so.
|
// if so.
|
||||||
bool Foam::autoHexMeshDriver::outwardsDisplacement
|
bool Foam::autoSnapDriver::outwardsDisplacement
|
||||||
(
|
(
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const vectorField& patchDisp
|
const vectorField& patchDisp
|
||||||
@ -637,9 +657,22 @@ bool Foam::autoHexMeshDriver::outwardsDisplacement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoSnapDriver::autoSnapDriver
|
||||||
|
(
|
||||||
|
meshRefinement& meshRefiner,
|
||||||
|
const labelList& globalToPatch
|
||||||
|
)
|
||||||
|
:
|
||||||
|
meshRefiner_(meshRefiner),
|
||||||
|
globalToPatch_(globalToPatch)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoSnapDriver::createZoneBaffles
|
||||||
(
|
(
|
||||||
List<labelPair>& baffles
|
List<labelPair>& baffles
|
||||||
)
|
)
|
||||||
@ -653,6 +686,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
|
|||||||
// No need to sync; all processors will have all same zonedSurfaces.
|
// No need to sync; all processors will have all same zonedSurfaces.
|
||||||
if (zonedSurfaces.size() > 0)
|
if (zonedSurfaces.size() > 0)
|
||||||
{
|
{
|
||||||
|
fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
// Split internal faces on interface surfaces
|
// Split internal faces on interface surfaces
|
||||||
Info<< "Converting zoned faces into baffles ..." << endl;
|
Info<< "Converting zoned faces into baffles ..." << endl;
|
||||||
|
|
||||||
@ -664,14 +699,14 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
|
|||||||
if (nZoneFaces > 0)
|
if (nZoneFaces > 0)
|
||||||
{
|
{
|
||||||
// Convert into labelLists
|
// Convert into labelLists
|
||||||
labelList ownPatch(mesh_.nFaces(), -1);
|
labelList ownPatch(mesh.nFaces(), -1);
|
||||||
forAllConstIter(Map<label>, faceToPatch, iter)
|
forAllConstIter(Map<label>, faceToPatch, iter)
|
||||||
{
|
{
|
||||||
ownPatch[iter.key()] = iter();
|
ownPatch[iter.key()] = iter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create baffles. both sides same patch.
|
// Create baffles. both sides same patch.
|
||||||
map = meshRefinerPtr_().createBaffles(ownPatch, ownPatch);
|
map = meshRefiner_.createBaffles(ownPatch, ownPatch);
|
||||||
|
|
||||||
// Get pairs of faces created.
|
// Get pairs of faces created.
|
||||||
// Just loop over faceMap and store baffle if we encounter a slave
|
// Just loop over faceMap and store baffle if we encounter a slave
|
||||||
@ -702,29 +737,29 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
|
|||||||
|
|
||||||
if (baffleI != faceToPatch.size())
|
if (baffleI != faceToPatch.size())
|
||||||
{
|
{
|
||||||
FatalErrorIn("autoHexMeshDriver::createZoneBaffles(..)")
|
FatalErrorIn("autoSnapDriver::createZoneBaffles(..)")
|
||||||
<< "Had " << faceToPatch.size() << " patches to create "
|
<< "Had " << faceToPatch.size() << " patches to create "
|
||||||
<< " but encountered " << baffleI
|
<< " but encountered " << baffleI
|
||||||
<< " slave faces originating from patcheable faces."
|
<< " slave faces originating from patcheable faces."
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_)
|
if (debug)
|
||||||
{
|
{
|
||||||
const_cast<Time&>(mesh_.time())++;
|
const_cast<Time&>(mesh.time())++;
|
||||||
Pout<< "Writing baffled mesh to time " << mesh_.time().timeName()
|
Pout<< "Writing baffled mesh to time "
|
||||||
<< endl;
|
<< mesh.time().timeName() << endl;
|
||||||
mesh_.write();
|
mesh.write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info<< "Created " << nZoneFaces << " baffles in = "
|
Info<< "Created " << nZoneFaces << " baffles in = "
|
||||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::mergeZoneBaffles
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoSnapDriver::mergeZoneBaffles
|
||||||
(
|
(
|
||||||
const List<labelPair>& baffles
|
const List<labelPair>& baffles
|
||||||
)
|
)
|
||||||
@ -743,29 +778,27 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::mergeZoneBaffles
|
|||||||
Info<< "Converting " << nBaffles << " baffles back into zoned faces ..."
|
Info<< "Converting " << nBaffles << " baffles back into zoned faces ..."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
map = meshRefinerPtr_().mergeBaffles(baffles);
|
map = meshRefiner_.mergeBaffles(baffles);
|
||||||
|
|
||||||
Info<< "Converted baffles in = "
|
Info<< "Converted baffles in = "
|
||||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
<< meshRefiner_.mesh().time().cpuTimeIncrement()
|
||||||
|
<< " s\n" << nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
|
Foam::scalarField Foam::autoSnapDriver::calcSnapDistance
|
||||||
(
|
(
|
||||||
const dictionary& snapDict,
|
const snapParameters& snapParams,
|
||||||
const indirectPrimitivePatch& pp
|
const indirectPrimitivePatch& pp
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// When to snap
|
|
||||||
scalar snapTol(readScalar(snapDict.lookup("snapTol")));
|
|
||||||
|
|
||||||
|
|
||||||
const edgeList& edges = pp.edges();
|
const edgeList& edges = pp.edges();
|
||||||
const labelListList& pointEdges = pp.pointEdges();
|
const labelListList& pointEdges = pp.pointEdges();
|
||||||
const pointField& localPoints = pp.localPoints();
|
const pointField& localPoints = pp.localPoints();
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
scalarField maxEdgeLen(localPoints.size(), -GREAT);
|
scalarField maxEdgeLen(localPoints.size(), -GREAT);
|
||||||
|
|
||||||
@ -785,7 +818,7 @@ Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
|
|||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
pp.meshPoints(),
|
pp.meshPoints(),
|
||||||
maxEdgeLen,
|
maxEdgeLen,
|
||||||
maxEqOp<scalar>(), // combine op
|
maxEqOp<scalar>(), // combine op
|
||||||
@ -793,57 +826,61 @@ Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
|
|||||||
false // no separation
|
false // no separation
|
||||||
);
|
);
|
||||||
|
|
||||||
return snapTol*maxEdgeLen;
|
return snapParams.snapTol()*maxEdgeLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Invert globalToPatch_ to get the patches related to surfaces.
|
//// Invert globalToPatch_ to get the patches related to surfaces.
|
||||||
Foam::labelList Foam::autoHexMeshDriver::getSurfacePatches() const
|
//Foam::labelList Foam::autoSnapDriver::getSurfacePatches() const
|
||||||
{
|
//{
|
||||||
// Set of patches originating from surface
|
// // Set of patches originating from surface
|
||||||
labelHashSet surfacePatchSet(surfaces().size());
|
// labelHashSet surfacePatchSet(globalToPatch_.size());
|
||||||
|
//
|
||||||
forAll(globalToPatch_, i)
|
// forAll(globalToPatch_, i)
|
||||||
{
|
// {
|
||||||
if (globalToPatch_[i] != -1)
|
// if (globalToPatch_[i] != -1)
|
||||||
{
|
// {
|
||||||
surfacePatchSet.insert(globalToPatch_[i]);
|
// surfacePatchSet.insert(globalToPatch_[i]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
DynamicList<label> surfacePatches(surfacePatchSet.size());
|
// const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
//
|
||||||
for (label patchI = 0; patchI < mesh_.boundaryMesh().size(); patchI++)
|
// DynamicList<label> surfacePatches(surfacePatchSet.size());
|
||||||
{
|
//
|
||||||
if (surfacePatchSet.found(patchI))
|
// for (label patchI = 0; patchI < mesh.boundaryMesh().size(); patchI++)
|
||||||
{
|
// {
|
||||||
surfacePatches.append(patchI);
|
// if (surfacePatchSet.found(patchI))
|
||||||
}
|
// {
|
||||||
}
|
// surfacePatches.append(patchI);
|
||||||
return surfacePatches.shrink();
|
// }
|
||||||
}
|
// }
|
||||||
|
// return surfacePatches.shrink();
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
void Foam::autoHexMeshDriver::preSmoothPatch
|
void Foam::autoSnapDriver::preSmoothPatch
|
||||||
(
|
(
|
||||||
const dictionary& snapDict,
|
const snapParameters& snapParams,
|
||||||
const label nInitErrors,
|
const label nInitErrors,
|
||||||
const List<labelPair>& baffles,
|
const List<labelPair>& baffles,
|
||||||
motionSmoother& meshMover
|
motionSmoother& meshMover
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Smoothing iterations
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
label nSmoothPatch(readLabel(snapDict.lookup("nSmoothPatch")));
|
|
||||||
// Snapping iterations
|
|
||||||
label nSnap(readLabel(snapDict.lookup("nSnap")));
|
|
||||||
|
|
||||||
labelList checkFaces;
|
labelList checkFaces;
|
||||||
|
|
||||||
Info<< "Smoothing patch points ..." << endl;
|
Info<< "Smoothing patch points ..." << endl;
|
||||||
for (label smoothIter = 0; smoothIter < nSmoothPatch; smoothIter++)
|
for
|
||||||
|
(
|
||||||
|
label smoothIter = 0;
|
||||||
|
smoothIter < snapParams.nSmoothPatch();
|
||||||
|
smoothIter++
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Info<< "Smoothing iteration " << smoothIter << endl;
|
Info<< "Smoothing iteration " << smoothIter << endl;
|
||||||
checkFaces.setSize(mesh_.nFaces());
|
checkFaces.setSize(mesh.nFaces());
|
||||||
forAll(checkFaces, faceI)
|
forAll(checkFaces, faceI)
|
||||||
{
|
{
|
||||||
checkFaces[faceI] = faceI;
|
checkFaces[faceI] = faceI;
|
||||||
@ -857,11 +894,11 @@ void Foam::autoHexMeshDriver::preSmoothPatch
|
|||||||
|
|
||||||
scalar oldErrorReduction = -1;
|
scalar oldErrorReduction = -1;
|
||||||
|
|
||||||
for (label snapIter = 0; snapIter < 2*nSnap; snapIter++)
|
for (label snapIter = 0; snapIter < 2*snapParams.nSnap(); snapIter++)
|
||||||
{
|
{
|
||||||
Info<< nl << "Scaling iteration " << snapIter << endl;
|
Info<< nl << "Scaling iteration " << snapIter << endl;
|
||||||
|
|
||||||
if (snapIter == nSnap)
|
if (snapIter == snapParams.nSnap())
|
||||||
{
|
{
|
||||||
Info<< "Displacement scaling for error reduction set to 0."
|
Info<< "Displacement scaling for error reduction set to 0."
|
||||||
<< endl;
|
<< endl;
|
||||||
@ -888,20 +925,72 @@ void Foam::autoHexMeshDriver::preSmoothPatch
|
|||||||
// The current mesh is the starting mesh to smooth from.
|
// The current mesh is the starting mesh to smooth from.
|
||||||
meshMover.correct();
|
meshMover.correct();
|
||||||
|
|
||||||
if (debug_)
|
if (debug)
|
||||||
{
|
{
|
||||||
const_cast<Time&>(mesh_.time())++;
|
const_cast<Time&>(mesh.time())++;
|
||||||
Pout<< "Writing patch smoothed mesh to time " << mesh_.time().timeName()
|
Pout<< "Writing patch smoothed mesh to time " << mesh.time().timeName()
|
||||||
<< endl;
|
<< endl;
|
||||||
mesh_.write();
|
mesh.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Patch points smoothed in = "
|
Info<< "Patch points smoothed in = "
|
||||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
// Get (pp-local) indices of points that are both on zone and on patched surface
|
||||||
|
Foam::labelList Foam::autoSnapDriver::getZoneSurfacePoints
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const word& zoneName
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
label zoneI = mesh.faceZones().findZoneID(zoneName);
|
||||||
|
|
||||||
|
if (zoneI == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"autoSnapDriver::getZoneSurfacePoints"
|
||||||
|
"(const indirectPrimitivePatch&, const word&)"
|
||||||
|
) << "Cannot find zone " << zoneName
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const faceZone& fZone = mesh.faceZones()[zoneI];
|
||||||
|
|
||||||
|
|
||||||
|
// Could use PrimitivePatch & localFaces to extract points but might just
|
||||||
|
// as well do it ourselves.
|
||||||
|
|
||||||
|
boolList pointOnZone(pp.nPoints(), false);
|
||||||
|
|
||||||
|
forAll(fZone, i)
|
||||||
|
{
|
||||||
|
const face& f = mesh.faces()[fZone[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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::vectorField Foam::autoSnapDriver::calcNearestSurface
|
||||||
(
|
(
|
||||||
const scalarField& snapDist,
|
const scalarField& snapDist,
|
||||||
motionSmoother& meshMover
|
motionSmoother& meshMover
|
||||||
@ -912,6 +1001,8 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
|
|
||||||
const indirectPrimitivePatch& pp = meshMover.patch();
|
const indirectPrimitivePatch& pp = meshMover.patch();
|
||||||
const pointField& localPoints = pp.localPoints();
|
const pointField& localPoints = pp.localPoints();
|
||||||
|
const refinementSurfaces& surfaces = meshRefiner_.surfaces();
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
// Divide surfaces into zoned and unzoned
|
// Divide surfaces into zoned and unzoned
|
||||||
labelList zonedSurfaces;
|
labelList zonedSurfaces;
|
||||||
@ -925,38 +1016,45 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
// 1. All points to non-interface surfaces
|
// 1. All points to non-interface surfaces
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
forAll(localPoints, pointI)
|
|
||||||
{
|
{
|
||||||
pointIndexHit pHit;
|
List<pointIndexHit> hitInfo;
|
||||||
|
labelList hitSurface;
|
||||||
label surfI = surfaces().findNearest
|
surfaces.findNearest
|
||||||
(
|
(
|
||||||
unzonedSurfaces,
|
unzonedSurfaces,
|
||||||
localPoints[pointI],
|
localPoints,
|
||||||
sqr(4*snapDist[pointI]), // sqr of attract distance
|
sqr(4*snapDist), // sqr of attract distance
|
||||||
pHit
|
hitSurface,
|
||||||
|
hitInfo
|
||||||
);
|
);
|
||||||
|
|
||||||
if (surfI != -1)
|
forAll(hitInfo, pointI)
|
||||||
{
|
{
|
||||||
patchDisp[pointI] = pHit.hitPoint() - localPoints[pointI];
|
if (hitInfo[pointI].hit())
|
||||||
|
{
|
||||||
|
patchDisp[pointI] =
|
||||||
|
hitInfo[pointI].hitPoint()
|
||||||
|
- localPoints[pointI];
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
// WarningIn("autoHexMeshDriver::calcNearestSurface(..)")
|
// WarningIn("autoSnapDriver::calcNearestSurface(..)")
|
||||||
// << "For point:" << pointI
|
// << "For point:" << pointI
|
||||||
// << " coordinate:" << localPoints[pointI]
|
// << " coordinate:" << localPoints[pointI]
|
||||||
// << " did not find any surface within:" << 4*snapDist[pointI]
|
// << " did not find any surface within:"
|
||||||
|
// << 4*snapDist[pointI]
|
||||||
// << " meter." << endl;
|
// << " meter." << endl;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 2. All points on zones to their respective surface
|
// 2. All points on zones to their respective surface
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Surfaces with zone information
|
// Surfaces with zone information
|
||||||
const wordList& faceZoneNames = surfaces().faceZoneNames();
|
const wordList& faceZoneNames = surfaces.faceZoneNames();
|
||||||
|
|
||||||
forAll(zonedSurfaces, i)
|
forAll(zonedSurfaces, i)
|
||||||
{
|
{
|
||||||
@ -964,43 +1062,45 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
|
|
||||||
const labelList surfacesToTest(1, zoneSurfI);
|
const labelList surfacesToTest(1, zoneSurfI);
|
||||||
|
|
||||||
label zoneI = mesh_.faceZones().findZoneID(faceZoneNames[zoneSurfI]);
|
// Get indices of points both on faceZone and on pp.
|
||||||
|
labelList zonePointIndices
|
||||||
const faceZone& fZone = mesh_.faceZones()[zoneI];
|
|
||||||
|
|
||||||
forAll(fZone, i)
|
|
||||||
{
|
|
||||||
const face& f = mesh_.faces()[fZone[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();
|
|
||||||
|
|
||||||
pointIndexHit pHit;
|
|
||||||
|
|
||||||
label surfI = surfaces().findNearest
|
|
||||||
(
|
(
|
||||||
surfacesToTest,
|
getZoneSurfacePoints
|
||||||
localPoints[pointI],
|
(
|
||||||
sqr(4*snapDist[pointI]), // sqr of attract distance
|
pp,
|
||||||
pHit
|
faceZoneNames[zoneSurfI]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (surfI != -1)
|
pointField zonePoints(zonePointIndices.size());
|
||||||
|
forAll(zonePointIndices, i)
|
||||||
|
{
|
||||||
|
zonePoints[i] = localPoints[zonePointIndices[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find nearest for points both on faceZone and pp.
|
||||||
|
List<pointIndexHit> hitInfo;
|
||||||
|
labelList hitSurface;
|
||||||
|
surfaces.findNearest
|
||||||
|
(
|
||||||
|
labelList(1, zoneSurfI),
|
||||||
|
zonePoints,
|
||||||
|
sqr(4*snapDist),
|
||||||
|
hitSurface,
|
||||||
|
hitInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(hitInfo, pointI)
|
||||||
|
{
|
||||||
|
if (hitInfo[pointI].hit())
|
||||||
{
|
{
|
||||||
patchDisp[pointI] =
|
patchDisp[pointI] =
|
||||||
pHit.hitPoint() - localPoints[pointI];
|
hitInfo[pointI].hitPoint()
|
||||||
|
- localPoints[pointI];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WarningIn("autoHexMeshDriver::calcNearestSurface(..)")
|
WarningIn("autoSnapDriver::calcNearestSurface(..)")
|
||||||
<< "For point:" << pointI
|
<< "For point:" << pointI
|
||||||
<< " coordinate:" << localPoints[pointI]
|
<< " coordinate:" << localPoints[pointI]
|
||||||
<< " did not find any surface within:"
|
<< " did not find any surface within:"
|
||||||
@ -1009,8 +1109,6 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1023,7 +1121,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Calculated surface displacement in = "
|
Info<< "Calculated surface displacement in = "
|
||||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
// Limit amount of movement.
|
// Limit amount of movement.
|
||||||
@ -1045,7 +1143,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
// will not do condition 2 on all. Sync explicitly.
|
// will not do condition 2 on all. Sync explicitly.
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh,
|
||||||
pp.meshPoints(),
|
pp.meshPoints(),
|
||||||
patchDisp,
|
patchDisp,
|
||||||
minMagEqOp(), // combine op
|
minMagEqOp(), // combine op
|
||||||
@ -1062,11 +1160,11 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
// pointVectorField.
|
// pointVectorField.
|
||||||
meshMover.setDisplacement(patchDisp);
|
meshMover.setDisplacement(patchDisp);
|
||||||
|
|
||||||
if (debug_)
|
if (debug)
|
||||||
{
|
{
|
||||||
dumpMove
|
dumpMove
|
||||||
(
|
(
|
||||||
mesh_.time().path()/"patchDisplacement.obj",
|
mesh.time().path()/"patchDisplacement.obj",
|
||||||
pp.localPoints(),
|
pp.localPoints(),
|
||||||
pp.localPoints() + patchDisp
|
pp.localPoints() + patchDisp
|
||||||
);
|
);
|
||||||
@ -1076,29 +1174,27 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::autoHexMeshDriver::smoothDisplacement
|
void Foam::autoSnapDriver::smoothDisplacement
|
||||||
(
|
(
|
||||||
const dictionary& snapDict,
|
const snapParameters& snapParams,
|
||||||
motionSmoother& meshMover
|
motionSmoother& meshMover
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
const pointMesh& pMesh = meshMover.pMesh();
|
const pointMesh& pMesh = meshMover.pMesh();
|
||||||
const indirectPrimitivePatch& pp = meshMover.patch();
|
const indirectPrimitivePatch& pp = meshMover.patch();
|
||||||
|
|
||||||
Info<< "Smoothing displacement ..." << endl;
|
Info<< "Smoothing displacement ..." << endl;
|
||||||
|
|
||||||
// Smoothing iterations
|
|
||||||
label nSmoothDisp(readLabel(snapDict.lookup("nSmoothDispl")));
|
|
||||||
|
|
||||||
// Set edge diffusivity as inverse of distance to patch
|
// Set edge diffusivity as inverse of distance to patch
|
||||||
scalarField edgeGamma(1.0/(edgePatchDist(pMesh, pp) + SMALL));
|
scalarField edgeGamma(1.0/(edgePatchDist(pMesh, pp) + SMALL));
|
||||||
//scalarField edgeGamma(mesh_.nEdges(), 1.0);
|
//scalarField edgeGamma(mesh.nEdges(), 1.0);
|
||||||
//scalarField edgeGamma(wallGamma(mesh, pp, 10, 1));
|
//scalarField edgeGamma(wallGamma(mesh, pp, 10, 1));
|
||||||
|
|
||||||
// Get displacement field
|
// Get displacement field
|
||||||
pointVectorField& disp = meshMover.displacement();
|
pointVectorField& disp = meshMover.displacement();
|
||||||
|
|
||||||
for (label iter = 0; iter < nSmoothDisp; iter++)
|
for (label iter = 0; iter < snapParams.nSmoothDispl(); iter++)
|
||||||
{
|
{
|
||||||
if ((iter % 10) == 0)
|
if ((iter % 10) == 0)
|
||||||
{
|
{
|
||||||
@ -1109,14 +1205,14 @@ void Foam::autoHexMeshDriver::smoothDisplacement
|
|||||||
meshMover.smooth(oldDisp, edgeGamma, false, disp);
|
meshMover.smooth(oldDisp, edgeGamma, false, disp);
|
||||||
}
|
}
|
||||||
Info<< "Displacement smoothed in = "
|
Info<< "Displacement smoothed in = "
|
||||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
|
|
||||||
if (debug_)
|
if (debug)
|
||||||
{
|
{
|
||||||
const_cast<Time&>(mesh_.time())++;
|
const_cast<Time&>(mesh.time())++;
|
||||||
Pout<< "Writing smoothed mesh to time " << mesh_.time().timeName()
|
Pout<< "Writing smoothed mesh to time " << mesh.time().timeName()
|
||||||
<< endl;
|
<< endl;
|
||||||
mesh_.write();
|
mesh.write();
|
||||||
|
|
||||||
Pout<< "Writing displacement field ..." << endl;
|
Pout<< "Writing displacement field ..." << endl;
|
||||||
disp.write();
|
disp.write();
|
||||||
@ -1130,7 +1226,7 @@ void Foam::autoHexMeshDriver::smoothDisplacement
|
|||||||
);
|
);
|
||||||
dumpMove
|
dumpMove
|
||||||
(
|
(
|
||||||
mesh_.time().path()/"actualPatchDisplacement.obj",
|
mesh.time().path()/"actualPatchDisplacement.obj",
|
||||||
pp.localPoints(),
|
pp.localPoints(),
|
||||||
pp.localPoints() + actualPatchDisp
|
pp.localPoints() + actualPatchDisp
|
||||||
);
|
);
|
||||||
@ -1138,30 +1234,28 @@ void Foam::autoHexMeshDriver::smoothDisplacement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::autoHexMeshDriver::scaleMesh
|
void Foam::autoSnapDriver::scaleMesh
|
||||||
(
|
(
|
||||||
const dictionary& snapDict,
|
const snapParameters& snapParams,
|
||||||
const label nInitErrors,
|
const label nInitErrors,
|
||||||
const List<labelPair>& baffles,
|
const List<labelPair>& baffles,
|
||||||
motionSmoother& meshMover
|
motionSmoother& meshMover
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Snapping iterations
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
label nSnap(readLabel(snapDict.lookup("nSnap")));
|
|
||||||
|
|
||||||
|
|
||||||
// Relax displacement until correct mesh
|
// Relax displacement until correct mesh
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
labelList checkFaces(identity(mesh_.nFaces()));
|
labelList checkFaces(identity(mesh.nFaces()));
|
||||||
|
|
||||||
scalar oldErrorReduction = -1;
|
scalar oldErrorReduction = -1;
|
||||||
|
|
||||||
Info<< "Moving mesh ..." << endl;
|
Info<< "Moving mesh ..." << endl;
|
||||||
for (label iter = 0; iter < 2*nSnap; iter++)
|
for (label iter = 0; iter < 2*snapParams.nSnap(); iter++)
|
||||||
{
|
{
|
||||||
Info<< nl << "Iteration " << iter << endl;
|
Info<< nl << "Iteration " << iter << endl;
|
||||||
|
|
||||||
if (iter == nSnap)
|
if (iter == snapParams.nSnap())
|
||||||
{
|
{
|
||||||
Info<< "Displacement scaling for error reduction set to 0." << endl;
|
Info<< "Displacement scaling for error reduction set to 0." << endl;
|
||||||
oldErrorReduction = meshMover.setErrorReduction(0.0);
|
oldErrorReduction = meshMover.setErrorReduction(0.0);
|
||||||
@ -1173,12 +1267,12 @@ void Foam::autoHexMeshDriver::scaleMesh
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (debug_)
|
if (debug)
|
||||||
{
|
{
|
||||||
const_cast<Time&>(mesh_.time())++;
|
const_cast<Time&>(mesh.time())++;
|
||||||
Pout<< "Writing scaled mesh to time " << mesh_.time().timeName()
|
Pout<< "Writing scaled mesh to time " << mesh.time().timeName()
|
||||||
<< endl;
|
<< endl;
|
||||||
mesh_.write();
|
mesh.write();
|
||||||
|
|
||||||
Pout<< "Writing displacement field ..." << endl;
|
Pout<< "Writing displacement field ..." << endl;
|
||||||
meshMover.displacement().write();
|
meshMover.displacement().write();
|
||||||
@ -1192,7 +1286,99 @@ void Foam::autoHexMeshDriver::scaleMesh
|
|||||||
meshMover.setErrorReduction(oldErrorReduction);
|
meshMover.setErrorReduction(oldErrorReduction);
|
||||||
}
|
}
|
||||||
Info<< "Moved mesh in = "
|
Info<< "Moved mesh in = "
|
||||||
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::autoSnapDriver::doSnap
|
||||||
|
(
|
||||||
|
const dictionary& snapDict,
|
||||||
|
const dictionary& motionDict,
|
||||||
|
const snapParameters& snapParams
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Morphing phase" << nl
|
||||||
|
<< "--------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const_cast<Time&>(mesh.time())++;
|
||||||
|
|
||||||
|
// Get the labels of added patches.
|
||||||
|
labelList adaptPatchIDs(meshRefinement::addedPatches(globalToPatch_));
|
||||||
|
|
||||||
|
// Create baffles (pairs of faces that share the same points)
|
||||||
|
// Baffles stored as owner and neighbour face that have been created.
|
||||||
|
List<labelPair> baffles;
|
||||||
|
createZoneBaffles(baffles);
|
||||||
|
|
||||||
|
{
|
||||||
|
autoPtr<indirectPrimitivePatch> ppPtr
|
||||||
|
(
|
||||||
|
meshRefinement::makePatch
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
adaptPatchIDs
|
||||||
|
)
|
||||||
|
);
|
||||||
|
indirectPrimitivePatch& pp = ppPtr();
|
||||||
|
|
||||||
|
// Distance to attact to nearest feature on surface
|
||||||
|
const scalarField snapDist(calcSnapDistance(snapParams, pp));
|
||||||
|
|
||||||
|
|
||||||
|
// Construct iterative mesh mover.
|
||||||
|
Info<< "Constructing mesh displacer ..." << endl;
|
||||||
|
Info<< "Using mesh parameters " << motionDict << nl << endl;
|
||||||
|
|
||||||
|
pointMesh pMesh(mesh);
|
||||||
|
|
||||||
|
motionSmoother meshMover
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
pp,
|
||||||
|
adaptPatchIDs,
|
||||||
|
meshRefinement::makeDisplacementField(pMesh, adaptPatchIDs),
|
||||||
|
motionDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Check initial mesh
|
||||||
|
Info<< "Checking initial mesh ..." << endl;
|
||||||
|
labelHashSet wrongFaces(mesh.nFaces()/100);
|
||||||
|
motionSmoother::checkMesh(false, mesh, motionDict, wrongFaces);
|
||||||
|
const label nInitErrors = returnReduce
|
||||||
|
(
|
||||||
|
wrongFaces.size(),
|
||||||
|
sumOp<label>()
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "Detected " << nInitErrors << " illegal faces"
|
||||||
|
<< " (concave, zero area or negative cell pyramid volume)"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Checked initial mesh in = "
|
||||||
|
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
|
||||||
|
|
||||||
|
// Pre-smooth patch vertices (so before determining nearest)
|
||||||
|
preSmoothPatch(snapParams, nInitErrors, baffles, meshMover);
|
||||||
|
|
||||||
|
// Calculate displacement at every patch point. Insert into
|
||||||
|
// meshMover.
|
||||||
|
calcNearestSurface(snapDist, meshMover);
|
||||||
|
|
||||||
|
// Get smoothly varying internal displacement field.
|
||||||
|
smoothDisplacement(snapParams, meshMover);
|
||||||
|
|
||||||
|
// Apply internal displacement to mesh.
|
||||||
|
scaleMesh(snapParams, nInitErrors, baffles, meshMover);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge any introduced baffles.
|
||||||
|
mergeZoneBaffles(baffles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
236
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H
Normal file
236
src/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::autoSnapDriver
|
||||||
|
|
||||||
|
Description
|
||||||
|
All to do with snapping to surface
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
autoSnapDriver.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef autoSnapDriver_H
|
||||||
|
#define autoSnapDriver_H
|
||||||
|
|
||||||
|
#include "meshRefinement.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class motionSmoother;
|
||||||
|
class snapParameters;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class autoSnapDriver Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class autoSnapDriver
|
||||||
|
{
|
||||||
|
// Private classes
|
||||||
|
|
||||||
|
//- Combine operator class for equalizing displacements.
|
||||||
|
class minMagEqOp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void operator()(vector& x, const vector& y) const
|
||||||
|
{
|
||||||
|
if (magSqr(y) < magSqr(x))
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Mesh+surface
|
||||||
|
meshRefinement& meshRefiner_;
|
||||||
|
|
||||||
|
//- From surface region to patch
|
||||||
|
const labelList globalToPatch_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
|
||||||
|
// Snapping
|
||||||
|
|
||||||
|
//- Split surfaces into non-zoned and zones ones
|
||||||
|
void getZonedSurfaces(labelList&, labelList&) const;
|
||||||
|
|
||||||
|
//- Get faces to repatch. Returns map from face to patch.
|
||||||
|
Map<label> getZoneBafflePatches(const bool allowBoundary) const;
|
||||||
|
|
||||||
|
//- Calculates (geometric) shared points
|
||||||
|
static label getCollocatedPoints
|
||||||
|
(
|
||||||
|
const scalar tol,
|
||||||
|
const pointField&,
|
||||||
|
PackedList<1>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate displacement per patch point to smooth out patch.
|
||||||
|
// Quite complicated in determining which points to move where.
|
||||||
|
pointField smoothPatchDisplacement(const motionSmoother&) const;
|
||||||
|
|
||||||
|
//- Check that face zones are synced
|
||||||
|
void checkCoupledFaceZones() const;
|
||||||
|
|
||||||
|
//- Per edge distance to patch
|
||||||
|
static tmp<scalarField> edgePatchDist
|
||||||
|
(
|
||||||
|
const pointMesh&,
|
||||||
|
const indirectPrimitivePatch&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Write displacement as .obj file.
|
||||||
|
static void dumpMove
|
||||||
|
(
|
||||||
|
const fileName&,
|
||||||
|
const pointField&,
|
||||||
|
const pointField&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Check displacement is outwards pointing
|
||||||
|
static bool outwardsDisplacement
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch&,
|
||||||
|
const vectorField&
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
autoSnapDriver(const autoSnapDriver&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const autoSnapDriver&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
ClassName("autoSnapDriver");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
autoSnapDriver
|
||||||
|
(
|
||||||
|
meshRefinement& meshRefiner,
|
||||||
|
const labelList& globalToPatch
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Snapping
|
||||||
|
|
||||||
|
//- Create baffles for faces straddling zoned surfaces. Return
|
||||||
|
// baffles.
|
||||||
|
autoPtr<mapPolyMesh> createZoneBaffles(List<labelPair>&);
|
||||||
|
|
||||||
|
//- Merge baffles.
|
||||||
|
autoPtr<mapPolyMesh> mergeZoneBaffles(const List<labelPair>&);
|
||||||
|
|
||||||
|
//- Calculate edge length per patch point.
|
||||||
|
scalarField calcSnapDistance
|
||||||
|
(
|
||||||
|
const snapParameters& snapParams,
|
||||||
|
const indirectPrimitivePatch&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
////- Get patches generated for surfaces.
|
||||||
|
//labelList getSurfacePatches() const;
|
||||||
|
|
||||||
|
//- Smooth the mesh (patch and internal) to increase visibility
|
||||||
|
// of surface points (on castellated mesh) w.r.t. surface.
|
||||||
|
void preSmoothPatch
|
||||||
|
(
|
||||||
|
const snapParameters& snapParams,
|
||||||
|
const label nInitErrors,
|
||||||
|
const List<labelPair>& baffles,
|
||||||
|
motionSmoother&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Get points both on patch and facezone.
|
||||||
|
labelList getZoneSurfacePoints
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch&,
|
||||||
|
const word& zoneName
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Per patch point calculate point on nearest surface. Set as
|
||||||
|
// boundary conditions of motionSmoother displacement field. Return
|
||||||
|
// displacement of patch points.
|
||||||
|
vectorField calcNearestSurface
|
||||||
|
(
|
||||||
|
const scalarField& snapDist,
|
||||||
|
motionSmoother& meshMover
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Smooth the displacement field to the internal.
|
||||||
|
void smoothDisplacement
|
||||||
|
(
|
||||||
|
const snapParameters& snapParams,
|
||||||
|
motionSmoother&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Do the hard work: move the mesh according to displacement,
|
||||||
|
// locally relax the displacement.
|
||||||
|
void scaleMesh
|
||||||
|
(
|
||||||
|
const snapParameters& snapParams,
|
||||||
|
const label nInitErrors,
|
||||||
|
const List<labelPair>& baffles,
|
||||||
|
motionSmoother&
|
||||||
|
);
|
||||||
|
|
||||||
|
void doSnap
|
||||||
|
(
|
||||||
|
const dictionary& snapDict,
|
||||||
|
const dictionary& motionDict,
|
||||||
|
const snapParameters& snapParams
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,327 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "layerParameters.H"
|
||||||
|
#include "polyBoundaryMesh.H"
|
||||||
|
#include "mathematicalConstants.H"
|
||||||
|
#include "refinementSurfaces.H"
|
||||||
|
#include "searchableSurfaces.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Read the number of layers from dictionary. Per patch 0 or the number
|
||||||
|
// of layers.
|
||||||
|
Foam::labelList Foam::layerParameters::readNumLayers
|
||||||
|
(
|
||||||
|
const PtrList<dictionary>& surfaceDicts,
|
||||||
|
const refinementSurfaces& refineSurfaces,
|
||||||
|
const labelList& globalToPatch,
|
||||||
|
const polyBoundaryMesh& boundaryMesh
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Per surface the number of layers
|
||||||
|
labelList globalSurfLayers(surfaceDicts.size());
|
||||||
|
// Per surface, per region the number of layers
|
||||||
|
List<Map<label> > regionSurfLayers(surfaceDicts.size());
|
||||||
|
|
||||||
|
const labelList& surfaceIndices = refineSurfaces.surfaces();
|
||||||
|
|
||||||
|
forAll(surfaceDicts, surfI)
|
||||||
|
{
|
||||||
|
const dictionary& dict = surfaceDicts[surfI];
|
||||||
|
|
||||||
|
globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
|
||||||
|
|
||||||
|
if (dict.found("regions"))
|
||||||
|
{
|
||||||
|
// Per-region layer information
|
||||||
|
|
||||||
|
PtrList<dictionary> regionDicts(dict.lookup("regions"));
|
||||||
|
|
||||||
|
const wordList& regionNames =
|
||||||
|
refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
|
||||||
|
|
||||||
|
forAll(regionDicts, dictI)
|
||||||
|
{
|
||||||
|
const dictionary& regionDict = regionDicts[dictI];
|
||||||
|
|
||||||
|
const word regionName(regionDict.lookup("name"));
|
||||||
|
|
||||||
|
label regionI = findIndex(regionNames, regionName);
|
||||||
|
|
||||||
|
label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
|
||||||
|
|
||||||
|
Info<< " region " << regionName << ':'<< nl
|
||||||
|
<< " surface layers:" << nLayers << nl;
|
||||||
|
|
||||||
|
regionSurfLayers[surfI].insert(regionI, nLayers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Transfer per surface/region information into patchwise region info
|
||||||
|
|
||||||
|
labelList nLayers(boundaryMesh.size(), 0);
|
||||||
|
|
||||||
|
forAll(surfaceIndices, surfI)
|
||||||
|
{
|
||||||
|
const wordList& regionNames =
|
||||||
|
refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
|
||||||
|
|
||||||
|
forAll(regionNames, regionI)
|
||||||
|
{
|
||||||
|
const word& regionName = regionNames[regionI];
|
||||||
|
|
||||||
|
label global = refineSurfaces.globalRegion(surfI, regionI);
|
||||||
|
|
||||||
|
label patchI = globalToPatch[global];
|
||||||
|
|
||||||
|
// Initialise to surface-wise layers
|
||||||
|
nLayers[patchI] = globalSurfLayers[surfI];
|
||||||
|
|
||||||
|
// Override with region specific data if available
|
||||||
|
Map<label>::const_iterator iter =
|
||||||
|
regionSurfLayers[surfI].find(regionI);
|
||||||
|
|
||||||
|
if (iter != regionSurfLayers[surfI].end())
|
||||||
|
{
|
||||||
|
nLayers[patchI] = iter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check
|
||||||
|
if (nLayers[patchI] < 0)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"layerParameters::readNumLayers(..)"
|
||||||
|
) << "Illegal number of layers " << nLayers[patchI]
|
||||||
|
<< " for surface "
|
||||||
|
<< refineSurfaces.names()[surfI]
|
||||||
|
<< " region " << regionName << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nLayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Construct from dictionary
|
||||||
|
Foam::layerParameters::layerParameters
|
||||||
|
(
|
||||||
|
const PtrList<dictionary>& surfaceDicts,
|
||||||
|
const refinementSurfaces& refineSurfaces,
|
||||||
|
const labelList& globalToPatch,
|
||||||
|
const dictionary& dict,
|
||||||
|
const polyBoundaryMesh& boundaryMesh
|
||||||
|
)
|
||||||
|
:
|
||||||
|
numLayers_
|
||||||
|
(
|
||||||
|
readNumLayers
|
||||||
|
(
|
||||||
|
surfaceDicts,
|
||||||
|
refineSurfaces,
|
||||||
|
globalToPatch,
|
||||||
|
boundaryMesh
|
||||||
|
)
|
||||||
|
),
|
||||||
|
expansionRatio_
|
||||||
|
(
|
||||||
|
numLayers_.size(),
|
||||||
|
readScalar(dict.lookup("expansionRatio"))
|
||||||
|
),
|
||||||
|
finalLayerRatio_
|
||||||
|
(
|
||||||
|
numLayers_.size(),
|
||||||
|
readScalar(dict.lookup("finalLayerRatio"))
|
||||||
|
),
|
||||||
|
minThickness_
|
||||||
|
(
|
||||||
|
numLayers_.size(),
|
||||||
|
readScalar(dict.lookup("minThickness"))
|
||||||
|
),
|
||||||
|
featureAngle_(readScalar(dict.lookup("featureAngle"))),
|
||||||
|
concaveAngle_
|
||||||
|
(
|
||||||
|
dict.found("concaveAngle")
|
||||||
|
? readScalar(dict.lookup("concaveAngle"))
|
||||||
|
: defaultConcaveAngle
|
||||||
|
),
|
||||||
|
nGrow_(readLabel(dict.lookup("nGrow"))),
|
||||||
|
nSmoothSurfaceNormals_
|
||||||
|
(
|
||||||
|
readLabel(dict.lookup("nSmoothSurfaceNormals"))
|
||||||
|
),
|
||||||
|
nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
|
||||||
|
nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
|
||||||
|
maxFaceThicknessRatio_
|
||||||
|
(
|
||||||
|
readScalar(dict.lookup("maxFaceThicknessRatio"))
|
||||||
|
),
|
||||||
|
layerTerminationCos_
|
||||||
|
(
|
||||||
|
Foam::cos
|
||||||
|
(
|
||||||
|
0.5
|
||||||
|
* featureAngle_
|
||||||
|
* mathematicalConstant::pi/180.
|
||||||
|
)
|
||||||
|
),
|
||||||
|
maxThicknessToMedialRatio_
|
||||||
|
(
|
||||||
|
readScalar(dict.lookup("maxThicknessToMedialRatio"))
|
||||||
|
),
|
||||||
|
minMedianAxisAngleCos_
|
||||||
|
(
|
||||||
|
Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
|
||||||
|
* mathematicalConstant::pi/180.
|
||||||
|
),
|
||||||
|
nBufferCellsNoExtrude_
|
||||||
|
(
|
||||||
|
readLabel(dict.lookup("nBufferCellsNoExtrude"))
|
||||||
|
),
|
||||||
|
nSnap_(readLabel(dict.lookup("nSnap")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Construct from dictionary
|
||||||
|
Foam::layerParameters::layerParameters
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const polyBoundaryMesh& boundaryMesh
|
||||||
|
)
|
||||||
|
:
|
||||||
|
numLayers_(boundaryMesh.size(), 0),
|
||||||
|
expansionRatio_
|
||||||
|
(
|
||||||
|
boundaryMesh.size(),
|
||||||
|
readScalar(dict.lookup("expansionRatio"))
|
||||||
|
),
|
||||||
|
finalLayerRatio_
|
||||||
|
(
|
||||||
|
boundaryMesh.size(),
|
||||||
|
readScalar(dict.lookup("finalLayerRatio"))
|
||||||
|
),
|
||||||
|
minThickness_
|
||||||
|
(
|
||||||
|
boundaryMesh.size(),
|
||||||
|
readScalar(dict.lookup("minThickness"))
|
||||||
|
),
|
||||||
|
featureAngle_(readScalar(dict.lookup("featureAngle"))),
|
||||||
|
concaveAngle_
|
||||||
|
(
|
||||||
|
dict.found("concaveAngle")
|
||||||
|
? readScalar(dict.lookup("concaveAngle"))
|
||||||
|
: defaultConcaveAngle
|
||||||
|
),
|
||||||
|
nGrow_(readLabel(dict.lookup("nGrow"))),
|
||||||
|
nSmoothSurfaceNormals_
|
||||||
|
(
|
||||||
|
readLabel(dict.lookup("nSmoothSurfaceNormals"))
|
||||||
|
),
|
||||||
|
nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
|
||||||
|
nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
|
||||||
|
maxFaceThicknessRatio_
|
||||||
|
(
|
||||||
|
readScalar(dict.lookup("maxFaceThicknessRatio"))
|
||||||
|
),
|
||||||
|
layerTerminationCos_
|
||||||
|
(
|
||||||
|
Foam::cos
|
||||||
|
(
|
||||||
|
0.5
|
||||||
|
* featureAngle_
|
||||||
|
* mathematicalConstant::pi/180.
|
||||||
|
)
|
||||||
|
),
|
||||||
|
maxThicknessToMedialRatio_
|
||||||
|
(
|
||||||
|
readScalar(dict.lookup("maxThicknessToMedialRatio"))
|
||||||
|
),
|
||||||
|
minMedianAxisAngleCos_
|
||||||
|
(
|
||||||
|
Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
|
||||||
|
* mathematicalConstant::pi/180.
|
||||||
|
),
|
||||||
|
nBufferCellsNoExtrude_
|
||||||
|
(
|
||||||
|
readLabel(dict.lookup("nBufferCellsNoExtrude"))
|
||||||
|
),
|
||||||
|
nSnap_(readLabel(dict.lookup("nRelaxIter")))
|
||||||
|
{
|
||||||
|
const dictionary& layersDict = dict.subDict("layers");
|
||||||
|
|
||||||
|
forAllConstIter(dictionary, layersDict, iter)
|
||||||
|
{
|
||||||
|
const word& key = iter().keyword();
|
||||||
|
|
||||||
|
if (layersDict.isDict(key))
|
||||||
|
{
|
||||||
|
label patchI = boundaryMesh.findPatchID(key);
|
||||||
|
|
||||||
|
if (patchI == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"layerParameters::layerParameters"
|
||||||
|
"(const dictionary&, const polyBoundaryMesh&)"
|
||||||
|
) << "Specified illegal patch " << key
|
||||||
|
<< " in layer dictionary." << endl
|
||||||
|
<< "Valid patch names are " << boundaryMesh.names()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dictionary& layerDict = layersDict.subDict(key);
|
||||||
|
|
||||||
|
numLayers_[patchI] =
|
||||||
|
readLabel(layerDict.lookup("nSurfaceLayers"));
|
||||||
|
|
||||||
|
//- Patch-wise layer parameters disabled for now. Just remove
|
||||||
|
// settings in initialiser list and uncomment below.
|
||||||
|
//expansionRatio_[patchI] =
|
||||||
|
// readScalar(layerDict.lookup("expansionRatio"));
|
||||||
|
//finalLayerRatio_[patchI] =
|
||||||
|
// readScalar(layerDict.lookup("finalLayerRatio"));
|
||||||
|
//minThickness_[patchI] =
|
||||||
|
// readScalar(layerDict.lookup("minThickness"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,263 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::layerParameters
|
||||||
|
|
||||||
|
Description
|
||||||
|
Simple container to keep together layer specific information.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
layerParameters.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef layerParameters_H
|
||||||
|
#define layerParameters_H
|
||||||
|
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "scalarField.H"
|
||||||
|
#include "labelList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Class forward declarations
|
||||||
|
class polyBoundaryMesh;
|
||||||
|
class refinementSurfaces;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class layerParameters Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class layerParameters
|
||||||
|
{
|
||||||
|
// Static data members
|
||||||
|
|
||||||
|
//- Default angle for faces to be convcave
|
||||||
|
static const scalar defaultConcaveAngle;
|
||||||
|
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
// Per patch (not region!) information
|
||||||
|
|
||||||
|
//- How many layers to add.
|
||||||
|
labelList numLayers_;
|
||||||
|
|
||||||
|
scalarField expansionRatio_;
|
||||||
|
|
||||||
|
//- Wanted thickness of final added cell layer. If multiple layers
|
||||||
|
// is the thickness of the layer furthest away from the wall.
|
||||||
|
// Relative to undistorted size of cell outside layer.
|
||||||
|
scalarField finalLayerRatio_;
|
||||||
|
|
||||||
|
//- Minimum thickness of cell layer. If for any reason layer
|
||||||
|
// cannot be above minThickness do not add layer.
|
||||||
|
// Relative to undistorted size of cell outside layer.
|
||||||
|
scalarField minThickness_;
|
||||||
|
|
||||||
|
|
||||||
|
scalar featureAngle_;
|
||||||
|
|
||||||
|
scalar concaveAngle_;
|
||||||
|
|
||||||
|
label nGrow_;
|
||||||
|
|
||||||
|
label nSmoothSurfaceNormals_;
|
||||||
|
|
||||||
|
label nSmoothNormals_;
|
||||||
|
|
||||||
|
label nSmoothThickness_;
|
||||||
|
|
||||||
|
scalar maxFaceThicknessRatio_;
|
||||||
|
|
||||||
|
scalar layerTerminationCos_;
|
||||||
|
|
||||||
|
scalar maxThicknessToMedialRatio_;
|
||||||
|
|
||||||
|
scalar minMedianAxisAngleCos_;
|
||||||
|
|
||||||
|
label nBufferCellsNoExtrude_;
|
||||||
|
|
||||||
|
label nSnap_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Extract patch-wise number of layers
|
||||||
|
static labelList readNumLayers
|
||||||
|
(
|
||||||
|
const PtrList<dictionary>& surfaceDicts,
|
||||||
|
const refinementSurfaces& refineSurfaces,
|
||||||
|
const labelList& globalToPatch,
|
||||||
|
const polyBoundaryMesh& boundaryMesh
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
layerParameters(const layerParameters&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const layerParameters&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary - old syntax
|
||||||
|
layerParameters
|
||||||
|
(
|
||||||
|
const PtrList<dictionary>& surfaceDicts,
|
||||||
|
const refinementSurfaces& refineSurfaces,
|
||||||
|
const labelList& globalToPatch,
|
||||||
|
const dictionary& dict,
|
||||||
|
const polyBoundaryMesh& boundaryMesh
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from dictionary - new syntax
|
||||||
|
layerParameters(const dictionary& dict, const polyBoundaryMesh&);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
// Per patch information
|
||||||
|
|
||||||
|
//- How many layers to add.
|
||||||
|
const labelList& numLayers() const
|
||||||
|
{
|
||||||
|
return numLayers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expansion factor for layer mesh
|
||||||
|
const scalarField& expansionRatio() const
|
||||||
|
{
|
||||||
|
return expansionRatio_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Wanted thickness of final added cell layer. If multiple
|
||||||
|
// layers
|
||||||
|
// is the thickness of the layer furthest away from the wall.
|
||||||
|
// Relative to undistorted size of cell outside layer.
|
||||||
|
const scalarField& finalLayerRatio() const
|
||||||
|
{
|
||||||
|
return finalLayerRatio_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Minimum thickness of cell layer. If for any reason layer
|
||||||
|
// cannot be above minThickness do not add layer.
|
||||||
|
// Relative to undistorted size of cell outside layer.
|
||||||
|
const scalarField& minThickness() const
|
||||||
|
{
|
||||||
|
return minThickness_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
scalar featureAngle() const
|
||||||
|
{
|
||||||
|
return featureAngle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar concaveAngle() const
|
||||||
|
{
|
||||||
|
return concaveAngle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- If points get not extruded do nGrow layers of connected faces
|
||||||
|
// that are not grown. Is used to not do layers at all close to
|
||||||
|
// features.
|
||||||
|
label nGrow() const
|
||||||
|
{
|
||||||
|
return nGrow_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of smoothing iterations of surface normals
|
||||||
|
label nSmoothSurfaceNormals() const
|
||||||
|
{
|
||||||
|
return nSmoothSurfaceNormals_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of smoothing iterations of interior mesh movement
|
||||||
|
// direction
|
||||||
|
label nSmoothNormals() const
|
||||||
|
{
|
||||||
|
return nSmoothNormals_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smooth layer thickness over surface patches
|
||||||
|
label nSmoothThickness() const
|
||||||
|
{
|
||||||
|
return nSmoothThickness_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop layer growth on highly warped cells
|
||||||
|
scalar maxFaceThicknessRatio() const
|
||||||
|
{
|
||||||
|
return maxFaceThicknessRatio_;
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar layerTerminationCos() const
|
||||||
|
{
|
||||||
|
return layerTerminationCos_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reduce layer growth where ratio thickness to medial
|
||||||
|
// distance is large
|
||||||
|
scalar maxThicknessToMedialRatio() const
|
||||||
|
{
|
||||||
|
return maxThicknessToMedialRatio_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Angle used to pick up medial axis points
|
||||||
|
scalar minMedianAxisAngleCos() const
|
||||||
|
{
|
||||||
|
return minMedianAxisAngleCos_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create buffer region for new layer terminations
|
||||||
|
label nBufferCellsNoExtrude() const
|
||||||
|
{
|
||||||
|
return nBufferCellsNoExtrude_;
|
||||||
|
}
|
||||||
|
|
||||||
|
label nSnap() const
|
||||||
|
{
|
||||||
|
return nSnap_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "refinementParameters.H"
|
||||||
|
#include "mathematicalConstants.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Construct from dictionary
|
||||||
|
Foam::refinementParameters::refinementParameters
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const label dummy
|
||||||
|
)
|
||||||
|
:
|
||||||
|
maxGlobalCells_(readLabel(dict.lookup("cellLimit"))),
|
||||||
|
maxLocalCells_(readLabel(dict.lookup("procCellLimit"))),
|
||||||
|
minRefineCells_(readLabel(dict.lookup("minimumRefine"))),
|
||||||
|
curvature_(readScalar(dict.lookup("curvature"))),
|
||||||
|
nBufferLayers_(readLabel(dict.lookup("nBufferLayers"))),
|
||||||
|
keepPoints_(dict.lookup("keepPoints"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::refinementParameters::refinementParameters(const dictionary& dict)
|
||||||
|
:
|
||||||
|
maxGlobalCells_(readLabel(dict.lookup("maxGlobalCells"))),
|
||||||
|
maxLocalCells_(readLabel(dict.lookup("maxLocalCells"))),
|
||||||
|
minRefineCells_(readLabel(dict.lookup("minRefinementCells"))),
|
||||||
|
nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))),
|
||||||
|
keepPoints_(pointField(1, dict.lookup("locationInMesh")))
|
||||||
|
{
|
||||||
|
scalar featAngle(readScalar(dict.lookup("resolveFeatureAngle")));
|
||||||
|
|
||||||
|
if (featAngle < 0 || featAngle > 180)
|
||||||
|
{
|
||||||
|
curvature_ = -GREAT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curvature_ = Foam::cos(featAngle*mathematicalConstant::pi/180.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::refinementParameters::findCells(const polyMesh& mesh)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
// Global calculation engine
|
||||||
|
globalIndex globalCells(mesh.nCells());
|
||||||
|
|
||||||
|
// Cell label per point
|
||||||
|
labelList cellLabels(keepPoints_.size());
|
||||||
|
|
||||||
|
forAll(keepPoints_, i)
|
||||||
|
{
|
||||||
|
const point& keepPoint = keepPoints_[i];
|
||||||
|
|
||||||
|
label localCellI = mesh.findCell(keepPoint);
|
||||||
|
|
||||||
|
label globalCellI = -1;
|
||||||
|
|
||||||
|
if (localCellI != -1)
|
||||||
|
{
|
||||||
|
Pout<< "Found point " << keepPoint << " in cell " << localCellI
|
||||||
|
<< " on processor " << Pstream::myProcNo() << endl;
|
||||||
|
globalCellI = globalCells.toGlobal(localCellI);
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(globalCellI, maxOp<label>());
|
||||||
|
|
||||||
|
if (globalCellI == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"refinementParameters::findCells(const polyMesh&) const"
|
||||||
|
) << "Point " << keepPoint
|
||||||
|
<< " is not inside the mesh or on a face or edge." << nl
|
||||||
|
<< "Bounding box of the mesh:" << mesh.bounds()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalCells.isLocal(globalCellI))
|
||||||
|
{
|
||||||
|
cellLabels[i] = localCellI;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cellLabels[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cellLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,154 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::refinementParameters
|
||||||
|
|
||||||
|
Description
|
||||||
|
Simple container to keep together refinement specific information.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
refinementParameters.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef refinementParameters_H
|
||||||
|
#define refinementParameters_H
|
||||||
|
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "pointField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Class forward declarations
|
||||||
|
class polyMesh;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class refinementParameters Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class refinementParameters
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Total number of cells
|
||||||
|
const label maxGlobalCells_;
|
||||||
|
|
||||||
|
//- Per processor max number of cells
|
||||||
|
const label maxLocalCells_;
|
||||||
|
|
||||||
|
//- When to stop refining
|
||||||
|
const label minRefineCells_;
|
||||||
|
|
||||||
|
//- Curvature
|
||||||
|
scalar curvature_;
|
||||||
|
|
||||||
|
//- Number of layers between different refinement levels
|
||||||
|
const label nBufferLayers_;
|
||||||
|
|
||||||
|
//- Areas to keep
|
||||||
|
const pointField keepPoints_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
refinementParameters(const refinementParameters&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const refinementParameters&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary - old syntax
|
||||||
|
refinementParameters(const dictionary& dict, const label dummy);
|
||||||
|
|
||||||
|
//- Construct from dictionary - new syntax
|
||||||
|
refinementParameters(const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Total number of cells
|
||||||
|
label maxGlobalCells() const
|
||||||
|
{
|
||||||
|
return maxGlobalCells_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Per processor max number of cells
|
||||||
|
label maxLocalCells() const
|
||||||
|
{
|
||||||
|
return maxLocalCells_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- When to stop refining
|
||||||
|
label minRefineCells() const
|
||||||
|
{
|
||||||
|
return minRefineCells_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Curvature
|
||||||
|
scalar curvature() const
|
||||||
|
{
|
||||||
|
return curvature_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Number of layers between different refinement levels
|
||||||
|
label nBufferLayers() const
|
||||||
|
{
|
||||||
|
return nBufferLayers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Areas to keep
|
||||||
|
const pointField& keepPoints() const
|
||||||
|
{
|
||||||
|
return keepPoints_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
//- Checks that cells are in mesh. Returns cells they are in.
|
||||||
|
labelList findCells(const polyMesh&) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "snapParameters.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Construct from dictionary
|
||||||
|
Foam::snapParameters::snapParameters(const dictionary& dict, const label dummy)
|
||||||
|
:
|
||||||
|
nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))),
|
||||||
|
snapTol_(readScalar(dict.lookup("snapTol"))),
|
||||||
|
nSmoothDispl_(readLabel(dict.lookup("nSmoothDispl"))),
|
||||||
|
nSnap_(readLabel(dict.lookup("nSnap")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Construct from dictionary
|
||||||
|
Foam::snapParameters::snapParameters(const dictionary& dict)
|
||||||
|
:
|
||||||
|
nSmoothPatch_(readLabel(dict.lookup("nSmoothPatch"))),
|
||||||
|
snapTol_(readScalar(dict.lookup("tolerance"))),
|
||||||
|
nSmoothDispl_(readLabel(dict.lookup("nSolveIter"))),
|
||||||
|
nSnap_(readLabel(dict.lookup("nRelaxIter")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::snapParameters
|
||||||
|
|
||||||
|
Description
|
||||||
|
Simple container to keep together snap specific information.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
snapParameters.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef snapParameters_H
|
||||||
|
#define snapParameters_H
|
||||||
|
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "scalar.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Class forward declarations
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class snapParameters Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class snapParameters
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
const label nSmoothPatch_;
|
||||||
|
|
||||||
|
const scalar snapTol_;
|
||||||
|
|
||||||
|
const label nSmoothDispl_;
|
||||||
|
|
||||||
|
const label nSnap_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
snapParameters(const snapParameters&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const snapParameters&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary - old syntax
|
||||||
|
snapParameters(const dictionary& dict, const label dummy);
|
||||||
|
|
||||||
|
//- Construct from dictionary - new syntax
|
||||||
|
snapParameters(const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Number of patch smoothing iterations before finding
|
||||||
|
// correspondence to surface
|
||||||
|
label nSmoothPatch() const
|
||||||
|
{
|
||||||
|
return nSmoothPatch_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Relative distance for points to be attracted by surface
|
||||||
|
// feature point
|
||||||
|
// or edge. True distance is this factor times local
|
||||||
|
// maximum edge length.
|
||||||
|
scalar snapTol() const
|
||||||
|
{
|
||||||
|
return snapTol_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Number of mesh displacement smoothing iterations.
|
||||||
|
label nSmoothDispl() const
|
||||||
|
{
|
||||||
|
return nSmoothDispl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Maximum number of snapping relaxation iterations. Should stop
|
||||||
|
// before upon reaching a correct mesh.
|
||||||
|
label nSnap() const
|
||||||
|
{
|
||||||
|
return nSnap_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ Description
|
|||||||
(static) surfaces.
|
(static) surfaces.
|
||||||
|
|
||||||
Maintains
|
Maintains
|
||||||
- per face any intersections of this edge with any of the surfaces
|
- per face any intersections of the cc-cc segment with any of the surfaces
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
meshRefinement.C
|
meshRefinement.C
|
||||||
@ -62,6 +62,7 @@ class fvMesh;
|
|||||||
class mapDistributePolyMesh;
|
class mapDistributePolyMesh;
|
||||||
class decompositionMethod;
|
class decompositionMethod;
|
||||||
class refinementSurfaces;
|
class refinementSurfaces;
|
||||||
|
class shellSurfaces;
|
||||||
class removeCells;
|
class removeCells;
|
||||||
class featureEdgeMesh;
|
class featureEdgeMesh;
|
||||||
class fvMeshDistribute;
|
class fvMeshDistribute;
|
||||||
@ -93,7 +94,7 @@ public:
|
|||||||
{
|
{
|
||||||
MASTERONLY = 1, /*!< maintain master only */
|
MASTERONLY = 1, /*!< maintain master only */
|
||||||
KEEPALL = 2, /*!< have slaves (upon refinement) from master */
|
KEEPALL = 2, /*!< have slaves (upon refinement) from master */
|
||||||
REMOVE = 4 /*!< set value to -1 any face that has been refined */
|
REMOVE = 4 /*!< set value to -1 any face that was refined */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -105,10 +106,14 @@ private:
|
|||||||
fvMesh& mesh_;
|
fvMesh& mesh_;
|
||||||
|
|
||||||
//- tolerance used for sorting coordinates (used in 'less' routine)
|
//- tolerance used for sorting coordinates (used in 'less' routine)
|
||||||
const scalar tol_;
|
const scalar mergeDistance_;
|
||||||
|
|
||||||
|
//- All surface-intersection interaction
|
||||||
const refinementSurfaces& surfaces_;
|
const refinementSurfaces& surfaces_;
|
||||||
|
|
||||||
|
//- All shell-refinement interaction
|
||||||
|
const shellSurfaces& shells_;
|
||||||
|
|
||||||
//- refinement engine
|
//- refinement engine
|
||||||
hexRef8 meshCutter_;
|
hexRef8 meshCutter_;
|
||||||
|
|
||||||
@ -229,14 +234,18 @@ private:
|
|||||||
//- Mark cells for refinement-shells based refinement.
|
//- Mark cells for refinement-shells based refinement.
|
||||||
label markInternalRefinement
|
label markInternalRefinement
|
||||||
(
|
(
|
||||||
const PtrList<searchableSurface>&,
|
|
||||||
const labelList& shellLevels,
|
|
||||||
const boolList& shellRefineInside,
|
|
||||||
const label nAllowRefine,
|
const label nAllowRefine,
|
||||||
labelList& refineCell,
|
labelList& refineCell,
|
||||||
label& nRefine
|
label& nRefine
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Collect faces that are intersected and whose neighbours aren't
|
||||||
|
// yet marked for refinement.
|
||||||
|
labelList getRefineCandidateFaces
|
||||||
|
(
|
||||||
|
const labelList& refineCell
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Mark cells for surface intersection based refinement.
|
//- Mark cells for surface intersection based refinement.
|
||||||
label markSurfaceRefinement
|
label markSurfaceRefinement
|
||||||
(
|
(
|
||||||
@ -252,17 +261,13 @@ private:
|
|||||||
// regions.
|
// regions.
|
||||||
bool checkCurvature
|
bool checkCurvature
|
||||||
(
|
(
|
||||||
const labelList& globalToPatch,
|
|
||||||
const scalar curvature,
|
const scalar curvature,
|
||||||
const bool markDifferingRegions,
|
|
||||||
const label nAllowRefine,
|
const label nAllowRefine,
|
||||||
const label newSurfI,
|
const label surfaceLevel,
|
||||||
const label newTriI,
|
const vector& surfaceNormal,
|
||||||
const label cellI,
|
const label cellI,
|
||||||
|
label& cellMaxLevel,
|
||||||
label& maxCellSurfI,
|
vector& cellMaxNormal,
|
||||||
label& maxCellTriI,
|
|
||||||
|
|
||||||
labelList& refineCell,
|
labelList& refineCell,
|
||||||
label& nRefine
|
label& nRefine
|
||||||
) const;
|
) const;
|
||||||
@ -273,9 +278,7 @@ private:
|
|||||||
// (markDifferingRegions)
|
// (markDifferingRegions)
|
||||||
label markSurfaceCurvatureRefinement
|
label markSurfaceCurvatureRefinement
|
||||||
(
|
(
|
||||||
const labelList& globalToPatch,
|
|
||||||
const scalar curvature,
|
const scalar curvature,
|
||||||
const bool markDifferingRegions,
|
|
||||||
const label nAllowRefine,
|
const label nAllowRefine,
|
||||||
const labelList& neiLevel,
|
const labelList& neiLevel,
|
||||||
const pointField& neiCc,
|
const pointField& neiCc,
|
||||||
@ -380,8 +383,9 @@ public:
|
|||||||
meshRefinement
|
meshRefinement
|
||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const scalar tol,
|
const scalar mergeDistance,
|
||||||
const refinementSurfaces&
|
const refinementSurfaces&,
|
||||||
|
const shellSurfaces&
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -399,12 +403,23 @@ public:
|
|||||||
return mesh_;
|
return mesh_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scalar mergeDistance() const
|
||||||
|
{
|
||||||
|
return mergeDistance_;
|
||||||
|
}
|
||||||
|
|
||||||
//- reference to surface search engines
|
//- reference to surface search engines
|
||||||
const refinementSurfaces& surfaces() const
|
const refinementSurfaces& surfaces() const
|
||||||
{
|
{
|
||||||
return surfaces_;
|
return surfaces_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- reference to refinement shells (regions)
|
||||||
|
const shellSurfaces& shells() const
|
||||||
|
{
|
||||||
|
return shells_;
|
||||||
|
}
|
||||||
|
|
||||||
//- reference to meshcutting engine
|
//- reference to meshcutting engine
|
||||||
const hexRef8& meshCutter() const
|
const hexRef8& meshCutter() const
|
||||||
{
|
{
|
||||||
@ -454,6 +469,18 @@ public:
|
|||||||
decompositionMethod&
|
decompositionMethod&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Redecompose according to cell count
|
||||||
|
// keepZoneFaces : find all faceZones from zoned surfaces and keep
|
||||||
|
// owner and neighbour together
|
||||||
|
// keepBaffles : find all baffles and keep them together
|
||||||
|
autoPtr<mapDistributePolyMesh> balance
|
||||||
|
(
|
||||||
|
const bool keepZoneFaces,
|
||||||
|
const bool keepBaffles,
|
||||||
|
decompositionMethod& decomposer,
|
||||||
|
fvMeshDistribute& distributor
|
||||||
|
);
|
||||||
|
|
||||||
//- Get faces with intersection.
|
//- Get faces with intersection.
|
||||||
labelList intersectedFaces() const;
|
labelList intersectedFaces() const;
|
||||||
|
|
||||||
@ -482,22 +509,21 @@ public:
|
|||||||
const labelList& adaptPatchIDs
|
const labelList& adaptPatchIDs
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Helper function: check that face zones are synced
|
||||||
|
static void checkCoupledFaceZones(const polyMesh&);
|
||||||
|
|
||||||
|
|
||||||
// Refinement
|
// Refinement
|
||||||
|
|
||||||
//- Calculate list of cells to refine.
|
//- Calculate list of cells to refine.
|
||||||
labelList refineCandidates
|
labelList refineCandidates
|
||||||
(
|
(
|
||||||
const point& keepPoint,
|
const point& keepPoint,
|
||||||
const labelList& globalToPatch,
|
|
||||||
const scalar curvature,
|
const scalar curvature,
|
||||||
|
|
||||||
const PtrList<featureEdgeMesh>& featureMeshes,
|
const PtrList<featureEdgeMesh>& featureMeshes,
|
||||||
const labelList& featureLevels,
|
const labelList& featureLevels,
|
||||||
|
|
||||||
const PtrList<searchableSurface>&,
|
|
||||||
const labelList& shellLevels,
|
|
||||||
const boolList& shellRefineInside,
|
|
||||||
|
|
||||||
const bool featureRefinement,
|
const bool featureRefinement,
|
||||||
const bool internalRefinement,
|
const bool internalRefinement,
|
||||||
const bool surfaceRefinement,
|
const bool surfaceRefinement,
|
||||||
@ -626,7 +652,7 @@ public:
|
|||||||
template<class T>
|
template<class T>
|
||||||
void testSyncBoundaryFaceList
|
void testSyncBoundaryFaceList
|
||||||
(
|
(
|
||||||
const scalar tol,
|
const scalar mergeDistance,
|
||||||
const string&,
|
const string&,
|
||||||
const UList<T>&,
|
const UList<T>&,
|
||||||
const UList<T>&
|
const UList<T>&
|
||||||
|
|||||||
@ -249,7 +249,7 @@ void Foam::meshRefinement::getBafflePatches
|
|||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "getBafflePatches : Not baffling surface "
|
Pout<< "getBafflePatches : Not baffling surface "
|
||||||
<< surfaces_[surfI].searchableSurface::name() << endl;
|
<< surfaces_.names()[surfI] << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -264,69 +264,95 @@ void Foam::meshRefinement::getBafflePatches
|
|||||||
neiPatch.setSize(mesh_.nFaces());
|
neiPatch.setSize(mesh_.nFaces());
|
||||||
neiPatch = -1;
|
neiPatch = -1;
|
||||||
|
|
||||||
forAll(surfaceIndex_, faceI)
|
|
||||||
|
// Collect candidate faces
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelList testFaces(intersectedFaces());
|
||||||
|
|
||||||
|
// Collect segments
|
||||||
|
// ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
pointField start(testFaces.size());
|
||||||
|
pointField end(testFaces.size());
|
||||||
|
|
||||||
|
forAll(testFaces, i)
|
||||||
{
|
{
|
||||||
if (surfaceIndex_[faceI] != -1)
|
label faceI = testFaces[i];
|
||||||
{
|
|
||||||
// Edge between owner and neighbour of face pierces a surface.
|
|
||||||
// Do closer inspection to find nearest intersection on both sides.
|
|
||||||
|
|
||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
// Cc of neighbouring cell
|
if (mesh_.isInternalFace(faceI))
|
||||||
point end
|
{
|
||||||
(
|
start[i] = cellCentres[own];
|
||||||
mesh_.isInternalFace(faceI)
|
end[i] = cellCentres[mesh_.faceNeighbour()[faceI]];
|
||||||
? cellCentres[mesh_.faceNeighbour()[faceI]]
|
}
|
||||||
: neiCc[faceI-mesh_.nInternalFaces()]
|
else
|
||||||
);
|
{
|
||||||
|
start[i] = cellCentres[own];
|
||||||
|
end[i] = neiCc[faceI-mesh_.nInternalFaces()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
label surface1, surface2;
|
|
||||||
pointIndexHit hit1, hit2;
|
// Do test for intersections
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
labelList surface1;
|
||||||
|
List<pointIndexHit> hit1;
|
||||||
|
labelList region1;
|
||||||
|
labelList surface2;
|
||||||
|
List<pointIndexHit> hit2;
|
||||||
|
labelList region2;
|
||||||
surfaces_.findNearestIntersection
|
surfaces_.findNearestIntersection
|
||||||
(
|
(
|
||||||
surfacesToBaffle,
|
surfacesToBaffle,
|
||||||
cellCentres[own],
|
start,
|
||||||
end,
|
end,
|
||||||
|
|
||||||
surface1,
|
surface1,
|
||||||
hit1,
|
hit1,
|
||||||
|
region1,
|
||||||
|
|
||||||
surface2,
|
surface2,
|
||||||
hit2
|
hit2,
|
||||||
|
region2
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hit1.hit() && hit2.hit())
|
forAll(testFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = testFaces[i];
|
||||||
|
|
||||||
|
if (hit1[i].hit() && hit2[i].hit())
|
||||||
{
|
{
|
||||||
if (str.valid())
|
if (str.valid())
|
||||||
{
|
{
|
||||||
meshTools::writeOBJ(str(), cellCentres[own]);
|
meshTools::writeOBJ(str(), start[i]);
|
||||||
vertI++;
|
vertI++;
|
||||||
meshTools::writeOBJ(str(), hit1.rawPoint());
|
meshTools::writeOBJ(str(), hit1[i].rawPoint());
|
||||||
vertI++;
|
vertI++;
|
||||||
meshTools::writeOBJ(str(), hit2.rawPoint());
|
meshTools::writeOBJ(str(), hit2[i].rawPoint());
|
||||||
vertI++;
|
vertI++;
|
||||||
meshTools::writeOBJ(str(), end);
|
meshTools::writeOBJ(str(), end[i]);
|
||||||
vertI++;
|
vertI++;
|
||||||
str()<< "l " << vertI-3 << ' ' << vertI-2 << nl;
|
str()<< "l " << vertI-3 << ' ' << vertI-2 << nl;
|
||||||
str()<< "l " << vertI-2 << ' ' << vertI-1 << nl;
|
str()<< "l " << vertI-2 << ' ' << vertI-1 << nl;
|
||||||
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Pick up the patches
|
// Pick up the patches
|
||||||
ownPatch[faceI] = globalToPatch
|
ownPatch[faceI] = globalToPatch
|
||||||
[
|
[
|
||||||
surfaces_.triangleRegion(surface1, hit1.index())
|
surfaces_.globalRegion(surface1[i], region1[i])
|
||||||
];
|
];
|
||||||
neiPatch[faceI] = globalToPatch
|
neiPatch[faceI] = globalToPatch
|
||||||
[
|
[
|
||||||
surfaces_.triangleRegion(surface2, hit2.index())
|
surfaces_.globalRegion(surface2[i], region2[i])
|
||||||
];
|
];
|
||||||
|
|
||||||
if (ownPatch[faceI] == -1 || neiPatch[faceI] == -1)
|
if (ownPatch[faceI] == -1 || neiPatch[faceI] == -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("getBafflePatches()") << abort(FatalError);
|
FatalErrorIn("getBafflePatches(..)")
|
||||||
}
|
<< "problem." << abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1203,15 +1229,20 @@ void Foam::meshRefinement::findCellZoneGeometric
|
|||||||
const labelList& faceOwner = mesh_.faceOwner();
|
const labelList& faceOwner = mesh_.faceOwner();
|
||||||
const labelList& faceNeighbour = mesh_.faceNeighbour();
|
const labelList& faceNeighbour = mesh_.faceNeighbour();
|
||||||
|
|
||||||
forAll(cellToZone, cellI)
|
// Check if cell centre is inside
|
||||||
|
labelList insideSurfaces;
|
||||||
|
surfaces_.findInside
|
||||||
|
(
|
||||||
|
closedNamedSurfaces,
|
||||||
|
cellCentres,
|
||||||
|
insideSurfaces
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(insideSurfaces, cellI)
|
||||||
{
|
{
|
||||||
if (cellToZone[cellI] == -2)
|
if (cellToZone[cellI] == -2)
|
||||||
{
|
{
|
||||||
label surfI = surfaces_.insideZone
|
label surfI = insideSurfaces[cellI];
|
||||||
(
|
|
||||||
closedNamedSurfaces,
|
|
||||||
cellCentres[cellI]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (surfI != -1)
|
if (surfI != -1)
|
||||||
{
|
{
|
||||||
@ -1223,6 +1254,32 @@ void Foam::meshRefinement::findCellZoneGeometric
|
|||||||
|
|
||||||
// Some cells with cell centres close to surface might have
|
// Some cells with cell centres close to surface might have
|
||||||
// had been put into wrong surface. Recheck with perturbed cell centre.
|
// had been put into wrong surface. Recheck with perturbed cell centre.
|
||||||
|
|
||||||
|
|
||||||
|
// 1. Collect points
|
||||||
|
|
||||||
|
// Count points to test.
|
||||||
|
label nCandidates = 0;
|
||||||
|
forAll(namedSurfaceIndex, faceI)
|
||||||
|
{
|
||||||
|
label surfI = namedSurfaceIndex[faceI];
|
||||||
|
|
||||||
|
if (surfI != -1)
|
||||||
|
{
|
||||||
|
if (mesh_.isInternalFace(faceI))
|
||||||
|
{
|
||||||
|
nCandidates += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nCandidates += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect points.
|
||||||
|
pointField candidatePoints(nCandidates);
|
||||||
|
nCandidates = 0;
|
||||||
forAll(namedSurfaceIndex, faceI)
|
forAll(namedSurfaceIndex, faceI)
|
||||||
{
|
{
|
||||||
label surfI = namedSurfaceIndex[faceI];
|
label surfI = namedSurfaceIndex[faceI];
|
||||||
@ -1236,51 +1293,62 @@ void Foam::meshRefinement::findCellZoneGeometric
|
|||||||
{
|
{
|
||||||
label nei = faceNeighbour[faceI];
|
label nei = faceNeighbour[faceI];
|
||||||
const point& neiCc = cellCentres[nei];
|
const point& neiCc = cellCentres[nei];
|
||||||
|
// Perturbed cc
|
||||||
const vector d = 1E-4*(neiCc - ownCc);
|
const vector d = 1E-4*(neiCc - ownCc);
|
||||||
|
candidatePoints[nCandidates++] = ownCc-d;
|
||||||
// Test perturbed owner
|
candidatePoints[nCandidates++] = neiCc+d;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
label ownSurfI = surfaces_.insideZone
|
const point& neiFc = mesh_.faceCentres()[faceI];
|
||||||
|
// Perturbed cc
|
||||||
|
const vector d = 1E-4*(neiFc - ownCc);
|
||||||
|
candidatePoints[nCandidates++] = ownCc-d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Test points for inside
|
||||||
|
|
||||||
|
surfaces_.findInside
|
||||||
(
|
(
|
||||||
closedNamedSurfaces,
|
closedNamedSurfaces,
|
||||||
ownCc-d
|
candidatePoints,
|
||||||
|
insideSurfaces
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Update zone information
|
||||||
|
|
||||||
|
nCandidates = 0;
|
||||||
|
forAll(namedSurfaceIndex, faceI)
|
||||||
|
{
|
||||||
|
label surfI = namedSurfaceIndex[faceI];
|
||||||
|
|
||||||
|
if (surfI != -1)
|
||||||
|
{
|
||||||
|
label own = faceOwner[faceI];
|
||||||
|
|
||||||
|
if (mesh_.isInternalFace(faceI))
|
||||||
|
{
|
||||||
|
label ownSurfI = insideSurfaces[nCandidates++];
|
||||||
if (ownSurfI != -1)
|
if (ownSurfI != -1)
|
||||||
{
|
{
|
||||||
cellToZone[own] = surfaceToCellZone[ownSurfI];
|
cellToZone[own] = surfaceToCellZone[ownSurfI];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Test perturbed neighbour
|
|
||||||
{
|
|
||||||
label neiSurfI = surfaces_.insideZone
|
|
||||||
(
|
|
||||||
closedNamedSurfaces,
|
|
||||||
neiCc+d
|
|
||||||
);
|
|
||||||
|
|
||||||
|
label neiSurfI = insideSurfaces[nCandidates++];
|
||||||
if (neiSurfI != -1)
|
if (neiSurfI != -1)
|
||||||
{
|
{
|
||||||
|
label nei = faceNeighbour[faceI];
|
||||||
|
|
||||||
cellToZone[nei] = surfaceToCellZone[neiSurfI];
|
cellToZone[nei] = surfaceToCellZone[neiSurfI];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const point& neiCc = mesh_.faceCentres()[faceI];
|
label ownSurfI = insideSurfaces[nCandidates++];
|
||||||
|
|
||||||
const vector d = 1E-4*(neiCc - ownCc);
|
|
||||||
|
|
||||||
// Test perturbed owner
|
|
||||||
{
|
|
||||||
label ownSurfI = surfaces_.insideZone
|
|
||||||
(
|
|
||||||
closedNamedSurfaces,
|
|
||||||
ownCc-d
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ownSurfI != -1)
|
if (ownSurfI != -1)
|
||||||
{
|
{
|
||||||
cellToZone[own] = surfaceToCellZone[ownSurfI];
|
cellToZone[own] = surfaceToCellZone[ownSurfI];
|
||||||
@ -1289,7 +1357,6 @@ void Foam::meshRefinement::findCellZoneGeometric
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Finds region per cell. Assumes:
|
// Finds region per cell. Assumes:
|
||||||
@ -1771,7 +1838,11 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
|
|||||||
const labelList& faceNeighbour = mesh_.faceNeighbour();
|
const labelList& faceNeighbour = mesh_.faceNeighbour();
|
||||||
|
|
||||||
// Patch for exposed faces for lack of anything sensible.
|
// Patch for exposed faces for lack of anything sensible.
|
||||||
const label defaultPatch = globalToPatch[0];
|
label defaultPatch = 0;
|
||||||
|
if (globalToPatch.size() > 0)
|
||||||
|
{
|
||||||
|
defaultPatch = globalToPatch[0];
|
||||||
|
}
|
||||||
|
|
||||||
for (label i = 0; i < nBufferLayers; i++)
|
for (label i = 0; i < nBufferLayers; i++)
|
||||||
{
|
{
|
||||||
@ -2291,7 +2362,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
|
|
||||||
isNamedSurface[surfI] = true;
|
isNamedSurface[surfI] = true;
|
||||||
|
|
||||||
Info<< "Surface : " << surfaces_[surfI].searchableSurface::name() << nl
|
Info<< "Surface : " << surfaces_.names()[surfI] << nl
|
||||||
<< " faceZone : " << faceZoneNames[surfI] << nl
|
<< " faceZone : " << faceZoneNames[surfI] << nl
|
||||||
<< " cellZone : " << cellZoneNames[surfI] << endl;
|
<< " cellZone : " << cellZoneNames[surfI] << endl;
|
||||||
}
|
}
|
||||||
@ -2329,7 +2400,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "Faces on " << surfaces_[surfI].searchableSurface::name()
|
Pout<< "Faces on " << surfaces_.names()[surfI]
|
||||||
<< " will go into faceZone " << zoneI << endl;
|
<< " will go into faceZone " << zoneI << endl;
|
||||||
}
|
}
|
||||||
surfaceToFaceZone[surfI] = zoneI;
|
surfaceToFaceZone[surfI] = zoneI;
|
||||||
@ -2387,8 +2458,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "Cells inside "
|
Pout<< "Cells inside " << surfaces_.names()[surfI]
|
||||||
<< surfaces_[surfI].searchableSurface::name()
|
|
||||||
<< " will go into cellZone " << zoneI << endl;
|
<< " will go into cellZone " << zoneI << endl;
|
||||||
}
|
}
|
||||||
surfaceToCellZone[surfI] = zoneI;
|
surfaceToCellZone[surfI] = zoneI;
|
||||||
@ -2444,78 +2514,83 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
// Note: for all internal faces? internal + coupled?
|
// Note: for all internal faces? internal + coupled?
|
||||||
// Since zonify is run after baffling the surfaceIndex_ on baffles is
|
// Since zonify is run after baffling the surfaceIndex_ on baffles is
|
||||||
// not synchronised across both baffle faces. Fortunately we don't
|
// not synchronised across both baffle faces. Fortunately we don't
|
||||||
// do zonify baffle faces anyway.
|
// do zonify baffle faces anyway (they are normal boundary faces).
|
||||||
forAll(surfaceIndex_, faceI)
|
|
||||||
{
|
|
||||||
label surfI = surfaceIndex_[faceI];
|
|
||||||
|
|
||||||
if
|
// Collect candidate faces
|
||||||
(
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
surfI != -1
|
|
||||||
&& (
|
|
||||||
mesh_.isInternalFace(faceI)
|
|
||||||
|| patches[patches.whichPatch(faceI)].coupled()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (isNamedSurface[surfI])
|
|
||||||
{
|
|
||||||
namedSurfaceIndex[faceI] = surfI;
|
|
||||||
nSurfFaces[surfI]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Test more accurately for whether intersection is at
|
|
||||||
// zoneable surface
|
|
||||||
|
|
||||||
label surface1, surface2;
|
labelList testFaces(intersectedFaces());
|
||||||
pointIndexHit hit1, hit2;
|
|
||||||
|
// Collect segments
|
||||||
|
// ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
pointField start(testFaces.size());
|
||||||
|
pointField end(testFaces.size());
|
||||||
|
|
||||||
|
forAll(testFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = testFaces[i];
|
||||||
|
|
||||||
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
if (mesh_.isInternalFace(faceI))
|
if (mesh_.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
surfaces_.findNearestIntersection
|
start[i] = cellCentres[own];
|
||||||
(
|
end[i] = cellCentres[mesh_.faceNeighbour()[faceI]];
|
||||||
namedSurfaces,
|
|
||||||
cellCentres[faceOwner[faceI]],
|
|
||||||
cellCentres[faceNeighbour[faceI]],
|
|
||||||
|
|
||||||
surface1,
|
|
||||||
hit1,
|
|
||||||
surface2,
|
|
||||||
hit2
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
start[i] = cellCentres[own];
|
||||||
|
end[i] = neiCc[faceI-mesh_.nInternalFaces()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Do test for intersections
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Note that we intersect all intersected faces again. Could reuse
|
||||||
|
// the information already in surfaceIndex_.
|
||||||
|
|
||||||
|
labelList surface1;
|
||||||
|
labelList surface2;
|
||||||
|
{
|
||||||
|
List<pointIndexHit> hit1;
|
||||||
|
labelList region1;
|
||||||
|
List<pointIndexHit> hit2;
|
||||||
|
labelList region2;
|
||||||
surfaces_.findNearestIntersection
|
surfaces_.findNearestIntersection
|
||||||
(
|
(
|
||||||
namedSurfaces,
|
namedSurfaces,
|
||||||
cellCentres[faceOwner[faceI]],
|
start,
|
||||||
neiCc[faceI-mesh_.nInternalFaces()],
|
end,
|
||||||
|
|
||||||
surface1,
|
surface1,
|
||||||
hit1,
|
hit1,
|
||||||
|
region1,
|
||||||
surface2,
|
surface2,
|
||||||
hit2
|
hit2,
|
||||||
|
region2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hit1.hit())
|
forAll(testFaces, i)
|
||||||
{
|
{
|
||||||
// If both hit should probably choose nearest. For
|
label faceI = testFaces[i];
|
||||||
// later.
|
|
||||||
namedSurfaceIndex[faceI] = surface1;
|
if (surface1[i] != -1)
|
||||||
nSurfFaces[surface1]++;
|
|
||||||
}
|
|
||||||
else if (hit2.hit())
|
|
||||||
{
|
{
|
||||||
namedSurfaceIndex[faceI] = surface2;
|
// If both hit should probably choose nearest. For later.
|
||||||
nSurfFaces[surface2]++;
|
namedSurfaceIndex[faceI] = surface1[i];
|
||||||
}
|
nSurfFaces[surface1[i]]++;
|
||||||
}
|
}
|
||||||
|
else if (surface2[i] != -1)
|
||||||
|
{
|
||||||
|
namedSurfaceIndex[faceI] = surface2[i];
|
||||||
|
nSurfFaces[surface2[i]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// surfaceIndex migh have different surfaces on both sides if
|
// surfaceIndex migh have different surfaces on both sides if
|
||||||
// there happen to be a (obviously thin) surface with different
|
// there happen to be a (obviously thin) surface with different
|
||||||
// regions between the cell centres. If one is on a named surface
|
// regions between the cell centres. If one is on a named surface
|
||||||
@ -2534,7 +2609,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
forAll(nSurfFaces, surfI)
|
forAll(nSurfFaces, surfI)
|
||||||
{
|
{
|
||||||
Pout<< "Surface:"
|
Pout<< "Surface:"
|
||||||
<< surfaces_[surfI].searchableSurface::name()
|
<< surfaces_.names()[surfI]
|
||||||
<< " nZoneFaces:" << nSurfFaces[surfI] << nl;
|
<< " nZoneFaces:" << nSurfFaces[surfI] << nl;
|
||||||
}
|
}
|
||||||
Pout<< endl;
|
Pout<< endl;
|
||||||
@ -2609,20 +2684,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
// Put the cells into the correct zone
|
// Put the cells into the correct zone
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
labelList closedNamedSurfaces(namedSurfaces.size());
|
// Closed surfaces with cellZone specified.
|
||||||
label nClosed = 0;
|
labelList closedNamedSurfaces(surfaces_.getClosedNamedSurfaces());
|
||||||
|
|
||||||
forAll(namedSurfaces, i)
|
|
||||||
{
|
|
||||||
label surfI = namedSurfaces[i];
|
|
||||||
|
|
||||||
if (surfaces_.closed()[surfI])
|
|
||||||
{
|
|
||||||
closedNamedSurfaces[nClosed++] = surfI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedNamedSurfaces.setSize(nClosed);
|
|
||||||
|
|
||||||
|
|
||||||
// Zone per cell:
|
// Zone per cell:
|
||||||
// -2 : unset
|
// -2 : unset
|
||||||
@ -2704,13 +2767,4 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -30,15 +30,9 @@ License
|
|||||||
#include "removePoints.H"
|
#include "removePoints.H"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Merge faces that are in-line.
|
// Merge faces that are in-line.
|
||||||
@ -244,13 +238,4 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::mergeEdges
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -29,6 +29,7 @@ License
|
|||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "refinementSurfaces.H"
|
#include "refinementSurfaces.H"
|
||||||
|
#include "shellSurfaces.H"
|
||||||
#include "faceSet.H"
|
#include "faceSet.H"
|
||||||
#include "decompositionMethod.H"
|
#include "decompositionMethod.H"
|
||||||
#include "fvMeshDistribute.H"
|
#include "fvMeshDistribute.H"
|
||||||
@ -37,9 +38,6 @@ License
|
|||||||
#include "featureEdgeMesh.H"
|
#include "featureEdgeMesh.H"
|
||||||
#include "Cloud.H"
|
#include "Cloud.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
// Get faces (on the new mesh) that have in some way been affected by the
|
// Get faces (on the new mesh) that have in some way been affected by the
|
||||||
@ -369,7 +367,7 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
|
|||||||
{
|
{
|
||||||
label edgeI = pEdges[i];
|
label edgeI = pEdges[i];
|
||||||
|
|
||||||
if (featureEdgeVisited[featI].get(edgeI) == 0)
|
if (featureEdgeVisited[featI].set(edgeI, 1u))
|
||||||
{
|
{
|
||||||
// Unvisited edge. Make the particle go to the other point
|
// Unvisited edge. Make the particle go to the other point
|
||||||
// on the edge.
|
// on the edge.
|
||||||
@ -377,7 +375,6 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
|
|||||||
const edge& e = featureMesh.edges()[edgeI];
|
const edge& e = featureMesh.edges()[edgeI];
|
||||||
label otherPointI = e.otherVertex(pointI);
|
label otherPointI = e.otherVertex(pointI);
|
||||||
|
|
||||||
featureEdgeVisited[featI].set(edgeI, 1u);
|
|
||||||
tp.end() = featureMesh.points()[otherPointI];
|
tp.end() = featureMesh.points()[otherPointI];
|
||||||
tp.j() = otherPointI;
|
tp.j() = otherPointI;
|
||||||
keepParticle = true;
|
keepParticle = true;
|
||||||
@ -438,6 +435,15 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
returnReduce(nRefine, sumOp<label>())
|
||||||
|
> returnReduce(nAllowRefine, sumOp<label>())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Reached refinement limit." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,9 +451,6 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
|
|||||||
// Mark cells for non-surface intersection based refinement.
|
// Mark cells for non-surface intersection based refinement.
|
||||||
Foam::label Foam::meshRefinement::markInternalRefinement
|
Foam::label Foam::meshRefinement::markInternalRefinement
|
||||||
(
|
(
|
||||||
const PtrList<searchableSurface>& shells,
|
|
||||||
const labelList& shellLevels,
|
|
||||||
const boolList& shellRefineInside,
|
|
||||||
const label nAllowRefine,
|
const label nAllowRefine,
|
||||||
|
|
||||||
labelList& refineCell,
|
labelList& refineCell,
|
||||||
@ -457,50 +460,39 @@ Foam::label Foam::meshRefinement::markInternalRefinement
|
|||||||
const labelList& cellLevel = meshCutter_.cellLevel();
|
const labelList& cellLevel = meshCutter_.cellLevel();
|
||||||
const pointField& cellCentres = mesh_.cellCentres();
|
const pointField& cellCentres = mesh_.cellCentres();
|
||||||
|
|
||||||
|
|
||||||
label oldNRefine = nRefine;
|
label oldNRefine = nRefine;
|
||||||
|
|
||||||
// Number of cells marked for refinement per shell.
|
// Collect cells to test
|
||||||
labelList nCellsPerShell(shells.size(), 0);
|
pointField testCc(cellLevel.size()-nRefine);
|
||||||
|
labelList testLevels(cellLevel.size()-nRefine);
|
||||||
|
label testI = 0;
|
||||||
|
|
||||||
forAll(cellLevel, cellI)
|
forAll(cellLevel, cellI)
|
||||||
{
|
{
|
||||||
if (refineCell[cellI] == -1)
|
if (refineCell[cellI] == -1)
|
||||||
{
|
{
|
||||||
// Cell not marked for refinement. Check if inside any shell
|
testCc[testI] = cellCentres[cellI];
|
||||||
// with higher refinement level than cell currently has.
|
testLevels[testI] = cellLevel[cellI];
|
||||||
|
testI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool reachedLimit = false;
|
// Do test to see whether cells is inside/outside shell with higher level
|
||||||
|
labelList maxLevel;
|
||||||
|
shells_.findHigherLevel(testCc, testLevels, maxLevel);
|
||||||
|
|
||||||
forAll(shells, shellI)
|
// Mark for refinement. Note that we didn't store the original cellID so
|
||||||
|
// now just reloop in same order.
|
||||||
|
testI = 0;
|
||||||
|
forAll(cellLevel, cellI)
|
||||||
{
|
{
|
||||||
// Cached inside-outside from tree
|
if (refineCell[cellI] == -1)
|
||||||
searchableSurface::volumeType t =
|
|
||||||
shells[shellI].getVolumeType(cellCentres[cellI]);
|
|
||||||
|
|
||||||
//// Uncached inside-outside from treeData
|
|
||||||
//label t = shells[shellI].shapes().getVolumeType
|
|
||||||
// (
|
|
||||||
// shells[shellI],
|
|
||||||
// cellCentres[cellI]
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Which side of shell is to be refined
|
|
||||||
searchableSurface::volumeType refSide =
|
|
||||||
(
|
|
||||||
shellRefineInside[shellI]
|
|
||||||
? searchableSurface::INSIDE
|
|
||||||
: searchableSurface::OUTSIDE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (t == refSide && cellLevel[cellI] < shellLevels[shellI])
|
|
||||||
{
|
{
|
||||||
// Cell is inside shell with higher refinement level. Mark
|
if (maxLevel[testI] > testLevels[testI])
|
||||||
// for refinement.
|
{
|
||||||
|
bool reachedLimit = !markForRefine
|
||||||
reachedLimit = !markForRefine
|
|
||||||
(
|
(
|
||||||
labelMax,
|
maxLevel[testI], // mark with any positive value
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
refineCell[cellI],
|
refineCell[cellI],
|
||||||
nRefine
|
nRefine
|
||||||
@ -516,35 +508,65 @@ Foam::label Foam::meshRefinement::markInternalRefinement
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Cell successfully marked for refinement
|
|
||||||
nCellsPerShell[shellI]++;
|
|
||||||
}
|
}
|
||||||
|
testI++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reachedLimit)
|
if
|
||||||
|
(
|
||||||
|
returnReduce(nRefine, sumOp<label>())
|
||||||
|
> returnReduce(nAllowRefine, sumOp<label>())
|
||||||
|
)
|
||||||
{
|
{
|
||||||
break;
|
Info<< "Reached refinement limit." << endl;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::listCombineGather(nCellsPerShell, plusEqOp<label>());
|
|
||||||
Pstream::listCombineScatter(nCellsPerShell);
|
|
||||||
|
|
||||||
Info<< "Marked for refinement per shell :" << endl;
|
|
||||||
forAll(nCellsPerShell, shellI)
|
|
||||||
{
|
|
||||||
Info<< " shell:" << shellI << " nCells:" << nCellsPerShell[shellI]
|
|
||||||
<< nl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Collect faces that are intersected and whose neighbours aren't yet marked
|
||||||
|
// for refinement.
|
||||||
|
Foam::labelList Foam::meshRefinement::getRefineCandidateFaces
|
||||||
|
(
|
||||||
|
const labelList& refineCell
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
labelList testFaces(mesh_.nCells());
|
||||||
|
|
||||||
|
label nTest = 0;
|
||||||
|
|
||||||
|
forAll(surfaceIndex_, faceI)
|
||||||
|
{
|
||||||
|
if (surfaceIndex_[faceI] != -1)
|
||||||
|
{
|
||||||
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
|
if (mesh_.isInternalFace(faceI))
|
||||||
|
{
|
||||||
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
|
if (refineCell[own] == -1 || refineCell[nei] == -1)
|
||||||
|
{
|
||||||
|
testFaces[nTest++] = faceI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (refineCell[own] == -1)
|
||||||
|
{
|
||||||
|
testFaces[nTest++] = faceI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testFaces.setSize(nTest);
|
||||||
|
|
||||||
|
return testFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mark cells for surface intersection based refinement.
|
// Mark cells for surface intersection based refinement.
|
||||||
Foam::label Foam::meshRefinement::markSurfaceRefinement
|
Foam::label Foam::meshRefinement::markSurfaceRefinement
|
||||||
(
|
(
|
||||||
@ -564,46 +586,79 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
|
|||||||
// Use cached surfaceIndex_ to detect if any intersection. If so
|
// Use cached surfaceIndex_ to detect if any intersection. If so
|
||||||
// re-intersect to determine level wanted.
|
// re-intersect to determine level wanted.
|
||||||
|
|
||||||
label faceI;
|
// Collect candidate faces
|
||||||
for (faceI = 0; faceI < surfaceIndex_.size(); faceI++)
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
{
|
|
||||||
if (surfaceIndex_[faceI] != -1)
|
labelList testFaces(getRefineCandidateFaces(refineCell));
|
||||||
|
|
||||||
|
// Collect segments
|
||||||
|
// ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
pointField start(testFaces.size());
|
||||||
|
pointField end(testFaces.size());
|
||||||
|
labelList minLevel(testFaces.size());
|
||||||
|
|
||||||
|
forAll(testFaces, i)
|
||||||
{
|
{
|
||||||
|
label faceI = testFaces[i];
|
||||||
|
|
||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
if (mesh_.isInternalFace(faceI))
|
if (mesh_.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
// Test if not both sides already marked for refinement.
|
start[i] = cellCentres[own];
|
||||||
if (refineCell[own] == -1 || refineCell[nei] == -1)
|
end[i] = cellCentres[nei];
|
||||||
|
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
pointIndexHit hit;
|
label bFaceI = faceI - mesh_.nInternalFaces();
|
||||||
label surfI = surfaces_.findHigherIntersection
|
|
||||||
|
start[i] = cellCentres[own];
|
||||||
|
end[i] = neiCc[bFaceI];
|
||||||
|
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Do test for higher intersections
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelList surfaceHit;
|
||||||
|
labelList surfaceMinLevel;
|
||||||
|
surfaces_.findHigherIntersection
|
||||||
(
|
(
|
||||||
cellCentres[own],
|
start,
|
||||||
cellCentres[nei],
|
end,
|
||||||
min(cellLevel[own], cellLevel[nei]),
|
minLevel,
|
||||||
hit
|
|
||||||
|
surfaceHit,
|
||||||
|
surfaceMinLevel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Mark cells for refinement
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
forAll(testFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = testFaces[i];
|
||||||
|
|
||||||
|
label surfI = surfaceHit[i];
|
||||||
|
|
||||||
if (surfI != -1)
|
if (surfI != -1)
|
||||||
{
|
{
|
||||||
// Found intersection with surface with higher wanted
|
// Found intersection with surface with higher wanted
|
||||||
// refinement. Mark cell for refining.
|
// refinement. Check if the level field on that surface
|
||||||
// Note: could do optimization here and only refine the
|
// specifies an even higher level. Note:this is weird. Should
|
||||||
// side of the face the intersection actually goes
|
// do the check with the surfaceMinLevel whilst intersecting the
|
||||||
// through.
|
// surfaces?
|
||||||
// This would require us though to find all
|
|
||||||
// intersections
|
|
||||||
// first instead of now only the first higher one. Also
|
|
||||||
// would need the exact intersection of face with cc-cc
|
|
||||||
// connection?
|
|
||||||
|
|
||||||
label surfaceMinLevel =
|
label own = mesh_.faceOwner()[faceI];
|
||||||
surfaces_.minLevelField(surfI)[hit.index()];
|
|
||||||
|
|
||||||
if (surfaceMinLevel > cellLevel[own])
|
if (surfaceMinLevel[i] > cellLevel[own])
|
||||||
{
|
{
|
||||||
// Owner needs refining
|
// Owner needs refining
|
||||||
if
|
if
|
||||||
@ -621,7 +676,10 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surfaceMinLevel > cellLevel[nei])
|
if (mesh_.isInternalFace(faceI))
|
||||||
|
{
|
||||||
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
if (surfaceMinLevel[i] > cellLevel[nei])
|
||||||
{
|
{
|
||||||
// Neighbour needs refining
|
// Neighbour needs refining
|
||||||
if
|
if
|
||||||
@ -641,79 +699,36 @@ Foam::label Foam::meshRefinement::markSurfaceRefinement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (refineCell[own] == -1)
|
|
||||||
{
|
|
||||||
// boundary face with unmarked owner
|
|
||||||
|
|
||||||
label bFaceI = faceI - mesh_.nInternalFaces();
|
|
||||||
|
|
||||||
pointIndexHit hit;
|
|
||||||
label surfI = surfaces_.findHigherIntersection
|
|
||||||
(
|
|
||||||
cellCentres[own],
|
|
||||||
neiCc[bFaceI],
|
|
||||||
min(cellLevel[own], neiLevel[bFaceI]),
|
|
||||||
hit
|
|
||||||
);
|
|
||||||
|
|
||||||
if (surfI != -1)
|
|
||||||
{
|
|
||||||
// Make sure it is my side that wants refinement.
|
|
||||||
label surfaceMinLevel =
|
|
||||||
surfaces_.minLevelField(surfI)[hit.index()];
|
|
||||||
|
|
||||||
if (surfaceMinLevel > cellLevel[own])
|
|
||||||
{
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
!markForRefine
|
returnReduce(nRefine, sumOp<label>())
|
||||||
(
|
> returnReduce(nAllowRefine, sumOp<label>())
|
||||||
surfI,
|
|
||||||
nAllowRefine,
|
|
||||||
refineCell[own],
|
|
||||||
nRefine
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
break;
|
Info<< "Reached refinement limit." << endl;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (faceI < surfaceIndex_.size())
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Stopped refining since reaching my cell limit of "
|
|
||||||
<< mesh_.nCells()+7*nRefine << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Given intersection of (face of) cell by newSurfI, newTriI, check whether
|
// Checks if multiple intersections of a cell (by a surface with a higher
|
||||||
// it needs to be refined. Updates maxCellSurf, maxCellTri and
|
// max than the cell level) and if so if the normals at these intersections
|
||||||
// refineCell,nRefine if it decides to refine the cell. Returns false
|
// make a large angle.
|
||||||
// if the nRefine limit has been reached, true otherwise.
|
// Returns false if the nRefine limit has been reached, true otherwise.
|
||||||
bool Foam::meshRefinement::checkCurvature
|
bool Foam::meshRefinement::checkCurvature
|
||||||
(
|
(
|
||||||
const labelList& globalToPatch,
|
|
||||||
const scalar curvature,
|
const scalar curvature,
|
||||||
const bool markDifferingRegions,
|
|
||||||
const label nAllowRefine,
|
const label nAllowRefine,
|
||||||
|
|
||||||
const label newSurfI,
|
const label surfaceLevel, // current intersection max level
|
||||||
const label newTriI,
|
const vector& surfaceNormal,// current intersection normal
|
||||||
|
|
||||||
const label cellI,
|
const label cellI,
|
||||||
|
|
||||||
label& maxCellSurfI,
|
label& cellMaxLevel, // cached max surface level for this cell
|
||||||
label& maxCellTriI,
|
vector& cellMaxNormal, // cached surface normal for this cell
|
||||||
|
|
||||||
labelList& refineCell,
|
labelList& refineCell,
|
||||||
label& nRefine
|
label& nRefine
|
||||||
@ -721,59 +736,35 @@ bool Foam::meshRefinement::checkCurvature
|
|||||||
{
|
{
|
||||||
const labelList& cellLevel = meshCutter_.cellLevel();
|
const labelList& cellLevel = meshCutter_.cellLevel();
|
||||||
|
|
||||||
if (maxCellSurfI == -1)
|
// Test if surface applicable
|
||||||
|
if (surfaceLevel > cellLevel[cellI])
|
||||||
|
{
|
||||||
|
if (cellMaxLevel == -1)
|
||||||
{
|
{
|
||||||
// First visit of cell. Store
|
// First visit of cell. Store
|
||||||
maxCellSurfI = newSurfI;
|
cellMaxLevel = surfaceLevel;
|
||||||
maxCellTriI = newTriI;
|
cellMaxNormal = surfaceNormal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Second or more visit.
|
// Second or more visit. Check curvature.
|
||||||
label cellRegion = surfaces_.triangleRegion(maxCellSurfI, maxCellTriI);
|
if ((cellMaxNormal & surfaceNormal) < curvature)
|
||||||
label newRegion = surfaces_.triangleRegion(newSurfI, newTriI);
|
|
||||||
|
|
||||||
// Update max
|
|
||||||
label maxLevel = surfaces_.maxLevel()[cellRegion];
|
|
||||||
|
|
||||||
if (surfaces_.maxLevel()[newRegion] > maxLevel)
|
|
||||||
{
|
|
||||||
maxCellSurfI = newSurfI;
|
|
||||||
maxCellTriI = newTriI;
|
|
||||||
maxLevel = surfaces_.maxLevel()[newRegion];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check if cell is candidate for refinement
|
|
||||||
if (cellLevel[cellI] < maxLevel)
|
|
||||||
{
|
|
||||||
// Test 1: different regions
|
|
||||||
if (markDifferingRegions && cellRegion != newRegion)
|
|
||||||
{
|
{
|
||||||
return markForRefine
|
return markForRefine
|
||||||
(
|
(
|
||||||
globalToPatch[newRegion], // mark with non-neg number.
|
surfaceLevel, // mark with any non-neg number.
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
refineCell[cellI],
|
refineCell[cellI],
|
||||||
nRefine
|
nRefine
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test 2: different normals
|
// Set normal to that of highest surface. Not really necessary
|
||||||
const vector& cellN =
|
// over here but we reuse cellMax info when doing coupled faces.
|
||||||
surfaces_[maxCellSurfI].faceNormals()[maxCellTriI];
|
if (surfaceLevel > cellMaxLevel)
|
||||||
const vector& newN =
|
|
||||||
surfaces_[newSurfI].faceNormals()[newTriI];
|
|
||||||
|
|
||||||
if ((cellN & newN) < curvature)
|
|
||||||
{
|
{
|
||||||
return markForRefine
|
cellMaxLevel = surfaceLevel;
|
||||||
(
|
cellMaxNormal = surfaceNormal;
|
||||||
globalToPatch[newRegion], // mark with non-neg number.
|
|
||||||
nAllowRefine,
|
|
||||||
refineCell[cellI],
|
|
||||||
nRefine
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -786,9 +777,7 @@ bool Foam::meshRefinement::checkCurvature
|
|||||||
// Mark cells for surface curvature based refinement.
|
// Mark cells for surface curvature based refinement.
|
||||||
Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||||
(
|
(
|
||||||
const labelList& globalToPatch,
|
|
||||||
const scalar curvature,
|
const scalar curvature,
|
||||||
const bool markDifferingRegions,
|
|
||||||
const label nAllowRefine,
|
const label nAllowRefine,
|
||||||
const labelList& neiLevel,
|
const labelList& neiLevel,
|
||||||
const pointField& neiCc,
|
const pointField& neiCc,
|
||||||
@ -802,107 +791,117 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
|
|
||||||
label oldNRefine = nRefine;
|
label oldNRefine = nRefine;
|
||||||
|
|
||||||
// 1. Any cell on more than one surface gets refined (if its current level
|
// 1. local test: any cell on more than one surface gets refined
|
||||||
// is <= max of the surface max level)
|
// (if its current level is < max of the surface max level)
|
||||||
|
|
||||||
// 2. Any cell on only one surface with a neighbour on a different surface
|
// 2. 'global' test: any cell on only one surface with a neighbour
|
||||||
// gets refined (if its current level etc.)
|
// on a different surface gets refined (if its current level etc.)
|
||||||
|
|
||||||
|
|
||||||
|
// Collect candidate faces (i.e. intersecting any surface and
|
||||||
|
// owner/neighbour not yet refined.
|
||||||
|
labelList testFaces(getRefineCandidateFaces(refineCell));
|
||||||
|
|
||||||
// Index of surface with the max maxLevel and the actual triangle
|
// Collect segments
|
||||||
// on the surface. We store these and not e.g. global region so we can get
|
pointField start(testFaces.size());
|
||||||
// at:
|
pointField end(testFaces.size());
|
||||||
// - global region
|
labelList minLevel(testFaces.size());
|
||||||
// - global patch
|
|
||||||
// - face normal
|
|
||||||
labelList cellMaxSurface(mesh_.nCells(), -1);
|
|
||||||
labelList cellMaxTriangle(mesh_.nCells(), -1);
|
|
||||||
|
|
||||||
// 1.
|
forAll(testFaces, i)
|
||||||
|
|
||||||
forAll(surfaceIndex_, faceI)
|
|
||||||
{
|
|
||||||
if (surfaceIndex_[faceI] != -1)
|
|
||||||
{
|
{
|
||||||
|
label faceI = testFaces[i];
|
||||||
|
|
||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
// There is an intersection. Do more accurate test to get all
|
|
||||||
// intersections
|
|
||||||
labelList surfaceIndices;
|
|
||||||
List<pointIndexHit> hits;
|
|
||||||
|
|
||||||
if (mesh_.isInternalFace(faceI))
|
if (mesh_.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
surfaces_.findAllIntersections
|
start[i] = cellCentres[own];
|
||||||
(
|
end[i] = cellCentres[nei];
|
||||||
cellCentres[own],
|
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
|
||||||
cellCentres[nei],
|
|
||||||
surfaceIndices,
|
|
||||||
hits
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
label bFaceI = faceI - mesh_.nInternalFaces();
|
label bFaceI = faceI - mesh_.nInternalFaces();
|
||||||
|
|
||||||
surfaces_.findAllIntersections
|
start[i] = cellCentres[own];
|
||||||
(
|
end[i] = neiCc[bFaceI];
|
||||||
cellCentres[own],
|
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
|
||||||
neiCc[bFaceI],
|
}
|
||||||
surfaceIndices,
|
|
||||||
hits
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test for all intersections (with surfaces of higher max level than
|
||||||
|
// minLevel) and cache per cell the max surface level and the local normal
|
||||||
|
// on that surface.
|
||||||
|
labelList cellMaxLevel(mesh_.nCells(), -1);
|
||||||
|
vectorField cellMaxNormal(mesh_.nCells());
|
||||||
|
|
||||||
// See if intersection adds any new information to the owner or
|
|
||||||
// neighbour cell.
|
|
||||||
|
|
||||||
forAll(surfaceIndices, i)
|
|
||||||
{
|
{
|
||||||
label surfI = surfaceIndices[i];
|
// Per segment the normals of the surfaces
|
||||||
label triI = hits[i].index();
|
List<vectorList> surfaceNormal;
|
||||||
|
// Per segment the list of levels of the surfaces
|
||||||
|
labelListList surfaceLevel;
|
||||||
|
|
||||||
|
surfaces_.findAllHigherIntersections
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
minLevel, // max level of surface has to be bigger
|
||||||
|
// than min level of neighbouring cells
|
||||||
|
surfaceNormal,
|
||||||
|
surfaceLevel
|
||||||
|
);
|
||||||
|
// Clear out unnecessary data
|
||||||
|
start.clear();
|
||||||
|
end.clear();
|
||||||
|
minLevel.clear();
|
||||||
|
|
||||||
|
// Extract per cell information on the surface with the highest max
|
||||||
|
forAll(testFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = testFaces[i];
|
||||||
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
|
const vectorList& fNormals = surfaceNormal[i];
|
||||||
|
const labelList& fLevels = surfaceLevel[i];
|
||||||
|
|
||||||
|
forAll(fLevels, hitI)
|
||||||
|
{
|
||||||
checkCurvature
|
checkCurvature
|
||||||
(
|
(
|
||||||
globalToPatch,
|
|
||||||
curvature,
|
curvature,
|
||||||
markDifferingRegions,
|
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
|
|
||||||
surfI,
|
fLevels[hitI],
|
||||||
triI,
|
fNormals[hitI],
|
||||||
|
|
||||||
own,
|
own,
|
||||||
|
cellMaxLevel[own],
|
||||||
cellMaxSurface[own],
|
cellMaxNormal[own],
|
||||||
cellMaxTriangle[own],
|
|
||||||
|
|
||||||
refineCell,
|
refineCell,
|
||||||
nRefine
|
nRefine
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (mesh_.isInternalFace(faceI))
|
if (mesh_.isInternalFace(faceI))
|
||||||
{
|
{
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
|
forAll(fLevels, hitI)
|
||||||
|
{
|
||||||
checkCurvature
|
checkCurvature
|
||||||
(
|
(
|
||||||
globalToPatch,
|
|
||||||
curvature,
|
curvature,
|
||||||
markDifferingRegions,
|
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
|
|
||||||
surfI,
|
fLevels[hitI],
|
||||||
triI,
|
fNormals[hitI],
|
||||||
|
|
||||||
nei,
|
nei,
|
||||||
|
cellMaxLevel[nei],
|
||||||
cellMaxSurface[nei],
|
cellMaxNormal[nei],
|
||||||
cellMaxTriangle[nei],
|
|
||||||
|
|
||||||
refineCell,
|
refineCell,
|
||||||
nRefine
|
nRefine
|
||||||
@ -910,93 +909,46 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nRefine > nAllowRefine)
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Stopped refining since reaching my cell limit of "
|
|
||||||
<< mesh_.nCells()+7*nRefine << endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Find out a measure of surface curvature and region edges.
|
// 2. Find out a measure of surface curvature and region edges.
|
||||||
// Send over surface region and surface normal to neighbour cell.
|
// Send over surface region and surface normal to neighbour cell.
|
||||||
|
|
||||||
// global region
|
labelList neiBndMaxLevel(mesh_.nFaces()-mesh_.nInternalFaces());
|
||||||
labelList ownRegion(mesh_.nFaces(), -1);
|
vectorField neiBndMaxNormal(mesh_.nFaces()-mesh_.nInternalFaces());
|
||||||
labelList neiRegion(mesh_.nFaces(), -1);
|
|
||||||
// local normal at hit
|
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
|
||||||
vectorField ownNormal(mesh_.nFaces(), vector::zero);
|
{
|
||||||
vectorField neiNormal(mesh_.nFaces(), vector::zero);
|
label bFaceI = faceI-mesh_.nInternalFaces();
|
||||||
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
|
neiBndMaxLevel[bFaceI] = cellMaxLevel[own];
|
||||||
|
neiBndMaxNormal[bFaceI] = cellMaxNormal[own];
|
||||||
|
}
|
||||||
|
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel, false);
|
||||||
|
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal, false);
|
||||||
|
|
||||||
|
// Loop over all faces. Could only be checkFaces.. except if they're coupled
|
||||||
|
|
||||||
// Internal faces
|
// Internal faces
|
||||||
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
||||||
{
|
{
|
||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
if (cellMaxSurface[own] != -1)
|
|
||||||
{
|
|
||||||
label surfI = cellMaxSurface[own];
|
|
||||||
label triI = cellMaxTriangle[own];
|
|
||||||
|
|
||||||
ownRegion[faceI] = surfaces_.triangleRegion(surfI, triI);
|
|
||||||
ownNormal[faceI] = surfaces_[surfI].faceNormals()[triI];
|
|
||||||
}
|
|
||||||
|
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
if (cellMaxSurface[nei] != -1)
|
if (cellMaxLevel[own] != -1 && cellMaxLevel[nei] != -1)
|
||||||
{
|
{
|
||||||
label surfI = cellMaxSurface[nei];
|
// Have valid data on both sides. Check curvature.
|
||||||
label triI = cellMaxTriangle[nei];
|
if ((cellMaxNormal[own] & cellMaxNormal[nei]) < curvature)
|
||||||
|
|
||||||
neiRegion[faceI] = surfaces_.triangleRegion(surfI, triI);
|
|
||||||
neiNormal[faceI] = surfaces_[surfI].faceNormals()[triI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Boundary faces
|
|
||||||
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
|
|
||||||
{
|
{
|
||||||
label own = mesh_.faceOwner()[faceI];
|
// See which side to refine
|
||||||
|
if (cellLevel[own] < cellMaxLevel[own])
|
||||||
if (cellMaxSurface[own] != -1)
|
|
||||||
{
|
|
||||||
label surfI = cellMaxSurface[own];
|
|
||||||
label triI = cellMaxTriangle[own];
|
|
||||||
|
|
||||||
ownRegion[faceI] = surfaces_.triangleRegion(surfI, triI);
|
|
||||||
ownNormal[faceI] = surfaces_[surfI].faceNormals()[triI];
|
|
||||||
|
|
||||||
neiRegion[faceI] = ownRegion[faceI];
|
|
||||||
neiNormal[faceI] = ownNormal[faceI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTools::swapFaceList(mesh_, neiRegion, false);
|
|
||||||
syncTools::swapFaceList(mesh_, neiNormal, false);
|
|
||||||
|
|
||||||
for (label faceI = 0; faceI < mesh_.nFaces(); faceI++)
|
|
||||||
{
|
|
||||||
if (ownRegion[faceI] != -1 && neiRegion[faceI] != -1)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
(markDifferingRegions && (ownRegion[faceI] != neiRegion[faceI]))
|
|
||||||
|| ((ownNormal[faceI] & neiNormal[faceI]) < curvature)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
label own = mesh_.faceOwner()[faceI];
|
|
||||||
|
|
||||||
if (cellLevel[own] < surfaces_.maxLevel()[ownRegion[faceI]])
|
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
!markForRefine
|
!markForRefine
|
||||||
(
|
(
|
||||||
globalToPatch[ownRegion[faceI]],
|
cellMaxLevel[own],
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
refineCell[own],
|
refineCell[own],
|
||||||
nRefine
|
nRefine
|
||||||
@ -1011,22 +963,16 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh_.isInternalFace(faceI))
|
if (cellLevel[nei] < cellMaxLevel[nei])
|
||||||
{
|
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
|
||||||
|
|
||||||
if (cellLevel[nei] < surfaces_.maxLevel()[neiRegion[faceI]])
|
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
!markForRefine
|
!markForRefine
|
||||||
(
|
(
|
||||||
globalToPatch[neiRegion[faceI]],
|
cellMaxLevel[nei],
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
|
|
||||||
refineCell[nei],
|
refineCell[nei],
|
||||||
nRefine
|
nRefine
|
||||||
)
|
)
|
||||||
@ -1044,13 +990,50 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Boundary faces
|
||||||
|
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
|
||||||
|
{
|
||||||
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
label bFaceI = faceI - mesh_.nInternalFaces();
|
||||||
|
|
||||||
|
if (cellLevel[own] < cellMaxLevel[own] && neiBndMaxLevel[bFaceI] != -1)
|
||||||
|
{
|
||||||
|
// Have valid data on both sides. Check curvature.
|
||||||
|
if ((cellMaxNormal[own] & neiBndMaxNormal[bFaceI]) < curvature)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!markForRefine
|
||||||
|
(
|
||||||
|
cellMaxLevel[own],
|
||||||
|
nAllowRefine,
|
||||||
|
refineCell[own],
|
||||||
|
nRefine
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "Stopped refining since reaching my cell"
|
||||||
|
<< " limit of " << mesh_.nCells()+7*nRefine
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
returnReduce(nRefine, sumOp<label>())
|
||||||
|
> returnReduce(nAllowRefine, sumOp<label>())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Reached refinement limit." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
||||||
label totNRefined = returnReduce(totNRefined, sumOp<label>());
|
|
||||||
|
|
||||||
return totNRefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1064,16 +1047,11 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
Foam::labelList Foam::meshRefinement::refineCandidates
|
Foam::labelList Foam::meshRefinement::refineCandidates
|
||||||
(
|
(
|
||||||
const point& keepPoint,
|
const point& keepPoint,
|
||||||
const labelList& globalToPatch,
|
|
||||||
const scalar curvature,
|
const scalar curvature,
|
||||||
|
|
||||||
const PtrList<featureEdgeMesh>& featureMeshes,
|
const PtrList<featureEdgeMesh>& featureMeshes,
|
||||||
const labelList& featureLevels,
|
const labelList& featureLevels,
|
||||||
|
|
||||||
const PtrList<searchableSurface>& shells,
|
|
||||||
const labelList& shellLevels,
|
|
||||||
const boolList& shellRefineInside,
|
|
||||||
|
|
||||||
const bool featureRefinement,
|
const bool featureRefinement,
|
||||||
const bool internalRefinement,
|
const bool internalRefinement,
|
||||||
const bool surfaceRefinement,
|
const bool surfaceRefinement,
|
||||||
@ -1086,7 +1064,12 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
|||||||
|
|
||||||
labelList cellsToRefine;
|
labelList cellsToRefine;
|
||||||
|
|
||||||
if (totNCells < maxGlobalCells)
|
if (totNCells >= maxGlobalCells)
|
||||||
|
{
|
||||||
|
Info<< "No cells marked for refinement since reached limit "
|
||||||
|
<< maxGlobalCells << '.' << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Every cell I refine adds 7 cells. Estimate the number of cells
|
// Every cell I refine adds 7 cells. Estimate the number of cells
|
||||||
// I am allowed to refine.
|
// I am allowed to refine.
|
||||||
@ -1151,9 +1134,6 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
|||||||
{
|
{
|
||||||
label nShell = markInternalRefinement
|
label nShell = markInternalRefinement
|
||||||
(
|
(
|
||||||
shells,
|
|
||||||
shellLevels,
|
|
||||||
shellRefineInside,
|
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
|
|
||||||
refineCell,
|
refineCell,
|
||||||
@ -1184,13 +1164,11 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
|||||||
// Refinement based on curvature of surface
|
// Refinement based on curvature of surface
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
if (curvatureRefinement)
|
if (curvatureRefinement && (curvature >= -1 && curvature <= 1))
|
||||||
{
|
{
|
||||||
label nCurv = markSurfaceCurvatureRefinement
|
label nCurv = markSurfaceCurvatureRefinement
|
||||||
(
|
(
|
||||||
globalToPatch,
|
|
||||||
curvature,
|
curvature,
|
||||||
false, // do not refine at multiple regions
|
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
neiLevel,
|
neiLevel,
|
||||||
neiCc,
|
neiCc,
|
||||||
@ -1287,28 +1265,6 @@ Foam::autoPtr<Foam::mapDistributePolyMesh>
|
|||||||
printMeshInfo(debug, "After refinement " + msg);
|
printMeshInfo(debug, "After refinement " + msg);
|
||||||
|
|
||||||
|
|
||||||
//// Remove cells which are inside closed surfaces
|
|
||||||
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
//
|
|
||||||
//if (findIndex(surfaces.closed(), true) != -1)
|
|
||||||
//{
|
|
||||||
// Info<< "Removing cells fully inside closed surfaces."
|
|
||||||
// << endl;
|
|
||||||
// removeInsideCells
|
|
||||||
// (
|
|
||||||
// msg, // refinement iteration for statistics only
|
|
||||||
// exposedFacesPatch // patch to use for exposed internal faces
|
|
||||||
// );
|
|
||||||
// Info<< "Removed inside cells in = "
|
|
||||||
// << mesh_.time().cpuTimeIncrement() << " s" << endl;
|
|
||||||
// if (debug)
|
|
||||||
// {
|
|
||||||
// // test all is still synced across proc patches
|
|
||||||
// checkData();
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
// Load balancing
|
// Load balancing
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -26,8 +26,8 @@ Class
|
|||||||
Foam::refinementSurfaces
|
Foam::refinementSurfaces
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Container for triSurfaces used for surface-driven refinement.
|
Container for data on surfaces used for surface-driven refinement.
|
||||||
These contain all the data about the level of refinement needed per
|
Contains all the data about the level of refinement needed per
|
||||||
surface.
|
surface.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
@ -38,34 +38,38 @@ SourceFiles
|
|||||||
#ifndef refinementSurfaces_H
|
#ifndef refinementSurfaces_H
|
||||||
#define refinementSurfaces_H
|
#define refinementSurfaces_H
|
||||||
|
|
||||||
#include "triSurfaceMeshes.H"
|
|
||||||
#include "PackedList.H"
|
#include "PackedList.H"
|
||||||
#include "triSurfaceGeoMesh.H"
|
#include "triSurfaceGeoMesh.H"
|
||||||
#include "triSurfaceFields.H"
|
#include "triSurfaceFields.H"
|
||||||
|
#include "vectorList.H"
|
||||||
|
#include "pointIndexHit.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
class searchableSurface;
|
class searchableSurfaces;
|
||||||
|
class shellSurfaces;
|
||||||
|
class triSurfaceMesh;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class refinementSurfaces Declaration
|
Class refinementSurfaces Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class refinementSurfaces
|
class refinementSurfaces
|
||||||
:
|
|
||||||
public triSurfaceMeshes
|
|
||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
//- Reference to all geometry.
|
||||||
|
const searchableSurfaces& allGeometry_;
|
||||||
|
|
||||||
|
//- Indices of surfaces that are refinement ones
|
||||||
|
labelList surfaces_;
|
||||||
|
|
||||||
//- Surface name (word)
|
//- Surface name (word)
|
||||||
wordList names_;
|
wordList names_;
|
||||||
|
|
||||||
//- Per surface whether is closed
|
|
||||||
boolList closed_;
|
|
||||||
|
|
||||||
//- Per 'interface' surface : name of faceZone to put faces into
|
//- Per 'interface' surface : name of faceZone to put faces into
|
||||||
wordList faceZoneNames_;
|
wordList faceZoneNames_;
|
||||||
|
|
||||||
@ -86,24 +90,12 @@ class refinementSurfaces
|
|||||||
//- From global region number to refinement level
|
//- From global region number to refinement level
|
||||||
labelList maxLevel_;
|
labelList maxLevel_;
|
||||||
|
|
||||||
//- From global region number to added layers
|
|
||||||
labelList numLayers_;
|
|
||||||
|
|
||||||
//- From global region number to patch name
|
|
||||||
wordList patchName_;
|
|
||||||
|
|
||||||
//- From global region number to patch name
|
|
||||||
wordList patchType_;
|
|
||||||
|
|
||||||
|
|
||||||
//- Per surface refinement level adapted for shells.
|
//- Per surface refinement level adapted for shells.
|
||||||
PtrList<triSurfaceLabelField> minLevelFields_;
|
PtrList<triSurfaceLabelField> minLevelFields_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
static fileNameList extractFileNames(const PtrList<dictionary>&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
refinementSurfaces(const refinementSurfaces&);
|
refinementSurfaces(const refinementSurfaces&);
|
||||||
|
|
||||||
@ -115,30 +107,41 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from directory (io.instance()) and dictionaries
|
//- Construct from surfaces and dictionaries
|
||||||
refinementSurfaces
|
refinementSurfaces
|
||||||
(
|
(
|
||||||
const IOobject& io,
|
const searchableSurfaces& allGeometry,
|
||||||
const PtrList<dictionary>&
|
const PtrList<dictionary>&
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Construct from surfaces and dictionary
|
||||||
|
refinementSurfaces
|
||||||
|
(
|
||||||
|
const searchableSurfaces& allGeometry,
|
||||||
|
const dictionary&
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
|
const searchableSurfaces& geometry() const
|
||||||
|
{
|
||||||
|
return allGeometry_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelList& surfaces() const
|
||||||
|
{
|
||||||
|
return surfaces_;
|
||||||
|
}
|
||||||
|
|
||||||
//- Names of surfaces
|
//- Names of surfaces
|
||||||
const wordList& names() const
|
const wordList& names() const
|
||||||
{
|
{
|
||||||
return names_;
|
return names_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Per surface whether is closed
|
|
||||||
const boolList& closed() const
|
|
||||||
{
|
|
||||||
return closed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Per 'interface' surface : name of faceZone to put faces into
|
//- Per 'interface' surface : name of faceZone to put faces into
|
||||||
const wordList& faceZoneNames() const
|
const wordList& faceZoneNames() const
|
||||||
{
|
{
|
||||||
@ -151,15 +154,11 @@ public:
|
|||||||
return cellZoneNames_;
|
return cellZoneNames_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Per 'interface' surface : if closed: zonify cells inside surface
|
|
||||||
const boolList& zoneInside() const
|
|
||||||
{
|
|
||||||
return zoneInside_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Get indices of named surfaces (surfaces with cellZoneName)
|
//- Get indices of named surfaces (surfaces with cellZoneName)
|
||||||
labelList getNamedSurfaces() const;
|
labelList getNamedSurfaces() const;
|
||||||
|
|
||||||
|
//- Get indices of closed named surfaces
|
||||||
|
labelList getClosedNamedSurfaces() const;
|
||||||
|
|
||||||
//- From local region number to global region number
|
//- From local region number to global region number
|
||||||
const labelList& regionOffset() const
|
const labelList& regionOffset() const
|
||||||
@ -179,24 +178,6 @@ public:
|
|||||||
return maxLevel_;
|
return maxLevel_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- From global region number to added layers
|
|
||||||
const labelList& numLayers() const
|
|
||||||
{
|
|
||||||
return numLayers_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- From global region number to patch name. Patchnames can be empty
|
|
||||||
const wordList& patchName() const
|
|
||||||
{
|
|
||||||
return patchName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- From global region number to patch name
|
|
||||||
const wordList& patchType() const
|
|
||||||
{
|
|
||||||
return patchType_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Helper
|
// Helper
|
||||||
|
|
||||||
@ -206,14 +187,6 @@ public:
|
|||||||
return regionOffset_[surfI]+regionI;
|
return regionOffset_[surfI]+regionI;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- From triangle on surface to global region
|
|
||||||
label triangleRegion(const label surfI, const label triI) const
|
|
||||||
{
|
|
||||||
const triSurface& s = operator[](surfI);
|
|
||||||
|
|
||||||
return globalRegion(surfI, s[triI].region());
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Min level for surface and region on surface
|
//- Min level for surface and region on surface
|
||||||
label minLevel(const label surfI, const label regionI) const
|
label minLevel(const label surfI, const label regionI) const
|
||||||
{
|
{
|
||||||
@ -231,23 +204,12 @@ public:
|
|||||||
return minLevel_.size();
|
return minLevel_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Minlevel updated for refinement shells
|
|
||||||
const triSurfaceLabelField& minLevelField(const label surfI) const
|
|
||||||
{
|
|
||||||
return minLevelFields_[surfI];
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Calculate minLevelFields
|
//- Calculate minLevelFields
|
||||||
void setMinLevelFields
|
void setMinLevelFields
|
||||||
(
|
(
|
||||||
const PtrList<searchableSurface>& shells,
|
const shellSurfaces& shells
|
||||||
const labelList& shellLevels,
|
|
||||||
const boolList& shellRefineInside
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Helper: is surface closed?
|
|
||||||
static bool isSurfaceClosed(const triSurface&);
|
|
||||||
|
|
||||||
//- Helper: orient (closed only) surfaces so keepPoint is outside.
|
//- Helper: orient (closed only) surfaces so keepPoint is outside.
|
||||||
static void orientSurface
|
static void orientSurface
|
||||||
(
|
(
|
||||||
@ -263,36 +225,71 @@ public:
|
|||||||
|
|
||||||
//- Find intersection of edge. Return -1 or first surface
|
//- Find intersection of edge. Return -1 or first surface
|
||||||
// with higher (than currentLevel) minlevel.
|
// with higher (than currentLevel) minlevel.
|
||||||
// Return surface number and hit info.
|
// Return surface number and level.
|
||||||
label findHigherIntersection
|
void findHigherIntersection
|
||||||
(
|
(
|
||||||
const point& start,
|
const pointField& start,
|
||||||
const point& end,
|
const pointField& end,
|
||||||
const label currentLevel, // current cell refinement level
|
const labelList& currentLevel, // current cell refinement level
|
||||||
pointIndexHit&
|
|
||||||
|
labelList& surfaces,
|
||||||
|
labelList& surfaceLevel
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Find intersection with max level. Return -1 or the surface
|
//- Find all intersections of edge. Unsorted order.
|
||||||
// with the highest maxLevel above currentLevel
|
void findAllHigherIntersections
|
||||||
label findHighestIntersection
|
|
||||||
(
|
(
|
||||||
const point& start,
|
const pointField& start,
|
||||||
const point& end,
|
const pointField& end,
|
||||||
const label currentLevel, // current cell refinement level
|
const labelList& currentLevel, // current cell refinement level
|
||||||
pointIndexHit&
|
|
||||||
|
List<vectorList>& surfaceNormal,
|
||||||
|
labelListList& surfaceLevel
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Detect if a point is 'inside' (depending on zoneInside flag) a
|
//- Find intersection nearest to the endpoints. surface1,2 are
|
||||||
// zoneable surface. Returns -1 if not, returns first surface it
|
// not indices into surfacesToTest but refinement surface indices.
|
||||||
// is.
|
void findNearestIntersection
|
||||||
label insideZone(const labelList& surfaces, const point& pt) const;
|
(
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
|
||||||
|
labelList& surface1,
|
||||||
|
List<pointIndexHit>& hit1,
|
||||||
|
labelList& region1,
|
||||||
|
labelList& surface2,
|
||||||
|
List<pointIndexHit>& hit2,
|
||||||
|
labelList& region2
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Mark for all points whether it is inside any closed surface
|
//- Used for debugging only: find intersection of edge.
|
||||||
// Return number of inside points.
|
void findAnyIntersection
|
||||||
label markInsidePoints(const pointField&, PackedList<1>& isInside)
|
(
|
||||||
const;
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelList& surfaces,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Find nearest point on surfaces.
|
||||||
|
void findNearest
|
||||||
|
(
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& samples,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
labelList& surfaces,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Detect if a point is 'inside' (closed) surfaces.
|
||||||
|
// Returns -1 if not, returns first surface it is.
|
||||||
|
void findInside
|
||||||
|
(
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& pt,
|
||||||
|
labelList& insideSurfaces
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
465
src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C
Normal file
465
src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "searchableSurface.H"
|
||||||
|
#include "shellSurfaces.H"
|
||||||
|
#include "boundBox.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "refinementSurfaces.H"
|
||||||
|
#include "searchableSurfaces.H"
|
||||||
|
#include "pointIndexHit.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
template<>
|
||||||
|
const char*
|
||||||
|
NamedEnum<shellSurfaces::refineMode, 3>::
|
||||||
|
names[] =
|
||||||
|
{
|
||||||
|
"inside",
|
||||||
|
"outside",
|
||||||
|
"distance"
|
||||||
|
};
|
||||||
|
|
||||||
|
const NamedEnum<shellSurfaces::refineMode, 3> shellSurfaces::refineModeNames_;
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::shellSurfaces::setAndCheckLevels
|
||||||
|
(
|
||||||
|
const scalar shellI,
|
||||||
|
const List<Tuple2<scalar, label> >& distLevels
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (modes_[shellI] != DISTANCE && distLevels.size() != 1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"shellSurfaces::shellSurfaces"
|
||||||
|
"(const searchableSurfaces&, const dictionary&)"
|
||||||
|
) << "For refinement mode "
|
||||||
|
<< refineModeNames_[modes_[shellI]]
|
||||||
|
<< " specify only one distance+level."
|
||||||
|
<< " (its distance gets discarded)"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
// Extract information into separate distance and level
|
||||||
|
distances_[shellI].setSize(distLevels.size());
|
||||||
|
levels_[shellI].setSize(distLevels.size());
|
||||||
|
|
||||||
|
forAll(distLevels, j)
|
||||||
|
{
|
||||||
|
distances_[shellI][j] = distLevels[j].first();
|
||||||
|
levels_[shellI][j] = distLevels[j].second();
|
||||||
|
|
||||||
|
// Check in incremental order
|
||||||
|
if (j > 0)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(distances_[shellI][j] <= distances_[shellI][j-1])
|
||||||
|
|| (levels_[shellI][j] > levels_[shellI][j-1])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"shellSurfaces::shellSurfaces"
|
||||||
|
"(const searchableSurfaces&, const dictionary&)"
|
||||||
|
) << "For refinement mode "
|
||||||
|
<< refineModeNames_[modes_[shellI]]
|
||||||
|
<< " : Refinement should be specified in order"
|
||||||
|
<< " of increasing distance"
|
||||||
|
<< " (and decreasing refinement level)." << endl
|
||||||
|
<< "Distance:" << distances_[shellI][j]
|
||||||
|
<< " refinementLevel:" << levels_[shellI][j]
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchableSurface& shell = allGeometry_[shells_[shellI]];
|
||||||
|
|
||||||
|
if (modes_[shellI] == DISTANCE)
|
||||||
|
{
|
||||||
|
Info<< "Refinement level according to distance to "
|
||||||
|
<< shell.name() << endl;
|
||||||
|
forAll(levels_[shellI], j)
|
||||||
|
{
|
||||||
|
Info<< " level " << levels_[shellI][j]
|
||||||
|
<< " for all cells within " << distances_[shellI][j]
|
||||||
|
<< " meter." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!allGeometry_[shells_[shellI]].hasVolumeType())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"shellSurfaces::shellSurfaces"
|
||||||
|
"(const searchableSurfaces&"
|
||||||
|
", const PtrList<dictionary>&)"
|
||||||
|
) << "Shell " << shell.name()
|
||||||
|
<< " does not support testing for "
|
||||||
|
<< refineModeNames_[modes_[shellI]] << endl
|
||||||
|
<< "Probably it is not closed."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modes_[shellI] == INSIDE)
|
||||||
|
{
|
||||||
|
Info<< "Refinement level " << levels_[shellI][0]
|
||||||
|
<< " for all cells inside " << shell.name() << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Refinement level " << levels_[shellI][0]
|
||||||
|
<< " for all cells outside " << shell.name() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Specifically orient triSurfaces using a calculated point outside.
|
||||||
|
// Done since quite often triSurfaces not of consistent orientation which
|
||||||
|
// is (currently) necessary for sideness calculation
|
||||||
|
void Foam::shellSurfaces::orient()
|
||||||
|
{
|
||||||
|
// Determine outside point.
|
||||||
|
boundBox overallBb
|
||||||
|
(
|
||||||
|
point(GREAT, GREAT, GREAT),
|
||||||
|
point(-GREAT, -GREAT, -GREAT)
|
||||||
|
);
|
||||||
|
|
||||||
|
bool hasSurface = false;
|
||||||
|
|
||||||
|
forAll(shells_, shellI)
|
||||||
|
{
|
||||||
|
const searchableSurface& s = allGeometry_[shells_[shellI]];
|
||||||
|
|
||||||
|
if (modes_[shellI] != DISTANCE && isA<triSurfaceMesh>(s))
|
||||||
|
{
|
||||||
|
const triSurfaceMesh& shell = refCast<const triSurfaceMesh>(s);
|
||||||
|
|
||||||
|
if (shell.triSurface::size() > 0)
|
||||||
|
{
|
||||||
|
const pointField& points = shell.points();
|
||||||
|
|
||||||
|
hasSurface = true;
|
||||||
|
|
||||||
|
boundBox shellBb(points[0], points[0]);
|
||||||
|
// Assume surface is compact!
|
||||||
|
for (label i = 0; i < points.size(); i++)
|
||||||
|
{
|
||||||
|
const point& pt = points[i];
|
||||||
|
shellBb.min() = min(shellBb.min(), pt);
|
||||||
|
shellBb.max() = max(shellBb.max(), pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
overallBb.min() = min(overallBb.min(), shellBb.min());
|
||||||
|
overallBb.max() = max(overallBb.max(), shellBb.max());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSurface)
|
||||||
|
{
|
||||||
|
const point outsidePt(2*overallBb.max() - overallBb.min());
|
||||||
|
|
||||||
|
//Info<< "Using point " << outsidePt << " to orient shells" << endl;
|
||||||
|
|
||||||
|
forAll(shells_, shellI)
|
||||||
|
{
|
||||||
|
const searchableSurface& s = allGeometry_[shells_[shellI]];
|
||||||
|
|
||||||
|
if (modes_[shellI] != DISTANCE && isA<triSurfaceMesh>(s))
|
||||||
|
{
|
||||||
|
triSurfaceMesh& shell = const_cast<triSurfaceMesh&>
|
||||||
|
(
|
||||||
|
refCast<const triSurfaceMesh>(s)
|
||||||
|
);
|
||||||
|
|
||||||
|
refinementSurfaces::orientSurface(outsidePt, shell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find maximum level of a shell.
|
||||||
|
void Foam::shellSurfaces::findHigherLevel
|
||||||
|
(
|
||||||
|
const pointField& pt,
|
||||||
|
const label shellI,
|
||||||
|
labelList& maxLevel
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const labelList& levels = levels_[shellI];
|
||||||
|
|
||||||
|
if (modes_[shellI] == DISTANCE)
|
||||||
|
{
|
||||||
|
// Distance mode.
|
||||||
|
|
||||||
|
const scalarField& distances = distances_[shellI];
|
||||||
|
|
||||||
|
// Collect all those points that have a current maxLevel less than
|
||||||
|
// (any of) the shell. Also collect the furthest distance allowable
|
||||||
|
// to any shell with a higher level.
|
||||||
|
|
||||||
|
pointField candidates(pt.size());
|
||||||
|
labelList candidateMap(pt.size());
|
||||||
|
scalarField candidateDistSqr(pt.size());
|
||||||
|
label candidateI = 0;
|
||||||
|
|
||||||
|
forAll(maxLevel, pointI)
|
||||||
|
{
|
||||||
|
forAllReverse(levels, levelI)
|
||||||
|
{
|
||||||
|
if (levels[levelI] > maxLevel[pointI])
|
||||||
|
{
|
||||||
|
candidates[candidateI] = pt[pointI];
|
||||||
|
candidateMap[candidateI] = pointI;
|
||||||
|
candidateDistSqr[candidateI] = sqr(distances[levelI]);
|
||||||
|
candidateI++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidates.setSize(candidateI);
|
||||||
|
candidateMap.setSize(candidateI);
|
||||||
|
candidateDistSqr.setSize(candidateI);
|
||||||
|
|
||||||
|
// Do the expensive nearest test only for the candidate points.
|
||||||
|
List<pointIndexHit> nearInfo;
|
||||||
|
allGeometry_[shells_[shellI]].findNearest
|
||||||
|
(
|
||||||
|
candidates,
|
||||||
|
candidateDistSqr,
|
||||||
|
nearInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update maxLevel
|
||||||
|
forAll(nearInfo, candidateI)
|
||||||
|
{
|
||||||
|
if (nearInfo[candidateI].hit())
|
||||||
|
{
|
||||||
|
// Check which level it actually is in.
|
||||||
|
label minDistI = findLower
|
||||||
|
(
|
||||||
|
distances,
|
||||||
|
mag(nearInfo[candidateI].hitPoint()-candidates[candidateI])
|
||||||
|
);
|
||||||
|
|
||||||
|
label pointI = candidateMap[candidateI];
|
||||||
|
|
||||||
|
// pt is inbetween shell[minDistI] and shell[minDistI+1]
|
||||||
|
maxLevel[pointI] = levels[minDistI+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Inside/outside mode
|
||||||
|
|
||||||
|
// Collect all those points that have a current maxLevel less than the
|
||||||
|
// shell.
|
||||||
|
|
||||||
|
pointField candidates(pt.size());
|
||||||
|
labelList candidateMap(pt.size());
|
||||||
|
label candidateI = 0;
|
||||||
|
|
||||||
|
forAll(maxLevel, pointI)
|
||||||
|
{
|
||||||
|
if (levels[0] > maxLevel[pointI])
|
||||||
|
{
|
||||||
|
candidates[candidateI] = pt[pointI];
|
||||||
|
candidateMap[candidateI] = pointI;
|
||||||
|
candidateI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidates.setSize(candidateI);
|
||||||
|
candidateMap.setSize(candidateI);
|
||||||
|
|
||||||
|
// Do the expensive nearest test only for the candidate points.
|
||||||
|
List<searchableSurface::volumeType> volType;
|
||||||
|
allGeometry_[shells_[shellI]].getVolumeType(candidates, volType);
|
||||||
|
|
||||||
|
forAll(volType, i)
|
||||||
|
{
|
||||||
|
label pointI = candidateMap[i];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(
|
||||||
|
modes_[shellI] == INSIDE
|
||||||
|
&& volType[i] == searchableSurface::INSIDE
|
||||||
|
)
|
||||||
|
|| (
|
||||||
|
modes_[shellI] == OUTSIDE
|
||||||
|
&& volType[i] == searchableSurface::OUTSIDE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
maxLevel[pointI] = levels[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::shellSurfaces::shellSurfaces
|
||||||
|
(
|
||||||
|
const searchableSurfaces& allGeometry,
|
||||||
|
const PtrList<dictionary>& shellDicts
|
||||||
|
)
|
||||||
|
:
|
||||||
|
allGeometry_(allGeometry)
|
||||||
|
{
|
||||||
|
shells_.setSize(shellDicts.size());
|
||||||
|
modes_.setSize(shellDicts.size());
|
||||||
|
distances_.setSize(shellDicts.size());
|
||||||
|
levels_.setSize(shellDicts.size());
|
||||||
|
|
||||||
|
forAll(shellDicts, shellI)
|
||||||
|
{
|
||||||
|
const dictionary& dict = shellDicts[shellI];
|
||||||
|
const word name = dict.lookup("name");
|
||||||
|
const word type = dict.lookup("type");
|
||||||
|
|
||||||
|
shells_[shellI] = allGeometry_.findSurfaceID(name);
|
||||||
|
|
||||||
|
if (shells_[shellI] == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"shellSurfaces::shellSurfaces"
|
||||||
|
"(const searchableSurfaces&, const PtrList<dictionary>&)"
|
||||||
|
) << "No surface called " << name << endl
|
||||||
|
<< "Valid surfaces are " << allGeometry_.names()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
modes_[shellI] = refineModeNames_.read(dict.lookup("refineMode"));
|
||||||
|
|
||||||
|
// Read pairs of distance+level
|
||||||
|
setAndCheckLevels(shellI, dict.lookup("levels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orient shell surfaces before any searching is done. Note that this
|
||||||
|
// only needs to be done for inside or outside. Orienting surfaces
|
||||||
|
// constructs lots of addressing which we want to avoid.
|
||||||
|
orient();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::shellSurfaces::shellSurfaces
|
||||||
|
(
|
||||||
|
const searchableSurfaces& allGeometry,
|
||||||
|
const dictionary& shellsDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
allGeometry_(allGeometry)
|
||||||
|
{
|
||||||
|
shells_.setSize(shellsDict.size());
|
||||||
|
modes_.setSize(shellsDict.size());
|
||||||
|
distances_.setSize(shellsDict.size());
|
||||||
|
levels_.setSize(shellsDict.size());
|
||||||
|
|
||||||
|
label shellI = 0;
|
||||||
|
forAllConstIter(dictionary, shellsDict, iter)
|
||||||
|
{
|
||||||
|
shells_[shellI] = allGeometry_.findSurfaceID(iter().keyword());
|
||||||
|
|
||||||
|
if (shells_[shellI] == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"shellSurfaces::shellSurfaces"
|
||||||
|
"(const searchableSurfaces&, const dictionary>&"
|
||||||
|
) << "No surface called " << iter().keyword() << endl
|
||||||
|
<< "Valid surfaces are " << allGeometry_.names()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
const dictionary& dict = shellsDict.subDict(iter().keyword());
|
||||||
|
|
||||||
|
modes_[shellI] = refineModeNames_.read(dict.lookup("mode"));
|
||||||
|
|
||||||
|
// Read pairs of distance+level
|
||||||
|
setAndCheckLevels(shellI, dict.lookup("levels"));
|
||||||
|
|
||||||
|
shellI++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orient shell surfaces before any searching is done. Note that this
|
||||||
|
// only needs to be done for inside or outside. Orienting surfaces
|
||||||
|
// constructs lots of addressing which we want to avoid.
|
||||||
|
orient();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Highest shell level
|
||||||
|
Foam::label Foam::shellSurfaces::maxLevel() const
|
||||||
|
{
|
||||||
|
label overallMax = 0;
|
||||||
|
forAll(levels_, shellI)
|
||||||
|
{
|
||||||
|
overallMax = max(overallMax, max(levels_[shellI]));
|
||||||
|
}
|
||||||
|
return overallMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::shellSurfaces::findHigherLevel
|
||||||
|
(
|
||||||
|
const pointField& pt,
|
||||||
|
const labelList& ptLevel,
|
||||||
|
labelList& maxLevel
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Maximum level of any shell. Start off with level of point.
|
||||||
|
maxLevel = ptLevel;
|
||||||
|
|
||||||
|
forAll(shells_, shellI)
|
||||||
|
{
|
||||||
|
findHigherLevel(pt, shellI, maxLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
182
src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.H
Normal file
182
src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.H
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
shellSurfaces
|
||||||
|
|
||||||
|
Description
|
||||||
|
Encapsulates queries for volume refinement ('refine all cells within
|
||||||
|
shell').
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
shellSurfaces.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef shellSurfaces_H
|
||||||
|
#define shellSurfaces_H
|
||||||
|
|
||||||
|
#include "searchableSurface.H"
|
||||||
|
#include "Tuple2.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class searchableSurfaces;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class shellSurfaces Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class shellSurfaces
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public data types
|
||||||
|
|
||||||
|
//- Volume refinement controls
|
||||||
|
enum refineMode
|
||||||
|
{
|
||||||
|
INSIDE, // Refine all inside shell
|
||||||
|
OUTSIDE, // ,, outside
|
||||||
|
DISTANCE // Refine based on distance to shell
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Reference to all geometry.
|
||||||
|
const searchableSurfaces& allGeometry_;
|
||||||
|
|
||||||
|
//- Indices of surfaces that are shells
|
||||||
|
labelList shells_;
|
||||||
|
|
||||||
|
//- Per shell whether to refine inside or outside
|
||||||
|
List<refineMode> modes_;
|
||||||
|
|
||||||
|
//- Per shell the list of ranges
|
||||||
|
List<scalarField> distances_;
|
||||||
|
|
||||||
|
//- Per shell per distance the refinement level
|
||||||
|
labelListList levels_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- refineMode names
|
||||||
|
static const NamedEnum<refineMode, 3> refineModeNames_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Helper function for initialisation.
|
||||||
|
void setAndCheckLevels
|
||||||
|
(
|
||||||
|
const scalar shellI,
|
||||||
|
const List<Tuple2<scalar, label> >&
|
||||||
|
);
|
||||||
|
|
||||||
|
void orient();
|
||||||
|
|
||||||
|
void findHigherLevel
|
||||||
|
(
|
||||||
|
const pointField& pt,
|
||||||
|
const label shellI,
|
||||||
|
labelList& maxLevel
|
||||||
|
) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
shellSurfaces
|
||||||
|
(
|
||||||
|
const searchableSurfaces& allGeometry,
|
||||||
|
const labelList& shells,
|
||||||
|
const List<refineMode>& modes,
|
||||||
|
const List<scalarField>& distances,
|
||||||
|
const labelListList& levels
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from geometry and dictionaries
|
||||||
|
shellSurfaces
|
||||||
|
(
|
||||||
|
const searchableSurfaces& allGeometry,
|
||||||
|
const PtrList<dictionary>& shellDicts
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from geometry and dictionary
|
||||||
|
shellSurfaces
|
||||||
|
(
|
||||||
|
const searchableSurfaces& allGeometry,
|
||||||
|
const dictionary& shellsDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//const List<scalarField>& distances() const
|
||||||
|
//{
|
||||||
|
// return distances_;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
////- Per shell per distance the refinement level
|
||||||
|
//const labelListList& levels() const
|
||||||
|
//{
|
||||||
|
// return levels_;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// Query
|
||||||
|
|
||||||
|
//- Highest shell level
|
||||||
|
label maxLevel() const;
|
||||||
|
|
||||||
|
//- Find shell level higher than ptLevel
|
||||||
|
void findHigherLevel
|
||||||
|
(
|
||||||
|
const pointField& pt,
|
||||||
|
const labelList& ptLevel,
|
||||||
|
labelList& maxLevel
|
||||||
|
) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -256,7 +256,7 @@ Foam::Ostream& Foam::operator<<
|
|||||||
const ExactParticle<ParticleType>& p
|
const ExactParticle<ParticleType>& p
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return operator<<(os, static_cast<Particle<ParticleType> >(p));
|
return operator<<(os, static_cast<const Particle<ParticleType>&>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -361,7 +361,7 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Helper funntion: count cells per processor in wanted distribution
|
//- Helper function: count cells per processor in wanted distribution
|
||||||
static labelList countCells(const labelList&);
|
static labelList countCells(const labelList&);
|
||||||
|
|
||||||
//- Send cells to neighbours according to distribution
|
//- Send cells to neighbours according to distribution
|
||||||
|
|||||||
@ -553,7 +553,7 @@ Foam::labelListList Foam::addPatchCellLayer::addedCells() const
|
|||||||
|
|
||||||
void Foam::addPatchCellLayer::setRefinement
|
void Foam::addPatchCellLayer::setRefinement
|
||||||
(
|
(
|
||||||
const scalar expansionRatio,
|
const scalarField& expansionRatio,
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const labelList& nFaceLayers,
|
const labelList& nFaceLayers,
|
||||||
const labelList& nPointLayers,
|
const labelList& nPointLayers,
|
||||||
@ -885,7 +885,7 @@ void Foam::addPatchCellLayer::setRefinement
|
|||||||
|
|
||||||
addedPoints_[patchPointI][i] = addedVertI;
|
addedPoints_[patchPointI][i] = addedVertI;
|
||||||
|
|
||||||
disp *= expansionRatio;
|
disp *= expansionRatio[patchPointI];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -305,7 +305,7 @@ public:
|
|||||||
// (instead of e.g. from patch faces)
|
// (instead of e.g. from patch faces)
|
||||||
void setRefinement
|
void setRefinement
|
||||||
(
|
(
|
||||||
const scalar expansionRatio,
|
const scalarField& expansionRatio,
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const labelList& nFaceLayers,
|
const labelList& nFaceLayers,
|
||||||
const labelList& nPointLayers,
|
const labelList& nPointLayers,
|
||||||
@ -325,7 +325,7 @@ public:
|
|||||||
{
|
{
|
||||||
setRefinement
|
setRefinement
|
||||||
(
|
(
|
||||||
1.0, // expansion ration
|
scalarField(pp.nPoints(), 1.0), // expansion ration
|
||||||
pp,
|
pp,
|
||||||
labelList(pp.size(), nLayers),
|
labelList(pp.size(), nLayers),
|
||||||
labelList(pp.nPoints(), nLayers),
|
labelList(pp.nPoints(), nLayers),
|
||||||
|
|||||||
@ -30,12 +30,10 @@ License
|
|||||||
#include "fvPatchFieldMapper.H"
|
#include "fvPatchFieldMapper.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "IFstream.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::
|
Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
||||||
(
|
(
|
||||||
const fvPatch& p,
|
const fvPatch& p,
|
||||||
@ -47,8 +45,7 @@ timeVaryingFlowRateInletVelocityFvPatchVectorField
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::
|
Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
||||||
(
|
(
|
||||||
const timeVaryingFlowRateInletVelocityFvPatchVectorField& ptf,
|
const timeVaryingFlowRateInletVelocityFvPatchVectorField& ptf,
|
||||||
@ -62,8 +59,7 @@ timeVaryingFlowRateInletVelocityFvPatchVectorField
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::
|
Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
||||||
(
|
(
|
||||||
const fvPatch& p,
|
const fvPatch& p,
|
||||||
@ -72,12 +68,11 @@ timeVaryingFlowRateInletVelocityFvPatchVectorField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
flowRateInletVelocityFvPatchVectorField(p, iF, dict),
|
flowRateInletVelocityFvPatchVectorField(p, iF, dict),
|
||||||
timeSeries_(this->db(), dict)
|
timeSeries_(dict)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::
|
Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
||||||
(
|
(
|
||||||
const timeVaryingFlowRateInletVelocityFvPatchVectorField& ptf
|
const timeVaryingFlowRateInletVelocityFvPatchVectorField& ptf
|
||||||
@ -88,8 +83,7 @@ timeVaryingFlowRateInletVelocityFvPatchVectorField
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::
|
Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
timeVaryingFlowRateInletVelocityFvPatchVectorField
|
||||||
(
|
(
|
||||||
const timeVaryingFlowRateInletVelocityFvPatchVectorField& ptf,
|
const timeVaryingFlowRateInletVelocityFvPatchVectorField& ptf,
|
||||||
@ -103,8 +97,7 @@ timeVaryingFlowRateInletVelocityFvPatchVectorField
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::
|
void Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
updateCoeffs()
|
updateCoeffs()
|
||||||
{
|
{
|
||||||
if (updated())
|
if (updated())
|
||||||
@ -117,8 +110,7 @@ updateCoeffs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::
|
void Foam::timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
||||||
timeVaryingFlowRateInletVelocityFvPatchVectorField::
|
|
||||||
write(Ostream& os) const
|
write(Ostream& os) const
|
||||||
{
|
{
|
||||||
flowRateInletVelocityFvPatchVectorField::write(os);
|
flowRateInletVelocityFvPatchVectorField::write(os);
|
||||||
|
|||||||
@ -26,7 +26,6 @@ License
|
|||||||
|
|
||||||
#include "timeVaryingUniformFixedValueFvPatchField.H"
|
#include "timeVaryingUniformFixedValueFvPatchField.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "IFstream.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ timeVaryingUniformFixedValueFvPatchField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchField<Type>(p, iF),
|
fixedValueFvPatchField<Type>(p, iF),
|
||||||
timeSeries_(this->db(), dict)
|
timeSeries_(dict)
|
||||||
{
|
{
|
||||||
if (dict.found("value"))
|
if (dict.found("value"))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -29,7 +29,6 @@ License
|
|||||||
#include "fvPatchFieldMapper.H"
|
#include "fvPatchFieldMapper.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
#include "IFstream.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -66,7 +65,7 @@ timeVaryingUniformTotalPressureFvPatchScalarField
|
|||||||
psiName_(dict.lookup("psi")),
|
psiName_(dict.lookup("psi")),
|
||||||
gamma_(readScalar(dict.lookup("gamma"))),
|
gamma_(readScalar(dict.lookup("gamma"))),
|
||||||
p0_(readScalar(dict.lookup("p0"))),
|
p0_(readScalar(dict.lookup("p0"))),
|
||||||
totalPressureTimeSeries_(this->db(), dict)
|
totalPressureTimeSeries_(dict)
|
||||||
{
|
{
|
||||||
if (dict.found("value"))
|
if (dict.found("value"))
|
||||||
{
|
{
|
||||||
@ -215,7 +214,8 @@ void Foam::timeVaryingUniformTotalPressureFvPatchScalarField::updateCoeffs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::timeVaryingUniformTotalPressureFvPatchScalarField::write(Ostream& os) const
|
void Foam::timeVaryingUniformTotalPressureFvPatchScalarField::
|
||||||
|
write(Ostream& os) const
|
||||||
{
|
{
|
||||||
fvPatchScalarField::write(os);
|
fvPatchScalarField::write(os);
|
||||||
os.writeKeyword("U") << UName_ << token::END_STATEMENT << nl;
|
os.writeKeyword("U") << UName_ << token::END_STATEMENT << nl;
|
||||||
|
|||||||
@ -62,7 +62,6 @@ surfaceSlipDisplacementPointPatchVectorField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointPatchVectorField(p, iF),
|
pointPatchVectorField(p, iF),
|
||||||
surfaceNames_(),
|
|
||||||
projectMode_(NEAREST),
|
projectMode_(NEAREST),
|
||||||
projectDir_(vector::zero),
|
projectDir_(vector::zero),
|
||||||
wedgePlane_(-1)
|
wedgePlane_(-1)
|
||||||
@ -78,7 +77,7 @@ surfaceSlipDisplacementPointPatchVectorField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointPatchVectorField(p, iF, dict),
|
pointPatchVectorField(p, iF, dict),
|
||||||
surfaceNames_(dict.lookup("projectSurfaces")),
|
surfacesDict_(dict.subDict("geometry")),
|
||||||
projectMode_(followModeNames_.read(dict.lookup("followMode"))),
|
projectMode_(followModeNames_.read(dict.lookup("followMode"))),
|
||||||
projectDir_(dict.lookup("projectDirection")),
|
projectDir_(dict.lookup("projectDirection")),
|
||||||
wedgePlane_(readLabel(dict.lookup("wedgePlane"))),
|
wedgePlane_(readLabel(dict.lookup("wedgePlane"))),
|
||||||
@ -96,7 +95,7 @@ surfaceSlipDisplacementPointPatchVectorField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointPatchVectorField(p, iF),
|
pointPatchVectorField(p, iF),
|
||||||
surfaceNames_(ppf.surfaceNames()),
|
surfacesDict_(ppf.surfacesDict()),
|
||||||
projectMode_(ppf.projectMode()),
|
projectMode_(ppf.projectMode()),
|
||||||
projectDir_(ppf.projectDir()),
|
projectDir_(ppf.projectDir()),
|
||||||
wedgePlane_(ppf.wedgePlane()),
|
wedgePlane_(ppf.wedgePlane()),
|
||||||
@ -111,7 +110,7 @@ surfaceSlipDisplacementPointPatchVectorField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointPatchVectorField(ppf),
|
pointPatchVectorField(ppf),
|
||||||
surfaceNames_(ppf.surfaceNames()),
|
surfacesDict_(ppf.surfacesDict()),
|
||||||
projectMode_(ppf.projectMode()),
|
projectMode_(ppf.projectMode()),
|
||||||
projectDir_(ppf.projectDir()),
|
projectDir_(ppf.projectDir()),
|
||||||
wedgePlane_(ppf.wedgePlane()),
|
wedgePlane_(ppf.wedgePlane()),
|
||||||
@ -127,7 +126,7 @@ surfaceSlipDisplacementPointPatchVectorField
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointPatchVectorField(ppf, iF),
|
pointPatchVectorField(ppf, iF),
|
||||||
surfaceNames_(ppf.surfaceNames()),
|
surfacesDict_(ppf.surfacesDict()),
|
||||||
projectMode_(ppf.projectMode()),
|
projectMode_(ppf.projectMode()),
|
||||||
projectDir_(ppf.projectDir()),
|
projectDir_(ppf.projectDir()),
|
||||||
wedgePlane_(ppf.wedgePlane()),
|
wedgePlane_(ppf.wedgePlane()),
|
||||||
@ -137,14 +136,14 @@ surfaceSlipDisplacementPointPatchVectorField
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const triSurfaceMeshes& surfaceSlipDisplacementPointPatchVectorField::
|
const searchableSurfaces& surfaceSlipDisplacementPointPatchVectorField::
|
||||||
surfaces() const
|
surfaces() const
|
||||||
{
|
{
|
||||||
if (!surfacesPtr_.valid())
|
if (!surfacesPtr_.valid())
|
||||||
{
|
{
|
||||||
surfacesPtr_.reset
|
surfacesPtr_.reset
|
||||||
(
|
(
|
||||||
new triSurfaceMeshes
|
new searchableSurfaces
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
@ -155,7 +154,7 @@ surfaces() const
|
|||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
surfaceNames_
|
surfacesDict_
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -215,130 +214,182 @@ void surfaceSlipDisplacementPointPatchVectorField::evaluate
|
|||||||
);
|
);
|
||||||
const pointField& points0 = motionSolver.points0();
|
const pointField& points0 = motionSolver.points0();
|
||||||
|
|
||||||
forAll(localPoints, i)
|
|
||||||
|
//XXXXXX
|
||||||
|
|
||||||
|
|
||||||
|
pointField start(meshPoints.size());
|
||||||
|
forAll(start, i)
|
||||||
|
{
|
||||||
|
start[i] = points0[meshPoints[i]] + displacement[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (projectMode_ == NEAREST)
|
||||||
|
{
|
||||||
|
List<pointIndexHit> nearest;
|
||||||
|
labelList hitSurfaces;
|
||||||
|
surfaces().findNearest
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
scalarField(start.size(), sqr(projectLen)),
|
||||||
|
hitSurfaces,
|
||||||
|
nearest
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(nearest, i)
|
||||||
{
|
{
|
||||||
if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
|
if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
|
||||||
{
|
{
|
||||||
// Fixed point. Reset to point0 location.
|
// Fixed point. Reset to point0 location.
|
||||||
|
|
||||||
//Pout<< " Fixed point:" << meshPoints[i]
|
|
||||||
// << " coord:" << localPoints[i]
|
|
||||||
// << " should be at:" << points0[meshPoints[i]]
|
|
||||||
// << endl;
|
|
||||||
displacement[i] = points0[meshPoints[i]] - localPoints[i];
|
displacement[i] = points0[meshPoints[i]] - localPoints[i];
|
||||||
}
|
}
|
||||||
else
|
else if (nearest[i].hit())
|
||||||
{
|
{
|
||||||
point start(points0[meshPoints[i]] + displacement[i]);
|
displacement[i] =
|
||||||
|
nearest[i].hitPoint()
|
||||||
scalar offset = 0;
|
- points0[meshPoints[i]];
|
||||||
pointIndexHit intersection;
|
|
||||||
|
|
||||||
if (projectMode_ == NEAREST)
|
|
||||||
{
|
|
||||||
surfaces().findNearest(start, sqr(projectLen), intersection);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if already on surface
|
Pout<< " point:" << meshPoints[i]
|
||||||
surfaces().findNearest(start, sqr(SMALL), intersection);
|
<< " coord:" << localPoints[i]
|
||||||
|
<< " did not find any surface within " << projectLen
|
||||||
if (!intersection.hit())
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// No nearest found. Do intersection
|
// Do tests on all points. Combine later on.
|
||||||
|
|
||||||
|
// 1. Check if already on surface
|
||||||
|
List<pointIndexHit> nearest;
|
||||||
|
{
|
||||||
|
labelList nearestSurface;
|
||||||
|
surfaces().findNearest
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
scalarField(start.size(), sqr(SMALL)),
|
||||||
|
nearestSurface,
|
||||||
|
nearest
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. intersection. (combined later on with information from nearest
|
||||||
|
// above)
|
||||||
|
vectorField projectVecs(start.size(), projectVec);
|
||||||
|
|
||||||
if (projectMode_ == POINTNORMAL)
|
if (projectMode_ == POINTNORMAL)
|
||||||
{
|
{
|
||||||
projectVec = projectLen*patch().pointNormals()[i];
|
projectVecs = projectLen*patch().pointNormals();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Knock out any wedge component
|
// Knock out any wedge component
|
||||||
|
scalarField offset(start.size(), 0.0);
|
||||||
if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
|
if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
|
||||||
{
|
{
|
||||||
offset = start[wedgePlane_];
|
forAll(offset, i)
|
||||||
start[wedgePlane_] = 0;
|
{
|
||||||
projectVec[wedgePlane_] = 0;
|
offset[i] = start[i][wedgePlane_];
|
||||||
|
start[i][wedgePlane_] = 0;
|
||||||
|
projectVecs[i][wedgePlane_] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label rightSurf0, rightSurf1;
|
List<pointIndexHit> rightHit;
|
||||||
pointIndexHit rightHit0, rightHit1;
|
|
||||||
surfaces().findNearestIntersection
|
|
||||||
(
|
|
||||||
start,
|
|
||||||
start+projectVec,
|
|
||||||
rightSurf0,
|
|
||||||
rightHit0,
|
|
||||||
rightSurf1,
|
|
||||||
rightHit1
|
|
||||||
);
|
|
||||||
|
|
||||||
// Do intersection
|
|
||||||
label leftSurf0, leftSurf1;
|
|
||||||
pointIndexHit leftHit0, leftHit1;
|
|
||||||
surfaces().findNearestIntersection
|
|
||||||
(
|
|
||||||
start,
|
|
||||||
start-projectVec,
|
|
||||||
leftSurf0,
|
|
||||||
leftHit0,
|
|
||||||
leftSurf1,
|
|
||||||
leftHit1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (rightHit0.hit())
|
|
||||||
{
|
{
|
||||||
if (leftHit0.hit())
|
labelList rightSurf;
|
||||||
|
surfaces().findAnyIntersection
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
start+projectVecs,
|
||||||
|
rightSurf,
|
||||||
|
rightHit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<pointIndexHit> leftHit;
|
||||||
|
{
|
||||||
|
labelList leftSurf;
|
||||||
|
surfaces().findAnyIntersection
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
start-projectVecs,
|
||||||
|
leftSurf,
|
||||||
|
leftHit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Choose either -fixed, nearest, right, left.
|
||||||
|
forAll(displacement, i)
|
||||||
|
{
|
||||||
|
if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
|
||||||
|
{
|
||||||
|
// Fixed point. Reset to point0 location.
|
||||||
|
displacement[i] = points0[meshPoints[i]] - localPoints[i];
|
||||||
|
}
|
||||||
|
else if (nearest[i].hit())
|
||||||
|
{
|
||||||
|
// Found nearest.
|
||||||
|
displacement[i] =
|
||||||
|
nearest[i].hitPoint()
|
||||||
|
- points0[meshPoints[i]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointIndexHit interPt;
|
||||||
|
|
||||||
|
if (rightHit[i].hit())
|
||||||
|
{
|
||||||
|
if (leftHit[i].hit())
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
magSqr(rightHit0.hitPoint()-start)
|
magSqr(rightHit[i].hitPoint()-start[i])
|
||||||
< magSqr(leftHit0.hitPoint()-start)
|
< magSqr(leftHit[i].hitPoint()-start[i])
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
intersection = rightHit0;
|
interPt = rightHit[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
intersection = leftHit0;
|
interPt = leftHit[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
intersection = rightHit0;
|
interPt = rightHit[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (leftHit0.hit())
|
if (leftHit[i].hit())
|
||||||
{
|
{
|
||||||
intersection = leftHit0;
|
interPt = leftHit[i];
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update *this from intersection point
|
|
||||||
|
|
||||||
if (intersection.hit())
|
if (interPt.hit())
|
||||||
{
|
{
|
||||||
point interPt = intersection.hitPoint();
|
|
||||||
|
|
||||||
if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
|
if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
|
||||||
{
|
{
|
||||||
interPt[wedgePlane_] += offset;
|
interPt.rawPoint()[wedgePlane_] += offset[i];
|
||||||
}
|
}
|
||||||
displacement[i] = interPt-points0[meshPoints[i]];
|
displacement[i] = interPt.rawPoint()-points0[meshPoints[i]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Pout<< " point:" << meshPoints[i]
|
Pout<< " point:" << meshPoints[i]
|
||||||
<< " coord:" << localPoints[i]
|
<< " coord:" << localPoints[i]
|
||||||
<< " did not find any intersection between ray from "
|
<< " did not find any intersection between ray from "
|
||||||
<< start-projectVec << " to " << start+projectVec
|
<< start[i]-projectVecs[i]
|
||||||
|
<< " to " << start[i]+projectVecs[i]
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get internal field to insert values into
|
// Get internal field to insert values into
|
||||||
Field<vector>& iF = const_cast<Field<vector>&>(this->internalField());
|
Field<vector>& iF = const_cast<Field<vector>&>(this->internalField());
|
||||||
@ -353,7 +404,7 @@ void surfaceSlipDisplacementPointPatchVectorField::evaluate
|
|||||||
void surfaceSlipDisplacementPointPatchVectorField::write(Ostream& os) const
|
void surfaceSlipDisplacementPointPatchVectorField::write(Ostream& os) const
|
||||||
{
|
{
|
||||||
pointPatchVectorField::write(os);
|
pointPatchVectorField::write(os);
|
||||||
os.writeKeyword("projectSurfaces") << surfaceNames_
|
os.writeKeyword("geometry") << surfacesDict_
|
||||||
<< token::END_STATEMENT << nl;
|
<< token::END_STATEMENT << nl;
|
||||||
os.writeKeyword("followMode") << followModeNames_[projectMode_]
|
os.writeKeyword("followMode") << followModeNames_[projectMode_]
|
||||||
<< token::END_STATEMENT << nl;
|
<< token::END_STATEMENT << nl;
|
||||||
|
|||||||
@ -52,7 +52,7 @@ SourceFiles
|
|||||||
#define surfaceSlipDisplacementPointPatchVectorField_H
|
#define surfaceSlipDisplacementPointPatchVectorField_H
|
||||||
|
|
||||||
#include "pointPatchFields.H"
|
#include "pointPatchFields.H"
|
||||||
#include "triSurfaceMeshes.H"
|
#include "searchableSurfaces.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ private:
|
|||||||
static const NamedEnum<followMode, 3> followModeNames_;
|
static const NamedEnum<followMode, 3> followModeNames_;
|
||||||
|
|
||||||
//- names of surfaces
|
//- names of surfaces
|
||||||
const fileNameList surfaceNames_;
|
const dictionary surfacesDict_;
|
||||||
|
|
||||||
//- How to follow/project onto surface
|
//- How to follow/project onto surface
|
||||||
const followMode projectMode_;
|
const followMode projectMode_;
|
||||||
@ -102,7 +102,7 @@ private:
|
|||||||
const word frozenPointsZone_;
|
const word frozenPointsZone_;
|
||||||
|
|
||||||
//- Demand driven: surface to follow
|
//- Demand driven: surface to follow
|
||||||
mutable autoPtr<triSurfaceMeshes> surfacesPtr_;
|
mutable autoPtr<searchableSurfaces> surfacesPtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
@ -187,13 +187,13 @@ public:
|
|||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Surfaces to follow
|
//- Surfaces to follow
|
||||||
const fileNameList& surfaceNames() const
|
const dictionary& surfacesDict() const
|
||||||
{
|
{
|
||||||
return surfaceNames_;
|
return surfacesDict_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Surface to follow. Demand loads surfaceNames.
|
//- Surface to follow. Demand loads surfaceNames.
|
||||||
const triSurfaceMeshes& surfaces() const;
|
const searchableSurfaces& surfaces() const;
|
||||||
|
|
||||||
//- Mode of projection/following
|
//- Mode of projection/following
|
||||||
followMode projectMode() const
|
followMode projectMode() const
|
||||||
|
|||||||
@ -53,6 +53,14 @@ indexedOctree/treeDataFace.C
|
|||||||
indexedOctree/treeDataPoint.C
|
indexedOctree/treeDataPoint.C
|
||||||
indexedOctree/treeDataTriSurface.C
|
indexedOctree/treeDataTriSurface.C
|
||||||
|
|
||||||
|
searchableSurface = searchableSurface
|
||||||
|
$(searchableSurface)/searchableBox.C
|
||||||
|
$(searchableSurface)/searchableSphere.C
|
||||||
|
$(searchableSurface)/searchableSurface.C
|
||||||
|
$(searchableSurface)/searchableSurfaces.C
|
||||||
|
$(searchableSurface)/searchableSurfacesQueries.C
|
||||||
|
$(searchableSurface)/triSurfaceMesh.C
|
||||||
|
|
||||||
topoSets = sets/topoSets
|
topoSets = sets/topoSets
|
||||||
$(topoSets)/cellSet.C
|
$(topoSets)/cellSet.C
|
||||||
$(topoSets)/topoSet.C
|
$(topoSets)/topoSet.C
|
||||||
@ -117,20 +125,10 @@ $(intersectedSurface)/intersectedSurface.C
|
|||||||
$(intersectedSurface)/edgeSurface.C
|
$(intersectedSurface)/edgeSurface.C
|
||||||
|
|
||||||
triSurface/triSurfaceSearch/triSurfaceSearch.C
|
triSurface/triSurfaceSearch/triSurfaceSearch.C
|
||||||
|
|
||||||
triSurface/octreeData/octreeDataTriSurface.C
|
triSurface/octreeData/octreeDataTriSurface.C
|
||||||
triSurface/octreeData/octreeDataTriSurfaceTreeLeaf.C
|
triSurface/octreeData/octreeDataTriSurfaceTreeLeaf.C
|
||||||
|
|
||||||
triSurface/triangleFuncs/triangleFuncs.C
|
triSurface/triangleFuncs/triangleFuncs.C
|
||||||
|
|
||||||
triSurface/searchableSurface/searchableSurface.C
|
|
||||||
triSurface/searchableSurface/triSurfaceMesh.C
|
|
||||||
triSurface/searchableSurface/searchableBox.C
|
|
||||||
|
|
||||||
triSurface/surfaceFeatures/surfaceFeatures.C
|
triSurface/surfaceFeatures/surfaceFeatures.C
|
||||||
|
|
||||||
triSurface/triSurfaceMeshes/triSurfaceMeshes.C
|
|
||||||
|
|
||||||
triSurface/triSurfaceTools/triSurfaceTools.C
|
triSurface/triSurfaceTools/triSurfaceTools.C
|
||||||
triSurface/triSurfaceTools/geompack/geompack.C
|
triSurface/triSurfaceTools/geompack/geompack.C
|
||||||
|
|
||||||
|
|||||||
541
src/meshTools/searchableSurface/searchableBox.C
Normal file
541
src/meshTools/searchableSurface/searchableBox.C
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "searchableBox.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "SortableList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(searchableBox, 0);
|
||||||
|
addToRunTimeSelectionTable(searchableSurface, searchableBox, dict);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::searchableBox::projectOntoCoordPlane
|
||||||
|
(
|
||||||
|
const direction dir,
|
||||||
|
const point& planePt,
|
||||||
|
pointIndexHit& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Set point
|
||||||
|
info.rawPoint()[dir] = planePt[dir];
|
||||||
|
// Set face
|
||||||
|
if (planePt[dir] == min()[dir])
|
||||||
|
{
|
||||||
|
info.setIndex(dir*2);
|
||||||
|
}
|
||||||
|
else if (planePt[dir] == max()[dir])
|
||||||
|
{
|
||||||
|
info.setIndex(dir*2+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn("searchableBox::projectOntoCoordPlane(..)")
|
||||||
|
<< "Point on plane " << planePt
|
||||||
|
<< " is not on coordinate " << min()[dir]
|
||||||
|
<< " nor " << max()[dir] << abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns miss or hit with face (0..5) and region(always 0)
|
||||||
|
Foam::pointIndexHit Foam::searchableBox::findNearest
|
||||||
|
(
|
||||||
|
const point& bbMid,
|
||||||
|
const point& sample,
|
||||||
|
const scalar nearestDistSqr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Point can be inside or outside. For every component direction can be
|
||||||
|
// left of min, right of max or inbetween.
|
||||||
|
// - outside points: project first one x plane (either min().x()
|
||||||
|
// or max().x()), then onto y plane and finally z. You should be left
|
||||||
|
// with intersection point
|
||||||
|
// - inside point: find nearest side (compare to mid point). Project onto
|
||||||
|
// that.
|
||||||
|
|
||||||
|
// The face is set to the last projected face.
|
||||||
|
|
||||||
|
|
||||||
|
// Outside point projected onto cube. Assume faces 0..5.
|
||||||
|
pointIndexHit info(true, sample, -1);
|
||||||
|
bool outside = false;
|
||||||
|
|
||||||
|
// (for internal points) per direction what nearest cube side is
|
||||||
|
point near;
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||||
|
{
|
||||||
|
if (info.rawPoint()[dir] < min()[dir])
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(dir, min(), info);
|
||||||
|
outside = true;
|
||||||
|
}
|
||||||
|
else if (info.rawPoint()[dir] > max()[dir])
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(dir, max(), info);
|
||||||
|
outside = true;
|
||||||
|
}
|
||||||
|
else if (info.rawPoint()[dir] > bbMid[dir])
|
||||||
|
{
|
||||||
|
near[dir] = max()[dir];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
near[dir] = min()[dir];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For outside points the info will be correct now. Handle inside points
|
||||||
|
// using the three near distances. Project onto the nearest plane.
|
||||||
|
if (!outside)
|
||||||
|
{
|
||||||
|
vector dist(cmptMag(info.rawPoint() - near));
|
||||||
|
|
||||||
|
if (dist.x() < dist.y())
|
||||||
|
{
|
||||||
|
if (dist.x() < dist.z())
|
||||||
|
{
|
||||||
|
// Project onto x plane
|
||||||
|
projectOntoCoordPlane(vector::X, near, info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(vector::Z, near, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dist.y() < dist.z())
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(vector::Y, near, info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(vector::Z, near, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if outside. Optimisation: could do some checks on distance already
|
||||||
|
// on components above
|
||||||
|
if (magSqr(info.rawPoint() - sample) > nearestDistSqr)
|
||||||
|
{
|
||||||
|
info.setMiss();
|
||||||
|
info.setIndex(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableBox::searchableBox
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const treeBoundBox& bb
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
treeBoundBox(bb)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::searchableBox::searchableBox
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
treeBoundBox(dict.lookup("min"), dict.lookup("max"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableBox::~searchableBox()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::wordList& Foam::searchableBox::regions() const
|
||||||
|
{
|
||||||
|
if (regions_.size() == 0)
|
||||||
|
{
|
||||||
|
regions_.setSize(1);
|
||||||
|
regions_[0] = "region0";
|
||||||
|
}
|
||||||
|
return regions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableBox::findNearest
|
||||||
|
(
|
||||||
|
const point& sample,
|
||||||
|
const scalar nearestDistSqr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return findNearest(mid(), sample, nearestDistSqr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableBox::findNearestOnEdge
|
||||||
|
(
|
||||||
|
const point& sample,
|
||||||
|
const scalar nearestDistSqr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const point bbMid(mid());
|
||||||
|
|
||||||
|
// Outside point projected onto cube. Assume faces 0..5.
|
||||||
|
pointIndexHit info(true, sample, -1);
|
||||||
|
bool outside = false;
|
||||||
|
|
||||||
|
// (for internal points) per direction what nearest cube side is
|
||||||
|
point near;
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||||
|
{
|
||||||
|
if (info.rawPoint()[dir] < min()[dir])
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(dir, min(), info);
|
||||||
|
outside = true;
|
||||||
|
}
|
||||||
|
else if (info.rawPoint()[dir] > max()[dir])
|
||||||
|
{
|
||||||
|
projectOntoCoordPlane(dir, max(), info);
|
||||||
|
outside = true;
|
||||||
|
}
|
||||||
|
else if (info.rawPoint()[dir] > bbMid[dir])
|
||||||
|
{
|
||||||
|
near[dir] = max()[dir];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
near[dir] = min()[dir];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For outside points the info will be correct now. Handle inside points
|
||||||
|
// using the three near distances. Project onto the nearest two planes.
|
||||||
|
if (!outside)
|
||||||
|
{
|
||||||
|
// Get the per-component distance to nearest wall
|
||||||
|
vector dist(cmptMag(info.rawPoint() - near));
|
||||||
|
|
||||||
|
SortableList<scalar> sortedDist(3);
|
||||||
|
sortedDist[0] = dist[0];
|
||||||
|
sortedDist[1] = dist[1];
|
||||||
|
sortedDist[2] = dist[2];
|
||||||
|
sortedDist.sort();
|
||||||
|
|
||||||
|
// Project onto nearest
|
||||||
|
projectOntoCoordPlane(sortedDist.indices()[0], near, info);
|
||||||
|
// Project onto second nearest
|
||||||
|
projectOntoCoordPlane(sortedDist.indices()[1], near, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if outside. Optimisation: could do some checks on distance already
|
||||||
|
// on components above
|
||||||
|
if (magSqr(info.rawPoint() - sample) > nearestDistSqr)
|
||||||
|
{
|
||||||
|
info.setMiss();
|
||||||
|
info.setIndex(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableBox::findNearest
|
||||||
|
(
|
||||||
|
const linePointRef& ln,
|
||||||
|
treeBoundBox& tightest,
|
||||||
|
point& linePoint
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
notImplemented
|
||||||
|
(
|
||||||
|
"searchableBox::findNearest"
|
||||||
|
"(const linePointRef&, treeBoundBox&, point&)"
|
||||||
|
);
|
||||||
|
return pointIndexHit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableBox::findLine
|
||||||
|
(
|
||||||
|
const point& start,
|
||||||
|
const point& end
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
pointIndexHit info(false, start, -1);
|
||||||
|
|
||||||
|
bool foundInter;
|
||||||
|
|
||||||
|
if (posBits(start) == 0)
|
||||||
|
{
|
||||||
|
if (posBits(end) == 0)
|
||||||
|
{
|
||||||
|
// Both start and end inside.
|
||||||
|
foundInter = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// end is outside. Clip to bounding box.
|
||||||
|
foundInter = intersects(end, start, info.rawPoint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// start is outside. Clip to bounding box.
|
||||||
|
foundInter = intersects(start, end, info.rawPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Classify point
|
||||||
|
if (foundInter)
|
||||||
|
{
|
||||||
|
info.setHit();
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||||
|
{
|
||||||
|
if (info.rawPoint()[dir] == min()[dir])
|
||||||
|
{
|
||||||
|
info.setIndex(2*dir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (info.rawPoint()[dir] == max()[dir])
|
||||||
|
{
|
||||||
|
info.setIndex(2*dir+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.index() == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn("searchableBox::findLine(const point&, const point&)")
|
||||||
|
<< "point " << info.rawPoint()
|
||||||
|
<< " on segment " << start << end
|
||||||
|
<< " should be on face of " << *this
|
||||||
|
<< " but it isn't." << abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableBox::findLineAny
|
||||||
|
(
|
||||||
|
const point& start,
|
||||||
|
const point& end
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return findLine(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableBox::findNearest
|
||||||
|
(
|
||||||
|
const pointField& samples,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
List<pointIndexHit>& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
info.setSize(samples.size());
|
||||||
|
|
||||||
|
const point bbMid(mid());
|
||||||
|
|
||||||
|
forAll(samples, i)
|
||||||
|
{
|
||||||
|
info[i] = findNearest(bbMid, samples[i], nearestDistSqr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableBox::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::searchableBox::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::searchableBox::findLineAll
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<List<pointIndexHit> >& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
// Work array
|
||||||
|
DynamicList<pointIndexHit, 1, 1> hits;
|
||||||
|
|
||||||
|
// Tolerances
|
||||||
|
const vectorField dirVec(end-start);
|
||||||
|
const scalarField magSqrDirVec(magSqr(dirVec));
|
||||||
|
const vectorField smallVec
|
||||||
|
(
|
||||||
|
Foam::sqrt(SMALL)*dirVec
|
||||||
|
+ vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(start, pointI)
|
||||||
|
{
|
||||||
|
hits.clear();
|
||||||
|
|
||||||
|
// Current starting point of ray.
|
||||||
|
point pt = start[pointI];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// See if any intersection between pt and end
|
||||||
|
pointIndexHit inter = findLine(pt, end[pointI]);
|
||||||
|
|
||||||
|
if (!inter.hit())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hits.append(inter);
|
||||||
|
|
||||||
|
pt = inter.hitPoint() + smallVec[pointI];
|
||||||
|
|
||||||
|
if (((pt-start[pointI])&dirVec[pointI]) > magSqrDirVec[pointI])
|
||||||
|
{
|
||||||
|
// Adding smallVec has taken us beyond end
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hits.shrink();
|
||||||
|
info[pointI].transfer(hits);
|
||||||
|
hits.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableBox::getRegion
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>& info,
|
||||||
|
labelList& region
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
region.setSize(info.size());
|
||||||
|
region = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableBox::getNormal
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>& info,
|
||||||
|
vectorField& normal
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
normal.setSize(info.size());
|
||||||
|
normal = vector::zero;
|
||||||
|
|
||||||
|
forAll(info, i)
|
||||||
|
{
|
||||||
|
if (info[i].hit())
|
||||||
|
{
|
||||||
|
normal[i] = treeBoundBox::faceNormals[info[i].index()];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set to what?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableBox::getVolumeType
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
List<volumeType>& volType
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
volType.setSize(points.size());
|
||||||
|
volType = INSIDE;
|
||||||
|
|
||||||
|
forAll(points, pointI)
|
||||||
|
{
|
||||||
|
const point& pt = points[pointI];
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||||
|
{
|
||||||
|
if (pt[dir] < min()[dir] || pt[dir] > max()[dir])
|
||||||
|
{
|
||||||
|
volType[pointI] = OUTSIDE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
249
src/meshTools/searchableSurface/searchableBox.H
Normal file
249
src/meshTools/searchableSurface/searchableBox.H
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableBox
|
||||||
|
|
||||||
|
Description
|
||||||
|
Searching on bounding box
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
searchableBox.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef searchableBox_H
|
||||||
|
#define searchableBox_H
|
||||||
|
|
||||||
|
#include "searchableSurface.H"
|
||||||
|
#include "treeBoundBox.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class searchableBox Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class searchableBox
|
||||||
|
:
|
||||||
|
public searchableSurface,
|
||||||
|
public treeBoundBox
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
mutable wordList regions_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Project onto component dir of planePt and update index() (=face)
|
||||||
|
void projectOntoCoordPlane
|
||||||
|
(
|
||||||
|
const direction dir,
|
||||||
|
const point& planePt,
|
||||||
|
pointIndexHit& info
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Returns miss or hit with face (0..5)
|
||||||
|
pointIndexHit findNearest
|
||||||
|
(
|
||||||
|
const point& bbMid,
|
||||||
|
const point& sample,
|
||||||
|
const scalar nearestDistSqr
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
searchableBox(const searchableBox&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const searchableBox&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("searchableBox");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
searchableBox(const IOobject& io, const treeBoundBox& bb);
|
||||||
|
|
||||||
|
//- Construct from dictionary (used by searchableSurface)
|
||||||
|
searchableBox
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
|
||||||
|
virtual ~searchableBox();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual const wordList& regions() const;
|
||||||
|
|
||||||
|
//- Whether supports volume type below
|
||||||
|
virtual bool hasVolumeType() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
//- Calculate nearest point on edge. Returns
|
||||||
|
// - bool : any point found nearer than nearestDistSqr
|
||||||
|
// - label: relevant index in surface(=?)
|
||||||
|
// - point: actual nearest point found
|
||||||
|
pointIndexHit findNearestOnEdge
|
||||||
|
(
|
||||||
|
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("searchableBox::writeData(Ostream&) const");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
328
src/meshTools/searchableSurface/searchableSphere.C
Normal file
328
src/meshTools/searchableSurface/searchableSphere.C
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "searchableSphere.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "SortableList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(searchableSphere, 0);
|
||||||
|
addToRunTimeSelectionTable(searchableSurface, searchableSphere, dict);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableSphere::findNearest
|
||||||
|
(
|
||||||
|
const point& sample,
|
||||||
|
const scalar nearestDistSqr
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
pointIndexHit info(false, sample, -1);
|
||||||
|
|
||||||
|
const vector n(sample-centre_);
|
||||||
|
scalar magN = mag(n);
|
||||||
|
|
||||||
|
if (nearestDistSqr > sqr(magN-radius_))
|
||||||
|
{
|
||||||
|
info.rawPoint() = centre_ + n/magN*radius_;
|
||||||
|
info.setHit();
|
||||||
|
info.setIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// From Graphics Gems - intersection of sphere with ray
|
||||||
|
void Foam::searchableSphere::findLineAll
|
||||||
|
(
|
||||||
|
const point& start,
|
||||||
|
const point& end,
|
||||||
|
pointIndexHit& near,
|
||||||
|
pointIndexHit& far
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
near.setMiss();
|
||||||
|
far.setMiss();
|
||||||
|
|
||||||
|
vector dir(end-start);
|
||||||
|
scalar magSqrDir = magSqr(dir);
|
||||||
|
|
||||||
|
if (magSqrDir > ROOTVSMALL)
|
||||||
|
{
|
||||||
|
const vector toCentre(centre_-start);
|
||||||
|
scalar magSqrToCentre = magSqr(toCentre);
|
||||||
|
|
||||||
|
dir /= Foam::sqrt(magSqrDir);
|
||||||
|
|
||||||
|
scalar v = (toCentre & dir);
|
||||||
|
|
||||||
|
scalar disc = sqr(radius_) - (magSqrToCentre - sqr(v));
|
||||||
|
|
||||||
|
if (disc >= 0)
|
||||||
|
{
|
||||||
|
scalar d = Foam::sqrt(disc);
|
||||||
|
|
||||||
|
scalar nearParam = v-d;
|
||||||
|
|
||||||
|
if (nearParam >= 0 && sqr(nearParam) <= magSqrDir)
|
||||||
|
{
|
||||||
|
near.setHit();
|
||||||
|
near.setPoint(start + nearParam*dir);
|
||||||
|
near.setIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar farParam = v+d;
|
||||||
|
|
||||||
|
if (farParam >= 0 && sqr(farParam) <= magSqrDir)
|
||||||
|
{
|
||||||
|
far.setHit();
|
||||||
|
far.setPoint(start + farParam*dir);
|
||||||
|
far.setIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSphere::searchableSphere
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const point& centre,
|
||||||
|
const scalar radius
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
centre_(centre),
|
||||||
|
radius_(radius)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::searchableSphere::searchableSphere
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
centre_(dict.lookup("centre")),
|
||||||
|
radius_(readScalar(dict.lookup("radius")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSphere::~searchableSphere()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::wordList& Foam::searchableSphere::regions() const
|
||||||
|
{
|
||||||
|
if (regions_.size() == 0)
|
||||||
|
{
|
||||||
|
regions_.setSize(1);
|
||||||
|
regions_[0] = "region0";
|
||||||
|
}
|
||||||
|
return regions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSphere::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::searchableSphere::findLine
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<pointIndexHit>& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
pointIndexHit b;
|
||||||
|
|
||||||
|
forAll(start, i)
|
||||||
|
{
|
||||||
|
// Pick nearest intersection. If none intersected take second one.
|
||||||
|
findLineAll(start[i], end[i], info[i], b);
|
||||||
|
if (!info[i].hit() && b.hit())
|
||||||
|
{
|
||||||
|
info[i] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSphere::findLineAny
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<pointIndexHit>& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
pointIndexHit b;
|
||||||
|
|
||||||
|
forAll(start, i)
|
||||||
|
{
|
||||||
|
// Discard far intersection
|
||||||
|
findLineAll(start[i], end[i], info[i], b);
|
||||||
|
if (!info[i].hit() && b.hit())
|
||||||
|
{
|
||||||
|
info[i] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSphere::findLineAll
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<List<pointIndexHit> >& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
pointIndexHit near, far;
|
||||||
|
|
||||||
|
forAll(start, i)
|
||||||
|
{
|
||||||
|
findLineAll(start[i], end[i], near, far);
|
||||||
|
|
||||||
|
if (near.hit())
|
||||||
|
{
|
||||||
|
if (far.hit())
|
||||||
|
{
|
||||||
|
info[i].setSize(2);
|
||||||
|
info[i][0] = near;
|
||||||
|
info[i][1] = far;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info[i].setSize(1);
|
||||||
|
info[i][0] = near;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (far.hit())
|
||||||
|
{
|
||||||
|
info[i].setSize(1);
|
||||||
|
info[i][0] = far;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSphere::getRegion
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>& info,
|
||||||
|
labelList& region
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
region.setSize(info.size());
|
||||||
|
region = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSphere::getNormal
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>& info,
|
||||||
|
vectorField& normal
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
normal.setSize(info.size());
|
||||||
|
normal = vector::zero;
|
||||||
|
|
||||||
|
forAll(info, i)
|
||||||
|
{
|
||||||
|
if (info[i].hit())
|
||||||
|
{
|
||||||
|
normal[i] = info[i].hitPoint() - centre_;
|
||||||
|
normal[i] /= mag(normal[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set to what?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSphere::getVolumeType
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
List<volumeType>& volType
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
volType.setSize(points.size());
|
||||||
|
volType = INSIDE;
|
||||||
|
|
||||||
|
forAll(points, pointI)
|
||||||
|
{
|
||||||
|
const point& pt = points[pointI];
|
||||||
|
|
||||||
|
if (magSqr(pt - centre_) <= sqr(radius_))
|
||||||
|
{
|
||||||
|
volType[pointI] = INSIDE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
volType[pointI] = OUTSIDE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
204
src/meshTools/searchableSurface/searchableSphere.H
Normal file
204
src/meshTools/searchableSurface/searchableSphere.H
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSphere
|
||||||
|
|
||||||
|
Description
|
||||||
|
Searching on sphere
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
searchableSphere.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef searchableSphere_H
|
||||||
|
#define searchableSphere_H
|
||||||
|
|
||||||
|
#include "searchableSurface.H"
|
||||||
|
#include "treeBoundBox.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class searchableSphere Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class searchableSphere
|
||||||
|
:
|
||||||
|
public searchableSurface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
//- Centre point
|
||||||
|
const point centre_;
|
||||||
|
|
||||||
|
//- Radius squared
|
||||||
|
const scalar radius_;
|
||||||
|
|
||||||
|
//- Names of regions
|
||||||
|
mutable wordList regions_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Find nearest point on sphere.
|
||||||
|
pointIndexHit findNearest
|
||||||
|
(
|
||||||
|
const point& sample,
|
||||||
|
const scalar nearestDistSqr
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Find intersection with sphere
|
||||||
|
void findLineAll
|
||||||
|
(
|
||||||
|
const point& start,
|
||||||
|
const point& end,
|
||||||
|
pointIndexHit& near,
|
||||||
|
pointIndexHit& far
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
searchableSphere(const searchableSphere&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const searchableSphere&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("searchableSphere");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
searchableSphere(const IOobject& io, const point&, const scalar radius);
|
||||||
|
|
||||||
|
//- Construct from dictionary (used by searchableSurface)
|
||||||
|
searchableSphere
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
|
||||||
|
virtual ~searchableSphere();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual const wordList& regions() const;
|
||||||
|
|
||||||
|
//- Whether supports volume type below
|
||||||
|
virtual bool hasVolumeType() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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("searchableSphere::writeData(Ostream&) const");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -34,15 +34,13 @@ namespace Foam
|
|||||||
|
|
||||||
defineTypeNameAndDebug(searchableSurface, 0);
|
defineTypeNameAndDebug(searchableSurface, 0);
|
||||||
defineRunTimeSelectionTable(searchableSurface, dict);
|
defineRunTimeSelectionTable(searchableSurface, dict);
|
||||||
//defineRunTimeSelectionTable(searchableSurface, istream);
|
|
||||||
|
|
||||||
|
|
||||||
// Construct named object from dictionary
|
// Construct named object from dictionary
|
||||||
autoPtr<searchableSurface> searchableSurface::New
|
autoPtr<searchableSurface> searchableSurface::New
|
||||||
(
|
(
|
||||||
const word& searchableSurfaceType,
|
const word& searchableSurfaceType,
|
||||||
const word& name,
|
const IOobject& io,
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -55,7 +53,7 @@ autoPtr<searchableSurface> searchableSurface::New
|
|||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"searchableSurface::New(const word&, const word&"
|
"searchableSurface::New(const word&, const word&"
|
||||||
", const objectRegistry&, const dictionary&)"
|
", const IOobject&, const dictionary&)"
|
||||||
) << "Unknown searchableSurface type " << searchableSurfaceType
|
) << "Unknown searchableSurface type " << searchableSurfaceType
|
||||||
<< endl << endl
|
<< endl << endl
|
||||||
<< "Valid searchableSurface types : " << endl
|
<< "Valid searchableSurface types : " << endl
|
||||||
@ -63,44 +61,15 @@ autoPtr<searchableSurface> searchableSurface::New
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
return autoPtr<searchableSurface>(cstrIter()(name, obj, dict));
|
return autoPtr<searchableSurface>(cstrIter()(io, dict));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Construct named object from Istream
|
|
||||||
//autoPtr<searchableSurface> searchableSurface::New
|
|
||||||
//(
|
|
||||||
// const word& searchableSurfaceType,
|
|
||||||
// const objectRegistry& obj,
|
|
||||||
// Istream& is
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// istreamConstructorTable::iterator cstrIter =
|
|
||||||
// istreamConstructorTablePtr_
|
|
||||||
// ->find(searchableSurfaceType);
|
|
||||||
//
|
|
||||||
// if (cstrIter == istreamConstructorTablePtr_->end())
|
|
||||||
// {
|
|
||||||
// FatalErrorIn
|
|
||||||
// (
|
|
||||||
// "searchableSurface::New(const word&, const objectRegistry&"
|
|
||||||
// ", Istream&)"
|
|
||||||
// ) << "Unknown searchableSurface type " << searchableSurfaceType
|
|
||||||
// << endl << endl
|
|
||||||
// << "Valid searchableSurface types : " << endl
|
|
||||||
// << istreamConstructorTablePtr_->toc()
|
|
||||||
// << exit(FatalError);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return autoPtr<searchableSurface>(cstrIter()(obj, is));
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::searchableSurface::searchableSurface(const word& name)
|
Foam::searchableSurface::searchableSurface(const IOobject& io)
|
||||||
:
|
:
|
||||||
name_(name)
|
regIOobject(io)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
322
src/meshTools/searchableSurface/searchableSurface.H
Normal file
322
src/meshTools/searchableSurface/searchableSurface.H
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSurface
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class of (analytical or triangulated) surface.
|
||||||
|
Encapsulates all the search routines. WIP.
|
||||||
|
|
||||||
|
Information returned is usually a pointIndexHit:
|
||||||
|
- bool : was intersection/nearest found?
|
||||||
|
- point : intersection point or nearest point
|
||||||
|
- index : unique index on surface (e.g. triangle for triSurfaceMesh)
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
searchableSurface.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef searchableSurface_H
|
||||||
|
#define searchableSurface_H
|
||||||
|
|
||||||
|
#include "pointField.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "pointIndexHit.H"
|
||||||
|
#include "linePointRef.H"
|
||||||
|
#include "objectRegistry.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class objectRegistry;
|
||||||
|
class treeBoundBox;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class searchableSurface Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class searchableSurface
|
||||||
|
:
|
||||||
|
public regIOobject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Data types
|
||||||
|
|
||||||
|
//- volume types
|
||||||
|
enum volumeType
|
||||||
|
{
|
||||||
|
UNKNOWN = 0,
|
||||||
|
MIXED = 1, // not used. only here to maintain consistency with
|
||||||
|
// indexedOctree volumeType.
|
||||||
|
INSIDE = 2,
|
||||||
|
OUTSIDE = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
const word name_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
searchableSurface(const searchableSurface&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const searchableSurface&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("searchableSurface");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
// For the dictionary constructor
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
searchableSurface,
|
||||||
|
dict,
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
),
|
||||||
|
(io, dict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Class used for the read-construction of
|
||||||
|
// PtrLists of searchableSurface.
|
||||||
|
class iNew
|
||||||
|
{
|
||||||
|
IOobject& io_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
iNew(IOobject& io)
|
||||||
|
:
|
||||||
|
io_(io)
|
||||||
|
{}
|
||||||
|
|
||||||
|
autoPtr<searchableSurface> operator()(Istream& is) const
|
||||||
|
{
|
||||||
|
word surfaceType(is);
|
||||||
|
word readName(is);
|
||||||
|
dictionary dict(is);
|
||||||
|
|
||||||
|
autoPtr<IOobject> namedIO(io_.clone());
|
||||||
|
namedIO().rename(readName);
|
||||||
|
return searchableSurface::New(surfaceType, namedIO(), dict);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
searchableSurface(const IOobject& io);
|
||||||
|
|
||||||
|
//- Clone
|
||||||
|
virtual autoPtr<searchableSurface> clone() const
|
||||||
|
{
|
||||||
|
notImplemented("autoPtr<searchableSurface> clone() const");
|
||||||
|
return autoPtr<searchableSurface>(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected searchableSurface
|
||||||
|
static autoPtr<searchableSurface> New
|
||||||
|
(
|
||||||
|
const word& surfaceType,
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
|
||||||
|
virtual ~searchableSurface();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
|
||||||
|
//- Names of regions.
|
||||||
|
virtual const wordList& regions() const = 0;
|
||||||
|
|
||||||
|
//- Whether supports volume type below.
|
||||||
|
virtual bool hasVolumeType() const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Single point queries.
|
||||||
|
|
||||||
|
////- Calculate nearest point on surface. Returns
|
||||||
|
//// - bool : any point found nearer than nearestDistSqr
|
||||||
|
//// - label: relevant index in surface
|
||||||
|
//// - label: region in surface
|
||||||
|
//// - point: actual nearest point found
|
||||||
|
//virtual pointIndexHit findNearest
|
||||||
|
//(
|
||||||
|
// const point& sample,
|
||||||
|
// const scalar nearestDistSqr
|
||||||
|
//) const = 0;
|
||||||
|
//
|
||||||
|
////- Calculate nearest point on edge. Returns
|
||||||
|
//// - bool : any point found nearer than nearestDistSqr
|
||||||
|
//// - label: relevant index in surface
|
||||||
|
//// - label: region in surface
|
||||||
|
//// - point: actual nearest point found
|
||||||
|
//virtual pointIndexHit findNearestOnEdge
|
||||||
|
//(
|
||||||
|
// const point& sample,
|
||||||
|
// const scalar nearestDistSqr
|
||||||
|
//) const = 0;
|
||||||
|
//
|
||||||
|
////- Find nearest to segment. Returns
|
||||||
|
//// - bool : any point found?
|
||||||
|
//// - label: relevant index in shapes
|
||||||
|
//// - label: region in surface
|
||||||
|
//// - point: actual nearest point found
|
||||||
|
//// sets:
|
||||||
|
//// - tightest : bounding box
|
||||||
|
//// - linePoint : corresponding nearest point on line
|
||||||
|
//virtual pointIndexHit findNearest
|
||||||
|
//(
|
||||||
|
// const linePointRef& ln,
|
||||||
|
// treeBoundBox& tightest,
|
||||||
|
// point& linePoint
|
||||||
|
//) const = 0;
|
||||||
|
//
|
||||||
|
////- Find nearest intersection of line between start and end.
|
||||||
|
//virtual pointIndexHit findLine
|
||||||
|
//(
|
||||||
|
// const point& start,
|
||||||
|
// const point& end
|
||||||
|
//) const = 0;
|
||||||
|
//
|
||||||
|
////- Find any intersection of line between start and end.
|
||||||
|
//virtual pointIndexHit findLineAny
|
||||||
|
//(
|
||||||
|
// const point& start,
|
||||||
|
// const point& end
|
||||||
|
//) const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Multiple point queries. When surface is distributed the index
|
||||||
|
// should be a global index. Not done yet.
|
||||||
|
|
||||||
|
virtual void findNearest
|
||||||
|
(
|
||||||
|
const pointField& sample,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- Find first intersection on segment from start to end.
|
||||||
|
// Note: searchableSurfacesQueries expects no
|
||||||
|
// intersection to be found if start==end. Is problem?
|
||||||
|
virtual void findLine
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- Return any intersection on segment from start to end.
|
||||||
|
virtual void findLineAny
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- Get all intersections in order from start to end.
|
||||||
|
virtual void findLineAll
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<List<pointIndexHit> >&
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- From a set of points and indices get the region
|
||||||
|
virtual void getRegion
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>&,
|
||||||
|
labelList& region
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- From a set of points and indices get the normal
|
||||||
|
virtual void getNormal
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>&,
|
||||||
|
vectorField& normal
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
//- Determine type (inside/outside) for point. unknown if
|
||||||
|
// cannot be determined (e.g. non-manifold surface)
|
||||||
|
virtual void getVolumeType
|
||||||
|
(
|
||||||
|
const pointField&,
|
||||||
|
List<volumeType>&
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
////- Get bounding box.
|
||||||
|
//const boundBox& bounds() const = 0;
|
||||||
|
|
||||||
|
////- Set bounding box.
|
||||||
|
//void setBounds
|
||||||
|
//(
|
||||||
|
// const boundBox&,
|
||||||
|
// autoPtr<mapDistribute>& faceMap,
|
||||||
|
// autoPtr<mapDistribute>& pointMap
|
||||||
|
//) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
355
src/meshTools/searchableSurface/searchableSurfaces.C
Normal file
355
src/meshTools/searchableSurface/searchableSurfaces.C
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "searchableSurfaces.H"
|
||||||
|
#include "searchableSurfacesQueries.H"
|
||||||
|
#include "ListOps.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(searchableSurfaces, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Construct with length.
|
||||||
|
Foam::searchableSurfaces::searchableSurfaces(const label size)
|
||||||
|
:
|
||||||
|
PtrList<searchableSurface>(size),
|
||||||
|
regionNames_(size),
|
||||||
|
allSurfaces_(identity(size))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
//Foam::searchableSurfaces::searchableSurfaces
|
||||||
|
//(
|
||||||
|
// const IOobject& io,
|
||||||
|
// const PtrList<dictionary>& dicts
|
||||||
|
//)
|
||||||
|
//:
|
||||||
|
// PtrList<searchableSurface>(dicts.size()),
|
||||||
|
// regionNames_(dicts.size()),
|
||||||
|
// allSurfaces_(identity(dicts.size()))
|
||||||
|
//{
|
||||||
|
// forAll(dicts, surfI)
|
||||||
|
// {
|
||||||
|
// const dictionary& dict = dicts[surfI];
|
||||||
|
//
|
||||||
|
// // Make IOobject with correct name
|
||||||
|
// autoPtr<IOobject> namedIO(io.clone());
|
||||||
|
// namedIO().rename(dict.lookup("name"));
|
||||||
|
//
|
||||||
|
// // Create and hook surface
|
||||||
|
// set
|
||||||
|
// (
|
||||||
|
// surfI,
|
||||||
|
// searchableSurface::New
|
||||||
|
// (
|
||||||
|
// dict.lookup("type"),
|
||||||
|
// namedIO(),
|
||||||
|
// dict
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// const searchableSurface& s = operator[](surfI);
|
||||||
|
//
|
||||||
|
// // Construct default region names by prepending surface name
|
||||||
|
// // to region name.
|
||||||
|
// const wordList& localNames = s.regions();
|
||||||
|
//
|
||||||
|
// wordList globalNames(localNames.size());
|
||||||
|
// forAll(localNames, regionI)
|
||||||
|
// {
|
||||||
|
// globalNames[regionI] = s.name() + '_' + localNames[regionI];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // See if dictionary provides any global region names.
|
||||||
|
// if (dict.found("regions"))
|
||||||
|
// {
|
||||||
|
// const dictionary& regionsDict = dict.subDict("regions");
|
||||||
|
//
|
||||||
|
// forAllConstIter(dictionary, regionsDict, iter)
|
||||||
|
// {
|
||||||
|
// const word& key = iter().keyword();
|
||||||
|
//
|
||||||
|
// if (regionsDict.isDict(key))
|
||||||
|
// {
|
||||||
|
// // Get the dictionary for region iter.key()
|
||||||
|
// const dictionary& regionDict = regionsDict.subDict(key);
|
||||||
|
//
|
||||||
|
// label index = findIndex(localNames, key);
|
||||||
|
//
|
||||||
|
// if (index == -1)
|
||||||
|
// {
|
||||||
|
// FatalErrorIn
|
||||||
|
// (
|
||||||
|
// "searchableSurfaces::searchableSurfaces"
|
||||||
|
// "( const IOobject&, const dictionary&)"
|
||||||
|
// ) << "Unknown region name " << key
|
||||||
|
// << " for surface " << s.name() << endl
|
||||||
|
// << "Valid region names are " << localNames
|
||||||
|
// << exit(FatalError);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// globalNames[index] = word(regionDict.lookup("name"));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Now globalNames contains the names of the regions.
|
||||||
|
// Info<< "Surface:" << s.name() << " has regions:"
|
||||||
|
// << endl;
|
||||||
|
// forAll(globalNames, regionI)
|
||||||
|
// {
|
||||||
|
// Info<< " " << globalNames[regionI] << endl;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Create reverse lookup
|
||||||
|
// forAll(globalNames, regionI)
|
||||||
|
// {
|
||||||
|
// regionNames_.insert
|
||||||
|
// (
|
||||||
|
// globalNames[regionI],
|
||||||
|
// labelPair(surfI, regionI)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::searchableSurfaces::searchableSurfaces
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& topDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PtrList<searchableSurface>(topDict.size()),
|
||||||
|
names_(topDict.size()),
|
||||||
|
regionNames_(topDict.size()),
|
||||||
|
allSurfaces_(identity(topDict.size()))
|
||||||
|
{
|
||||||
|
label surfI = 0;
|
||||||
|
forAllConstIter(dictionary, topDict, iter)
|
||||||
|
{
|
||||||
|
const word& key = iter().keyword();
|
||||||
|
|
||||||
|
if (!topDict.isDict(key))
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"searchableSurfaces::searchableSurfaces"
|
||||||
|
"( const IOobject&, const dictionary&)"
|
||||||
|
) << "Found non-dictionary entry " << iter()
|
||||||
|
<< " in top-level dictionary " << topDict
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dictionary& dict = topDict.subDict(key);
|
||||||
|
|
||||||
|
names_[surfI] = key;
|
||||||
|
|
||||||
|
if (dict.found("name"))
|
||||||
|
{
|
||||||
|
dict.lookup("name") >> names_[surfI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Make IOobject with correct name
|
||||||
|
autoPtr<IOobject> namedIO(io.clone());
|
||||||
|
// Note: we would like to e.g. register triSurface 'sphere.stl' as
|
||||||
|
// 'sphere'. Unfortunately
|
||||||
|
// no support for having object read from different location than
|
||||||
|
// their object name. Maybe have stlTriSurfaceMesh which appends .stl
|
||||||
|
// when reading/writing?
|
||||||
|
namedIO().rename(key); // names_[surfI]
|
||||||
|
|
||||||
|
// Create and hook surface
|
||||||
|
set
|
||||||
|
(
|
||||||
|
surfI,
|
||||||
|
searchableSurface::New
|
||||||
|
(
|
||||||
|
dict.lookup("type"),
|
||||||
|
namedIO(),
|
||||||
|
dict
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const searchableSurface& s = operator[](surfI);
|
||||||
|
|
||||||
|
// Construct default region names by prepending surface name
|
||||||
|
// to region name.
|
||||||
|
const wordList& localNames = s.regions();
|
||||||
|
|
||||||
|
wordList& rNames = regionNames_[surfI];
|
||||||
|
rNames.setSize(localNames.size());
|
||||||
|
|
||||||
|
forAll(localNames, regionI)
|
||||||
|
{
|
||||||
|
rNames[regionI] = names_[surfI] + '_' + localNames[regionI];
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if dictionary provides any global region names.
|
||||||
|
if (dict.found("regions"))
|
||||||
|
{
|
||||||
|
const dictionary& regionsDict = dict.subDict("regions");
|
||||||
|
|
||||||
|
forAllConstIter(dictionary, regionsDict, iter)
|
||||||
|
{
|
||||||
|
const word& key = iter().keyword();
|
||||||
|
|
||||||
|
if (regionsDict.isDict(key))
|
||||||
|
{
|
||||||
|
// Get the dictionary for region iter.keyword()
|
||||||
|
const dictionary& regionDict = regionsDict.subDict(key);
|
||||||
|
|
||||||
|
label index = findIndex(localNames, key);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"searchableSurfaces::searchableSurfaces"
|
||||||
|
"( const IOobject&, const dictionary&)"
|
||||||
|
) << "Unknown region name " << key
|
||||||
|
<< " for surface " << s.name() << endl
|
||||||
|
<< "Valid region names are " << localNames
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
rNames[index] = word(regionDict.lookup("name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
surfI++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim (not really necessary since we don't allow non-dictionary entries)
|
||||||
|
PtrList<searchableSurface>::setSize(surfI);
|
||||||
|
names_.setSize(surfI);
|
||||||
|
regionNames_.setSize(surfI);
|
||||||
|
allSurfaces_.setSize(surfI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::searchableSurfaces::findSurfaceID(const word& wantedName)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return findIndex(names_, wantedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find any intersection
|
||||||
|
void Foam::searchableSurfaces::findAnyIntersection
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelList& hitSurfaces,
|
||||||
|
List<pointIndexHit>& hitInfo
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
searchableSurfacesQueries::findAnyIntersection
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
allSurfaces_,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
hitSurfaces,
|
||||||
|
hitInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find intersections of edge nearest to both endpoints.
|
||||||
|
void Foam::searchableSurfaces::findAllIntersections
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelListList& hitSurfaces,
|
||||||
|
List<List<pointIndexHit> >& hitInfo
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
searchableSurfacesQueries::findAllIntersections
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
allSurfaces_,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
hitSurfaces,
|
||||||
|
hitInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find nearest. Return -1 or nearest point
|
||||||
|
void Foam::searchableSurfaces::findNearest
|
||||||
|
(
|
||||||
|
const pointField& samples,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
labelList& nearestSurfaces,
|
||||||
|
List<pointIndexHit>& nearestInfo
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return searchableSurfacesQueries::findNearest
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
allSurfaces_,
|
||||||
|
samples,
|
||||||
|
nearestDistSqr,
|
||||||
|
nearestSurfaces,
|
||||||
|
nearestInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Calculate point which is on a set of surfaces.
|
||||||
|
Foam::pointIndexHit Foam::searchableSurfaces::facesIntersection
|
||||||
|
(
|
||||||
|
const scalar initDistSqr,
|
||||||
|
const scalar convergenceDistSqr,
|
||||||
|
const point& start
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return searchableSurfacesQueries::facesIntersection
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
allSurfaces_,
|
||||||
|
initDistSqr,
|
||||||
|
convergenceDistSqr,
|
||||||
|
start
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
187
src/meshTools/searchableSurface/searchableSurfaces.H
Normal file
187
src/meshTools/searchableSurface/searchableSurfaces.H
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSurfaces
|
||||||
|
|
||||||
|
Description
|
||||||
|
Container for searchableSurfaces.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
searchableSurfaces.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef searchableSurfaces_H
|
||||||
|
#define searchableSurfaces_H
|
||||||
|
|
||||||
|
#include "searchableSurface.H"
|
||||||
|
#include "labelPair.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class searchableSurfaces Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class searchableSurfaces
|
||||||
|
:
|
||||||
|
public PtrList<searchableSurface>
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Surface names
|
||||||
|
wordList names_;
|
||||||
|
|
||||||
|
//- Region names per surface
|
||||||
|
List<wordList> regionNames_;
|
||||||
|
|
||||||
|
////- From global region name to surface and region on surface
|
||||||
|
//HashTable<labelPair> regionNames_;
|
||||||
|
|
||||||
|
//- Indices of all surfaces. Precalculated and stored.
|
||||||
|
labelList allSurfaces_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
searchableSurfaces(const searchableSurfaces&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const searchableSurfaces&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ClassName("searchableSurfaces");
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct with length specified. Fill later.
|
||||||
|
explicit searchableSurfaces(const label);
|
||||||
|
|
||||||
|
|
||||||
|
////- Construct from list of dictionaries
|
||||||
|
//searchableSurfaces(const IOobject&, const PtrList<dictionary>&);
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
searchableSurfaces(const IOobject&, const dictionary&);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
const wordList& names() const
|
||||||
|
{
|
||||||
|
return names_;
|
||||||
|
}
|
||||||
|
wordList& names()
|
||||||
|
{
|
||||||
|
return names_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const List<wordList>& regionNames() const
|
||||||
|
{
|
||||||
|
return regionNames_;
|
||||||
|
}
|
||||||
|
List<wordList>& regionNames()
|
||||||
|
{
|
||||||
|
return regionNames_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////- If adding surfaces 'by hand'
|
||||||
|
//HashTable<labelPair>& regionNames()
|
||||||
|
//{
|
||||||
|
// return regionNames_;
|
||||||
|
//}
|
||||||
|
////- Get surface and region for a name
|
||||||
|
//const labelPair& surfaceRegion(const word& globalRegion) const
|
||||||
|
//{
|
||||||
|
// return regionNames_[globalRegion];
|
||||||
|
//}
|
||||||
|
|
||||||
|
//- Find index of surface. Return -1 if not found.
|
||||||
|
label findSurfaceID(const word& name) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Multiple point queries.
|
||||||
|
|
||||||
|
//- Find any intersection. Return hit point information and
|
||||||
|
// surface number. If multiple surfaces hit the first surface
|
||||||
|
// is returned, not necessarily the nearest (to start).
|
||||||
|
void findAnyIntersection
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelList& surfaces,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Find all intersections in order from start to end. Returns for
|
||||||
|
// every hit the surface and the hit info.
|
||||||
|
void findAllIntersections
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelListList& surfaces,
|
||||||
|
List<List<pointIndexHit> >& surfaceHits
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Find nearest. Return -1 (and a miss()) or surface and nearest
|
||||||
|
// point.
|
||||||
|
void findNearest
|
||||||
|
(
|
||||||
|
const pointField&,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
labelList& surfaces,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Single point queries
|
||||||
|
|
||||||
|
//- Calculate point which is on a set of surfaces.
|
||||||
|
pointIndexHit facesIntersection
|
||||||
|
(
|
||||||
|
const scalar initialDistSqr,
|
||||||
|
const scalar convergenceDistSqr,
|
||||||
|
const point& start
|
||||||
|
) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
822
src/meshTools/searchableSurface/searchableSurfacesQueries.C
Normal file
822
src/meshTools/searchableSurface/searchableSurfacesQueries.C
Normal file
@ -0,0 +1,822 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "searchableSurfacesQueries.H"
|
||||||
|
#include "SortableList.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "meshTools.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(searchableSurfacesQueries, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::pointIndexHit Foam::searchableSurfacesQueries::tempFindNearest
|
||||||
|
(
|
||||||
|
const searchableSurface& surf,
|
||||||
|
const point& pt,
|
||||||
|
const scalar initDistSqr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pointField onePoint(1, pt);
|
||||||
|
scalarField oneDist(1, initDistSqr);
|
||||||
|
List<pointIndexHit> oneHit(1);
|
||||||
|
surf.findNearest(onePoint, oneDist, oneHit);
|
||||||
|
return oneHit[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate sum of distance to surfaces.
|
||||||
|
Foam::scalar Foam::searchableSurfacesQueries::sumDistSqr
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initDistSqr,
|
||||||
|
const point& pt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar sum = 0;
|
||||||
|
|
||||||
|
forAll(surfacesToTest, testI)
|
||||||
|
{
|
||||||
|
label surfI = surfacesToTest[testI];
|
||||||
|
|
||||||
|
pointIndexHit hit
|
||||||
|
(
|
||||||
|
tempFindNearest(allSurfaces[surfI], pt, initDistSqr)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Note: make it fall over if not hit.
|
||||||
|
sum += magSqr(hit.hitPoint()-pt);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Reflects the point furthest away around the triangle centre by a factor fac.
|
||||||
|
// (triangle centre is the average of all points but the ihi. pSum is running
|
||||||
|
// sum of all points)
|
||||||
|
Foam::scalar Foam::searchableSurfacesQueries::tryMorphTet
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initDistSqr,
|
||||||
|
List<vector>& p,
|
||||||
|
List<scalar>& y,
|
||||||
|
vector& pSum,
|
||||||
|
const label ihi,
|
||||||
|
const scalar fac
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar fac1 = (1.0-fac)/vector::nComponents;
|
||||||
|
scalar fac2 = fac1-fac;
|
||||||
|
|
||||||
|
vector ptry = pSum*fac1-p[ihi]*fac2;
|
||||||
|
|
||||||
|
scalar ytry = sumDistSqr(allSurfaces, surfacesToTest, initDistSqr, ptry);
|
||||||
|
|
||||||
|
if (ytry < y[ihi])
|
||||||
|
{
|
||||||
|
y[ihi] = ytry;
|
||||||
|
pSum += ptry - p[ihi];
|
||||||
|
p[ihi] = ptry;
|
||||||
|
}
|
||||||
|
return ytry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::searchableSurfacesQueries::morphTet
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initDistSqr,
|
||||||
|
const scalar convergenceDistSqr,
|
||||||
|
const label maxIter,
|
||||||
|
List<vector>& p,
|
||||||
|
List<scalar>& y
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vector pSum = sum(p);
|
||||||
|
|
||||||
|
autoPtr<OFstream> str;
|
||||||
|
label vertI = 0;
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
wordList names(surfacesToTest.size());
|
||||||
|
forAll(surfacesToTest, i)
|
||||||
|
{
|
||||||
|
names[i] = allSurfaces[surfacesToTest[i]].name();
|
||||||
|
}
|
||||||
|
Pout<< "searchableSurfacesQueries::morphTet : intersection of "
|
||||||
|
<< names << " starting from points:" << p << endl;
|
||||||
|
str.reset(new OFstream("track.obj"));
|
||||||
|
meshTools::writeOBJ(str(), p[0]);
|
||||||
|
vertI++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label iter = 0; iter < maxIter; iter++)
|
||||||
|
{
|
||||||
|
// Get the indices of highest, second-highest and lowest values.
|
||||||
|
label ihi, inhi, ilo;
|
||||||
|
{
|
||||||
|
SortableList<scalar> sortedY(y);
|
||||||
|
ilo = sortedY.indices()[0];
|
||||||
|
ihi = sortedY.indices()[sortedY.size()-1];
|
||||||
|
inhi = sortedY.indices()[sortedY.size()-2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "Iteration:" << iter
|
||||||
|
<< " lowest:" << y[ilo] << " highest:" << y[ihi]
|
||||||
|
<< " points:" << p << endl;
|
||||||
|
|
||||||
|
meshTools::writeOBJ(str(), p[ilo]);
|
||||||
|
vertI++;
|
||||||
|
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y[ihi] < convergenceDistSqr)
|
||||||
|
{
|
||||||
|
// Get point on 0th surface.
|
||||||
|
Swap(p[0], p[ilo]);
|
||||||
|
Swap(y[0], y[ilo]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reflection: point furthest away gets reflected.
|
||||||
|
scalar ytry = tryMorphTet
|
||||||
|
(
|
||||||
|
allSurfaces,
|
||||||
|
surfacesToTest,
|
||||||
|
10*y[ihi], // search box.
|
||||||
|
p,
|
||||||
|
y,
|
||||||
|
pSum,
|
||||||
|
ihi,
|
||||||
|
-1.0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ytry <= y[ilo])
|
||||||
|
{
|
||||||
|
// If in right direction (y lower) expand by two.
|
||||||
|
ytry = tryMorphTet
|
||||||
|
(
|
||||||
|
allSurfaces,
|
||||||
|
surfacesToTest,
|
||||||
|
10*y[ihi],
|
||||||
|
p,
|
||||||
|
y,
|
||||||
|
pSum,
|
||||||
|
ihi,
|
||||||
|
2.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (ytry >= y[inhi])
|
||||||
|
{
|
||||||
|
// If inside tet try contraction.
|
||||||
|
|
||||||
|
scalar ysave = y[ihi];
|
||||||
|
|
||||||
|
ytry = tryMorphTet
|
||||||
|
(
|
||||||
|
allSurfaces,
|
||||||
|
surfacesToTest,
|
||||||
|
10*y[ihi],
|
||||||
|
p,
|
||||||
|
y,
|
||||||
|
pSum,
|
||||||
|
ihi,
|
||||||
|
0.5
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ytry >= ysave)
|
||||||
|
{
|
||||||
|
// Contract around lowest point.
|
||||||
|
forAll(p, i)
|
||||||
|
{
|
||||||
|
if (i != ilo)
|
||||||
|
{
|
||||||
|
p[i] = 0.5*(p[i] + p[ilo]);
|
||||||
|
y[i] = sumDistSqr
|
||||||
|
(
|
||||||
|
allSurfaces,
|
||||||
|
surfacesToTest,
|
||||||
|
y[ihi],
|
||||||
|
p[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pSum = sum(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
meshTools::writeOBJ(str(), p[0]);
|
||||||
|
vertI++;
|
||||||
|
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure to converge. Return best guess so far.
|
||||||
|
label ilo = findMin(y);
|
||||||
|
Swap(p[0], p[ilo]);
|
||||||
|
Swap(y[0], y[ilo]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// Get all intersections (in order) for single surface.
|
||||||
|
//void Foam::searchableSurfacesQueries::findAllIntersections
|
||||||
|
//(
|
||||||
|
// const searchableSurface& s,
|
||||||
|
// const pointField& start,
|
||||||
|
// const pointField& end,
|
||||||
|
// const vectorField& smallVec,
|
||||||
|
// List<List<pointIndexHit> >& surfaceHitInfo
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// surfaceHitInfo.setSize(start.size());
|
||||||
|
//
|
||||||
|
// // Current start point of vector
|
||||||
|
// pointField p0(start);
|
||||||
|
//
|
||||||
|
// List<pointIndexHit> intersectInfo(start.size());
|
||||||
|
//
|
||||||
|
// // For test whether finished doing vector.
|
||||||
|
// const vectorField dirVec(end-start);
|
||||||
|
// const scalarField magSqrDirVec(magSqr(dirVec));
|
||||||
|
//
|
||||||
|
// while (true)
|
||||||
|
// {
|
||||||
|
// // Find first intersection. Synced.
|
||||||
|
// s.findLine(p0, end, intersectInfo);
|
||||||
|
//
|
||||||
|
// label nHits = 0;
|
||||||
|
//
|
||||||
|
// forAll(intersectInfo, i)
|
||||||
|
// {
|
||||||
|
// if (intersectInfo[i].hit())
|
||||||
|
// {
|
||||||
|
// nHits++;
|
||||||
|
//
|
||||||
|
// label sz = surfaceHitInfo[i].size();
|
||||||
|
// surfaceHitInfo[i].setSize(sz+1);
|
||||||
|
// surfaceHitInfo[i][sz] = intersectInfo[i];
|
||||||
|
//
|
||||||
|
// p0[i] = intersectInfo[i].hitPoint() + smallVec[i];
|
||||||
|
//
|
||||||
|
// // If beyond endpoint set to endpoint so as not to pick up
|
||||||
|
// // any intersections. Could instead just filter out hits.
|
||||||
|
// if (((p0[i]-start[i])&dirVec[i]) > magSqrDirVec[i])
|
||||||
|
// {
|
||||||
|
// p0[i] = end[i];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // Set to endpoint to stop intersection test. See above.
|
||||||
|
// p0[i] = end[i];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // returnReduce(nHits) ?
|
||||||
|
// if (nHits == 0)
|
||||||
|
// {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// Given current set of hits (allSurfaces, allInfo) merge in those coming from
|
||||||
|
// surface surfI.
|
||||||
|
void Foam::searchableSurfacesQueries::mergeHits
|
||||||
|
(
|
||||||
|
const point& start,
|
||||||
|
const scalar mergeDist,
|
||||||
|
|
||||||
|
const label testI, // index of surface
|
||||||
|
const List<pointIndexHit>& surfHits, // hits on surface
|
||||||
|
|
||||||
|
labelList& allSurfaces,
|
||||||
|
List<pointIndexHit>& allInfo,
|
||||||
|
scalarList& allDistSqr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Precalculate distances
|
||||||
|
scalarList surfDistSqr(surfHits.size());
|
||||||
|
forAll(surfHits, i)
|
||||||
|
{
|
||||||
|
surfDistSqr[i] = magSqr(surfHits[i].hitPoint()-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(surfDistSqr, i)
|
||||||
|
{
|
||||||
|
label index = findLower(allDistSqr, surfDistSqr[i]);
|
||||||
|
|
||||||
|
// Check if equal to lower.
|
||||||
|
if
|
||||||
|
(
|
||||||
|
index >= 0
|
||||||
|
&& (mag(allDistSqr[index]-surfDistSqr[i]) < mergeDist)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Same. Do not count.
|
||||||
|
//Pout<< "point:" << surfHits[i].hitPoint()
|
||||||
|
// << " considered same as:" << allInfo[index].hitPoint()
|
||||||
|
// << " within tol:" << mergeDist
|
||||||
|
// << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check if equal to higher
|
||||||
|
label next = index+1;
|
||||||
|
if
|
||||||
|
(
|
||||||
|
next < allDistSqr.size()
|
||||||
|
&& (mag(allDistSqr[next]-surfDistSqr[i]) < mergeDist)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//Pout<< "point:" << surfHits[i].hitPoint()
|
||||||
|
// << " considered same as:" << allInfo[next].hitPoint()
|
||||||
|
// << " within tol:" << mergeDist
|
||||||
|
// << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert after index
|
||||||
|
label sz = allSurfaces.size();
|
||||||
|
allSurfaces.setSize(sz+1);
|
||||||
|
allInfo.setSize(allSurfaces.size());
|
||||||
|
allDistSqr.setSize(allSurfaces.size());
|
||||||
|
// Make space.
|
||||||
|
for (label j = sz-1; j > index; --j)
|
||||||
|
{
|
||||||
|
allSurfaces[j+1] = allSurfaces[j];
|
||||||
|
allInfo[j+1] = allInfo[j];
|
||||||
|
allDistSqr[j+1] = allDistSqr[j];
|
||||||
|
}
|
||||||
|
// Insert new value
|
||||||
|
allSurfaces[index+1] = testI;
|
||||||
|
allInfo[index+1] = surfHits[i];
|
||||||
|
allDistSqr[index+1] = surfDistSqr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Find any intersection
|
||||||
|
void Foam::searchableSurfacesQueries::findAnyIntersection
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelList& hitSurfaces,
|
||||||
|
List<pointIndexHit>& hitInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
hitSurfaces.setSize(start.size());
|
||||||
|
hitSurfaces = -1;
|
||||||
|
hitInfo.setSize(start.size());
|
||||||
|
|
||||||
|
// Work arrays
|
||||||
|
labelList hitMap(identity(start.size()));
|
||||||
|
pointField p0(start);
|
||||||
|
pointField p1(end);
|
||||||
|
List<pointIndexHit> intersectInfo(start.size());
|
||||||
|
|
||||||
|
forAll(surfacesToTest, testI)
|
||||||
|
{
|
||||||
|
// Do synchronised call to all surfaces.
|
||||||
|
allSurfaces[surfacesToTest[testI]].findLineAny(p0, p1, intersectInfo);
|
||||||
|
|
||||||
|
// Copy all hits into arguments, continue with misses
|
||||||
|
label newI = 0;
|
||||||
|
forAll(intersectInfo, i)
|
||||||
|
{
|
||||||
|
if (intersectInfo[i].hit())
|
||||||
|
{
|
||||||
|
hitInfo[hitMap[i]] = intersectInfo[i];
|
||||||
|
hitSurfaces[hitMap[i]] = testI;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i != newI)
|
||||||
|
{
|
||||||
|
hitMap[newI] = hitMap[i];
|
||||||
|
p0[newI] = p0[i];
|
||||||
|
p1[newI] = p1[i];
|
||||||
|
}
|
||||||
|
newI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All done? Note that this decision should be synchronised
|
||||||
|
if (newI == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim and continue
|
||||||
|
hitMap.setSize(newI);
|
||||||
|
p0.setSize(newI);
|
||||||
|
p1.setSize(newI);
|
||||||
|
intersectInfo.setSize(newI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::searchableSurfacesQueries::findAllIntersections
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelListList& hitSurfaces,
|
||||||
|
List<List<pointIndexHit> >& hitInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Note: maybe move the single-surface all intersections test into
|
||||||
|
// searchable surface? Some of the tolerance issues might be
|
||||||
|
// lessened.
|
||||||
|
|
||||||
|
// 2. Currently calling searchableSurface::findLine with start==end
|
||||||
|
// is expected to find no intersection. Problem if it does.
|
||||||
|
|
||||||
|
hitSurfaces.setSize(start.size());
|
||||||
|
hitInfo.setSize(start.size());
|
||||||
|
|
||||||
|
if (surfacesToTest.size() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test first surface
|
||||||
|
allSurfaces[surfacesToTest[0]].findLineAll(start, end, hitInfo);
|
||||||
|
|
||||||
|
// Set hitSurfaces and distance
|
||||||
|
List<scalarList> hitDistSqr(hitInfo.size());
|
||||||
|
forAll(hitInfo, pointI)
|
||||||
|
{
|
||||||
|
const List<pointIndexHit>& pHits = hitInfo[pointI];
|
||||||
|
|
||||||
|
labelList& pSurfaces = hitSurfaces[pointI];
|
||||||
|
pSurfaces.setSize(pHits.size());
|
||||||
|
pSurfaces = 0;
|
||||||
|
|
||||||
|
scalarList& pDistSqr = hitDistSqr[pointI];
|
||||||
|
pDistSqr.setSize(pHits.size());
|
||||||
|
forAll(pHits, i)
|
||||||
|
{
|
||||||
|
pDistSqr[i] = magSqr(pHits[i].hitPoint() - start[pointI]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (surfacesToTest.size() > 1)
|
||||||
|
{
|
||||||
|
// Small vector to increment start vector by to find next intersection
|
||||||
|
// along line. Constant factor added to make sure that start==end still
|
||||||
|
// ends iteration in findAllIntersections. Also SMALL is just slightly
|
||||||
|
// too small.
|
||||||
|
const vectorField smallVec
|
||||||
|
(
|
||||||
|
1E2*SMALL*(end-start)
|
||||||
|
+ vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tolerance used to check whether points are equal. Note: used to
|
||||||
|
// compare distance^2. Note that we use the maximum possible tolerance
|
||||||
|
// (reached at intersections close to the end point)
|
||||||
|
const scalarField mergeDist(2*mag(smallVec)*mag(end-start));
|
||||||
|
|
||||||
|
// Test the other surfaces and merge (according to distance from start).
|
||||||
|
for (label testI = 1; testI < surfacesToTest.size(); testI++)
|
||||||
|
{
|
||||||
|
List<List<pointIndexHit> > surfHits;
|
||||||
|
allSurfaces[surfacesToTest[testI]].findLineAll
|
||||||
|
(
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
surfHits
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(surfHits, pointI)
|
||||||
|
{
|
||||||
|
mergeHits
|
||||||
|
(
|
||||||
|
start[pointI], // Current segment
|
||||||
|
mergeDist[pointI],
|
||||||
|
|
||||||
|
testI, // Surface and its hits
|
||||||
|
surfHits[pointI],
|
||||||
|
|
||||||
|
hitSurfaces[pointI], // Merge into overall hit info
|
||||||
|
hitInfo[pointI],
|
||||||
|
hitDistSqr[pointI]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// Find intersections of edge nearest to both endpoints.
|
||||||
|
//void Foam::searchableSurfacesQueries::findNearestIntersection
|
||||||
|
//(
|
||||||
|
// const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
// const labelList& surfacesToTest,
|
||||||
|
// const pointField& start,
|
||||||
|
// const pointField& end,
|
||||||
|
//
|
||||||
|
// labelList& surface1,
|
||||||
|
// List<pointIndexHit>& hit1,
|
||||||
|
// labelList& surface2,
|
||||||
|
// List<pointIndexHit>& hit2
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// // 1. intersection from start to end
|
||||||
|
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// // Initialize arguments
|
||||||
|
// surface1.setSize(start.size());
|
||||||
|
// surface1 = -1;
|
||||||
|
// hit1.setSize(start.size());
|
||||||
|
//
|
||||||
|
// // Current end of segment to test.
|
||||||
|
// pointField nearest(end);
|
||||||
|
// // Work array
|
||||||
|
// List<pointIndexHit> nearestInfo(start.size());
|
||||||
|
//
|
||||||
|
// forAll(surfacesToTest, testI)
|
||||||
|
// {
|
||||||
|
// // See if any intersection between start and current nearest
|
||||||
|
// allSurfaces[surfacesToTest[testI]].findLine
|
||||||
|
// (
|
||||||
|
// start,
|
||||||
|
// nearest,
|
||||||
|
// nearestInfo
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// forAll(nearestInfo, pointI)
|
||||||
|
// {
|
||||||
|
// if (nearestInfo[pointI].hit())
|
||||||
|
// {
|
||||||
|
// hit1[pointI] = nearestInfo[pointI];
|
||||||
|
// surface1[pointI] = testI;
|
||||||
|
// nearest[pointI] = hit1[pointI].hitPoint();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // 2. intersection from end to last intersection
|
||||||
|
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// // Find the nearest intersection from end to start. Note that we
|
||||||
|
// // initialize to the first intersection (if any).
|
||||||
|
// surface2 = surface1;
|
||||||
|
// hit2 = hit1;
|
||||||
|
//
|
||||||
|
// // Set current end of segment to test.
|
||||||
|
// forAll(nearest, pointI)
|
||||||
|
// {
|
||||||
|
// if (hit1[pointI].hit())
|
||||||
|
// {
|
||||||
|
// nearest[pointI] = hit1[pointI].hitPoint();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // Disable testing by setting to end.
|
||||||
|
// nearest[pointI] = end[pointI];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// forAll(surfacesToTest, testI)
|
||||||
|
// {
|
||||||
|
// // See if any intersection between end and current nearest
|
||||||
|
// allSurfaces[surfacesToTest[i]].findLine(end, nearest, nearestInfo);
|
||||||
|
//
|
||||||
|
// forAll(nearestInfo, pointI)
|
||||||
|
// {
|
||||||
|
// if (nearestInfo[pointI].hit())
|
||||||
|
// {
|
||||||
|
// hit2[pointI] = nearestInfo[pointI];
|
||||||
|
// surface2[pointI] = testI;
|
||||||
|
// nearest[pointI] = hit2[pointI].hitPoint();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// Find nearest. Return -1 or nearest point
|
||||||
|
void Foam::searchableSurfacesQueries::findNearest
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& samples,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
labelList& nearestSurfaces,
|
||||||
|
List<pointIndexHit>& nearestInfo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Initialise
|
||||||
|
nearestSurfaces.setSize(samples.size());
|
||||||
|
nearestSurfaces = -1;
|
||||||
|
nearestInfo.setSize(samples.size());
|
||||||
|
|
||||||
|
// Work arrays
|
||||||
|
scalarField minDistSqr(nearestDistSqr);
|
||||||
|
List<pointIndexHit> hitInfo(samples.size());
|
||||||
|
|
||||||
|
forAll(surfacesToTest, testI)
|
||||||
|
{
|
||||||
|
allSurfaces[surfacesToTest[testI]].findNearest
|
||||||
|
(
|
||||||
|
samples,
|
||||||
|
minDistSqr,
|
||||||
|
hitInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update minDistSqr and arguments
|
||||||
|
forAll(hitInfo, pointI)
|
||||||
|
{
|
||||||
|
if (hitInfo[pointI].hit())
|
||||||
|
{
|
||||||
|
minDistSqr[pointI] = magSqr
|
||||||
|
(
|
||||||
|
hitInfo[pointI].hitPoint()
|
||||||
|
- samples[pointI]
|
||||||
|
);
|
||||||
|
nearestInfo[pointI] = hitInfo[pointI];
|
||||||
|
nearestSurfaces[pointI] = testI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Calculate point which is on a set of surfaces.
|
||||||
|
Foam::pointIndexHit Foam::searchableSurfacesQueries::facesIntersection
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initDistSqr,
|
||||||
|
const scalar convergenceDistSqr,
|
||||||
|
const point& start
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Get four starting points. Take these as the projection of the
|
||||||
|
// starting point onto the surfaces and the mid point
|
||||||
|
List<point> nearest(surfacesToTest.size()+1);
|
||||||
|
|
||||||
|
point sumNearest = vector::zero;
|
||||||
|
|
||||||
|
forAll(surfacesToTest, i)
|
||||||
|
{
|
||||||
|
pointIndexHit hit
|
||||||
|
(
|
||||||
|
tempFindNearest(allSurfaces[surfacesToTest[i]], start, initDistSqr)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hit.hit())
|
||||||
|
{
|
||||||
|
nearest[i] = hit.hitPoint();
|
||||||
|
sumNearest += nearest[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"searchableSurfacesQueries::facesIntersection"
|
||||||
|
"(const labelList&, const scalar, const scalar, const point&)"
|
||||||
|
) << "Did not find point within distance "
|
||||||
|
<< initDistSqr << " of starting point " << start
|
||||||
|
<< " on surface "
|
||||||
|
<< allSurfaces[surfacesToTest[i]].IOobject::name()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nearest[nearest.size()-1] = sumNearest / surfacesToTest.size();
|
||||||
|
|
||||||
|
|
||||||
|
// Get the sum of distances (initial evaluation)
|
||||||
|
List<scalar> nearestDist(nearest.size());
|
||||||
|
|
||||||
|
forAll(nearestDist, i)
|
||||||
|
{
|
||||||
|
nearestDist[i] = sumDistSqr
|
||||||
|
(
|
||||||
|
allSurfaces,
|
||||||
|
surfacesToTest,
|
||||||
|
initDistSqr,
|
||||||
|
nearest[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Downhill Simplex method
|
||||||
|
|
||||||
|
bool converged = morphTet
|
||||||
|
(
|
||||||
|
allSurfaces,
|
||||||
|
surfacesToTest,
|
||||||
|
initDistSqr,
|
||||||
|
convergenceDistSqr,
|
||||||
|
2000,
|
||||||
|
nearest,
|
||||||
|
nearestDist
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
pointIndexHit intersection;
|
||||||
|
|
||||||
|
if (converged)
|
||||||
|
{
|
||||||
|
// Project nearest onto 0th surface.
|
||||||
|
intersection = tempFindNearest
|
||||||
|
(
|
||||||
|
allSurfaces[surfacesToTest[0]],
|
||||||
|
nearest[0],
|
||||||
|
nearestDist[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!intersection.hit())
|
||||||
|
//{
|
||||||
|
// // Restart
|
||||||
|
// scalar smallDist = Foam::sqr(convergenceDistSqr);
|
||||||
|
// nearest[0] = intersection.hitPoint();
|
||||||
|
// nearest[1] = nearest[0];
|
||||||
|
// nearest[1].x() += smallDist;
|
||||||
|
// nearest[2] = nearest[0];
|
||||||
|
// nearest[2].y() += smallDist;
|
||||||
|
// nearest[3] = nearest[0];
|
||||||
|
// nearest[3].z() += smallDist;
|
||||||
|
//
|
||||||
|
// forAll(nearestDist, i)
|
||||||
|
// {
|
||||||
|
// nearestDist[i] = sumDistSqr
|
||||||
|
// (
|
||||||
|
// surfacesToTest,
|
||||||
|
// initDistSqr,
|
||||||
|
// nearest[i]
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// intersection = morphTet
|
||||||
|
// (
|
||||||
|
// allSurfaces,
|
||||||
|
// surfacesToTest,
|
||||||
|
// initDistSqr,
|
||||||
|
// convergenceDistSqr,
|
||||||
|
// 1000,
|
||||||
|
// nearest,
|
||||||
|
// nearestDist
|
||||||
|
// );
|
||||||
|
//}
|
||||||
|
|
||||||
|
return intersection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
198
src/meshTools/searchableSurface/searchableSurfacesQueries.H
Normal file
198
src/meshTools/searchableSurface/searchableSurfacesQueries.H
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSurfacesQueries
|
||||||
|
|
||||||
|
Description
|
||||||
|
A collection of tools for searchableSurfaces.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
searchableSurfacesQueries.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef searchableSurfacesQueries_H
|
||||||
|
#define searchableSurfacesQueries_H
|
||||||
|
|
||||||
|
#include "searchableSurface.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class plane;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class searchableSurfacesQueries Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class searchableSurfacesQueries
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Temporary wrapper around findNearest. Used in facesIntersection only
|
||||||
|
static pointIndexHit tempFindNearest
|
||||||
|
(
|
||||||
|
const searchableSurface&,
|
||||||
|
const point& pt,
|
||||||
|
const scalar initDistSqr
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate sum of distances to nearest point on surfaces. Is used
|
||||||
|
// in minimisation to find intersection. Returns sum of (square of)
|
||||||
|
// distances to the surfaces.
|
||||||
|
static scalar sumDistSqr
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>&,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initialDistSqr, // search box
|
||||||
|
const point& pt
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Takes the tet (points p) and reflects the point with the
|
||||||
|
// highest value around the centre (pSum). Checks if it gets closer
|
||||||
|
// and updates p, y if so.
|
||||||
|
static scalar tryMorphTet
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>&,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initialDistSqr,
|
||||||
|
List<vector>& p,
|
||||||
|
List<scalar>& y,
|
||||||
|
vector& pSum,
|
||||||
|
const label ihi,
|
||||||
|
const scalar fac
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Downhill simplex method: find the point with min cumulative
|
||||||
|
// distance to all surfaces. Does so by morphing a tet (points p).
|
||||||
|
// Returns the point on the 0th surface or hit if not reached within
|
||||||
|
// maxIters iterations.
|
||||||
|
static bool morphTet
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>&,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initialDistSqr,
|
||||||
|
const scalar convergenceDistSqr,
|
||||||
|
const label maxIter,
|
||||||
|
List<vector>& p,
|
||||||
|
List<scalar>& y
|
||||||
|
);
|
||||||
|
|
||||||
|
//static void findAllIntersections
|
||||||
|
//(
|
||||||
|
// const searchableSurface& s,
|
||||||
|
// const pointField& start,
|
||||||
|
// const pointField& end,
|
||||||
|
// const vectorField& smallVec,
|
||||||
|
// List<List<pointIndexHit> >&
|
||||||
|
//);
|
||||||
|
|
||||||
|
static void mergeHits
|
||||||
|
(
|
||||||
|
const point& start,
|
||||||
|
const scalar mergeDist,
|
||||||
|
|
||||||
|
const label surfI,
|
||||||
|
const List<pointIndexHit>& surfHits,
|
||||||
|
|
||||||
|
labelList& allSurfaces,
|
||||||
|
List<pointIndexHit>& allInfo,
|
||||||
|
scalarList& allDistSqr
|
||||||
|
);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Declare name of the class and its debug switch
|
||||||
|
ClassName("searchableSurfacesQueries");
|
||||||
|
|
||||||
|
|
||||||
|
// Multiple point queries.
|
||||||
|
|
||||||
|
//- Find any intersection. Return hit point information and
|
||||||
|
// index in surfacesToTest. If multiple surfaces hit the first
|
||||||
|
// surface is returned, not necessarily the nearest (to start).
|
||||||
|
static void findAnyIntersection
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>&,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelList& surfaces,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Find all intersections in order from start to end. Returns for
|
||||||
|
// every hit the index in surfacesToTest and the hit info.
|
||||||
|
static void findAllIntersections
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>&,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
labelListList& surfaces,
|
||||||
|
List<List<pointIndexHit> >& surfaceHits
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Find nearest. Return -1 (and a miss()) or surface and nearest
|
||||||
|
// point.
|
||||||
|
static void findNearest
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>&,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const pointField&,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
labelList& surfaces,
|
||||||
|
List<pointIndexHit>&
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Single point queries
|
||||||
|
|
||||||
|
//- Calculate point which is on a set of surfaces. WIP.
|
||||||
|
static pointIndexHit facesIntersection
|
||||||
|
(
|
||||||
|
const PtrList<searchableSurface>& allSurfaces,
|
||||||
|
const labelList& surfacesToTest,
|
||||||
|
const scalar initDistSqr,
|
||||||
|
const scalar convergenceDistSqr,
|
||||||
|
const point& start
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
552
src/meshTools/searchableSurface/triSurfaceMesh.C
Normal file
552
src/meshTools/searchableSurface/triSurfaceMesh.C
Normal file
@ -0,0 +1,552 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "Random.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "EdgeMap.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(triSurfaceMesh, 0);
|
||||||
|
addToRunTimeSelectionTable(searchableSurface, triSurfaceMesh, dict);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
//- Check file existence
|
||||||
|
const Foam::fileName& Foam::triSurfaceMesh::checkFile
|
||||||
|
(
|
||||||
|
const fileName& fName,
|
||||||
|
const fileName& objectName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fName == fileName::null)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"triSurfaceMesh::checkFile(const fileName&, const fileName&)"
|
||||||
|
) << "Cannot find triSurfaceMesh starting from "
|
||||||
|
<< objectName << exit(FatalError);
|
||||||
|
}
|
||||||
|
return fName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::triSurfaceMesh::isSurfaceClosed() const
|
||||||
|
{
|
||||||
|
// Construct pointFaces. Let's hope surface has compact point
|
||||||
|
// numbering ...
|
||||||
|
labelListList pointFaces;
|
||||||
|
invertManyToMany(points().size(), *this, pointFaces);
|
||||||
|
|
||||||
|
// Loop over all faces surrounding point. Count edges emanating from point.
|
||||||
|
// Every edge should be used by two faces exactly.
|
||||||
|
// To prevent doing work twice per edge only look at edges to higher
|
||||||
|
// point
|
||||||
|
EdgeMap<label> facesPerEdge(100);
|
||||||
|
forAll(pointFaces, pointI)
|
||||||
|
{
|
||||||
|
const labelList& pFaces = pointFaces[pointI];
|
||||||
|
|
||||||
|
facesPerEdge.clear();
|
||||||
|
forAll(pFaces, i)
|
||||||
|
{
|
||||||
|
const labelledTri& f = triSurface::operator[](pFaces[i]);
|
||||||
|
label fp = findIndex(f, pointI);
|
||||||
|
|
||||||
|
// Forward edge
|
||||||
|
{
|
||||||
|
label p1 = f[f.fcIndex(fp)];
|
||||||
|
|
||||||
|
if (p1 > pointI)
|
||||||
|
{
|
||||||
|
const edge e(pointI, p1);
|
||||||
|
EdgeMap<label>::iterator eFnd = facesPerEdge.find(e);
|
||||||
|
if (eFnd != facesPerEdge.end())
|
||||||
|
{
|
||||||
|
if (eFnd() == 2)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
eFnd()++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
facesPerEdge.insert(e, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Reverse edge
|
||||||
|
{
|
||||||
|
label p1 = f[f.rcIndex(fp)];
|
||||||
|
|
||||||
|
if (p1 > pointI)
|
||||||
|
{
|
||||||
|
const edge e(pointI, p1);
|
||||||
|
EdgeMap<label>::iterator eFnd = facesPerEdge.find(e);
|
||||||
|
if (eFnd != facesPerEdge.end())
|
||||||
|
{
|
||||||
|
if (eFnd() == 2)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
eFnd()++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
facesPerEdge.insert(e, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for any edges used only once.
|
||||||
|
forAllConstIter(EdgeMap<label>, facesPerEdge, iter)
|
||||||
|
{
|
||||||
|
if (iter() != 2)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
objectRegistry(io),
|
||||||
|
triSurface(s),
|
||||||
|
surfaceClosed_(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
objectRegistry(io),
|
||||||
|
triSurface
|
||||||
|
(
|
||||||
|
checkFile
|
||||||
|
(
|
||||||
|
searchableSurface::filePath(),
|
||||||
|
searchableSurface::objectPath()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
surfaceClosed_(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::triSurfaceMesh::triSurfaceMesh
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurface(io),
|
||||||
|
objectRegistry(io),
|
||||||
|
triSurface
|
||||||
|
(
|
||||||
|
checkFile
|
||||||
|
(
|
||||||
|
searchableSurface::filePath(),
|
||||||
|
searchableSurface::objectPath()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
surfaceClosed_(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::triSurfaceMesh::~triSurfaceMesh()
|
||||||
|
{
|
||||||
|
clearOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::clearOut()
|
||||||
|
{
|
||||||
|
tree_.clear();
|
||||||
|
edgeTree_.clear();
|
||||||
|
triSurface::clearOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::movePoints(const pointField& newPoints)
|
||||||
|
{
|
||||||
|
tree_.clear();
|
||||||
|
edgeTree_.clear();
|
||||||
|
triSurface::movePoints(newPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::indexedOctree<Foam::treeDataTriSurface>&
|
||||||
|
Foam::triSurfaceMesh::tree() const
|
||||||
|
{
|
||||||
|
if (!tree_.valid())
|
||||||
|
{
|
||||||
|
treeBoundBox bb(points(), meshPoints());
|
||||||
|
|
||||||
|
// Random number generator. Bit dodgy since not exactly random ;-)
|
||||||
|
Random rndGen(65431);
|
||||||
|
|
||||||
|
tree_.reset
|
||||||
|
(
|
||||||
|
new indexedOctree<treeDataTriSurface>
|
||||||
|
(
|
||||||
|
treeDataTriSurface(*this),
|
||||||
|
bb.extend(rndGen, 1E-3), // slightly randomize bb
|
||||||
|
10, // maxLevel
|
||||||
|
10, // leafsize
|
||||||
|
3.0 // duplicity
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tree_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::indexedOctree<Foam::treeDataEdge>&
|
||||||
|
Foam::triSurfaceMesh::edgeTree() const
|
||||||
|
{
|
||||||
|
if (!edgeTree_.valid())
|
||||||
|
{
|
||||||
|
treeBoundBox bb(localPoints());
|
||||||
|
|
||||||
|
// Boundary edges
|
||||||
|
labelList bEdges
|
||||||
|
(
|
||||||
|
identity
|
||||||
|
(
|
||||||
|
nEdges()
|
||||||
|
-nInternalEdges()
|
||||||
|
)
|
||||||
|
+ nInternalEdges()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Random number generator. Bit dodgy since not exactly random ;-)
|
||||||
|
Random rndGen(65431);
|
||||||
|
|
||||||
|
edgeTree_.reset
|
||||||
|
(
|
||||||
|
new indexedOctree<treeDataEdge>
|
||||||
|
(
|
||||||
|
treeDataEdge
|
||||||
|
(
|
||||||
|
false, // cachebb
|
||||||
|
edges(), // edges
|
||||||
|
localPoints(), // points
|
||||||
|
bEdges // selected edges
|
||||||
|
),
|
||||||
|
bb.extend(rndGen, 1E-3), // slightly randomize bb
|
||||||
|
8, // maxLevel
|
||||||
|
10, // leafsize
|
||||||
|
3.0 // duplicity
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return edgeTree_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::wordList& Foam::triSurfaceMesh::regions() const
|
||||||
|
{
|
||||||
|
if (regions_.size() == 0)
|
||||||
|
{
|
||||||
|
regions_.setSize(patches().size());
|
||||||
|
forAll(regions_, regionI)
|
||||||
|
{
|
||||||
|
regions_[regionI] = patches()[regionI].name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return regions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Foam::pointIndexHit Foam::triSurfaceMesh::findNearest
|
||||||
|
//(
|
||||||
|
// const point& sample,
|
||||||
|
// const scalar nearestDistSqr
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// return tree().findNearest(sample, nearestDistSqr);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//Foam::pointIndexHit Foam::triSurfaceMesh::findNearestOnEdge
|
||||||
|
//(
|
||||||
|
// const point& sample,
|
||||||
|
// const scalar nearestDistSqr
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// return = edgeTree().findNearest(sample, nearestDistSqr);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//Foam::pointIndexHit Foam::triSurfaceMesh::findNearest
|
||||||
|
//(
|
||||||
|
// const linePointRef& ln,
|
||||||
|
// treeBoundBox& tightest,
|
||||||
|
// point& linePoint
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// return tree().findNearest(ln, tightest, linePoint);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//Foam::pointIndexHit Foam::triSurfaceMesh::findLine
|
||||||
|
//(
|
||||||
|
// const point& start,
|
||||||
|
// const point& end
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// return tree().findLine(start, end);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//Foam::pointIndexHit Foam::triSurfaceMesh::findLineAny
|
||||||
|
//(
|
||||||
|
// const point& start,
|
||||||
|
// const point& end
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// return tree().findLineAny(start, end);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// Find out if surface is closed.
|
||||||
|
bool Foam::triSurfaceMesh::hasVolumeType() const
|
||||||
|
{
|
||||||
|
if (surfaceClosed_ == -1)
|
||||||
|
{
|
||||||
|
if (isSurfaceClosed())
|
||||||
|
{
|
||||||
|
surfaceClosed_ = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
surfaceClosed_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return surfaceClosed_ == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::findNearest
|
||||||
|
(
|
||||||
|
const pointField& samples,
|
||||||
|
const scalarField& nearestDistSqr,
|
||||||
|
List<pointIndexHit>& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const indexedOctree<treeDataTriSurface>& octree = tree();
|
||||||
|
|
||||||
|
info.setSize(samples.size());
|
||||||
|
|
||||||
|
forAll(samples, i)
|
||||||
|
{
|
||||||
|
static_cast<pointIndexHit&>(info[i]) =
|
||||||
|
octree.findNearest(samples[i], nearestDistSqr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::findLine
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<pointIndexHit>& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const indexedOctree<treeDataTriSurface>& octree = tree();
|
||||||
|
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
forAll(start, i)
|
||||||
|
{
|
||||||
|
static_cast<pointIndexHit&>(info[i]) = octree.findLine
|
||||||
|
(
|
||||||
|
start[i],
|
||||||
|
end[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::findLineAny
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<pointIndexHit>& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const indexedOctree<treeDataTriSurface>& octree = tree();
|
||||||
|
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
forAll(start, i)
|
||||||
|
{
|
||||||
|
static_cast<pointIndexHit&>(info[i]) =
|
||||||
|
octree.findLineAny(start[i], end[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::findLineAll
|
||||||
|
(
|
||||||
|
const pointField& start,
|
||||||
|
const pointField& end,
|
||||||
|
List<List<pointIndexHit> >& info
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const indexedOctree<treeDataTriSurface>& octree = tree();
|
||||||
|
|
||||||
|
info.setSize(start.size());
|
||||||
|
|
||||||
|
// Work array
|
||||||
|
DynamicList<pointIndexHit, 1, 1> hits;
|
||||||
|
|
||||||
|
// Tolerances
|
||||||
|
const vectorField dirVec(end-start);
|
||||||
|
const scalarField magSqrDirVec(magSqr(dirVec));
|
||||||
|
const vectorField smallVec
|
||||||
|
(
|
||||||
|
Foam::sqrt(SMALL)*dirVec
|
||||||
|
+ vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(start, pointI)
|
||||||
|
{
|
||||||
|
hits.clear();
|
||||||
|
|
||||||
|
// Current starting point of ray.
|
||||||
|
point pt = start[pointI];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// See if any intersection between pt and end
|
||||||
|
pointIndexHit inter = octree.findLine(pt, end[pointI]);
|
||||||
|
|
||||||
|
if (!inter.hit())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hits.append(inter);
|
||||||
|
|
||||||
|
pt = inter.hitPoint() + smallVec[pointI];
|
||||||
|
|
||||||
|
if (((pt-start[pointI])&dirVec[pointI]) > magSqrDirVec[pointI])
|
||||||
|
{
|
||||||
|
// Adding smallVec has taken us beyond end
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hits.shrink();
|
||||||
|
info[pointI].transfer(hits);
|
||||||
|
hits.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::getRegion
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>& info,
|
||||||
|
labelList& region
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
region.setSize(info.size());
|
||||||
|
forAll(info, i)
|
||||||
|
{
|
||||||
|
if (info[i].hit())
|
||||||
|
{
|
||||||
|
region[i] = triSurface::operator[](info[i].index()).region();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
region[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::getNormal
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>& info,
|
||||||
|
vectorField& normal
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
normal.setSize(info.size());
|
||||||
|
|
||||||
|
forAll(info, i)
|
||||||
|
{
|
||||||
|
if (info[i].hit())
|
||||||
|
{
|
||||||
|
normal[i] = faceNormals()[info[i].index()];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set to what?
|
||||||
|
normal[i] = vector::zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::triSurfaceMesh::getVolumeType
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
List<volumeType>& volType
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
volType.setSize(points.size());
|
||||||
|
|
||||||
|
forAll(points, pointI)
|
||||||
|
{
|
||||||
|
const point& pt = points[pointI];
|
||||||
|
|
||||||
|
// - use cached volume type per each tree node
|
||||||
|
// - cheat conversion since same values
|
||||||
|
volType[pointI] = static_cast<volumeType>(tree().getVolumeType(pt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -54,7 +54,7 @@ namespace Foam
|
|||||||
class triSurfaceMesh
|
class triSurfaceMesh
|
||||||
:
|
:
|
||||||
public searchableSurface,
|
public searchableSurface,
|
||||||
public objectRegistry,
|
public objectRegistry, // so we can store fields
|
||||||
public triSurface
|
public triSurface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -67,6 +67,12 @@ private:
|
|||||||
//- Search tree for boundary edges.
|
//- Search tree for boundary edges.
|
||||||
mutable autoPtr<indexedOctree<treeDataEdge> > edgeTree_;
|
mutable autoPtr<indexedOctree<treeDataEdge> > edgeTree_;
|
||||||
|
|
||||||
|
//- Names of regions
|
||||||
|
mutable wordList regions_;
|
||||||
|
|
||||||
|
//- Is surface closed
|
||||||
|
mutable label surfaceClosed_;
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Check file existence
|
//- Check file existence
|
||||||
@ -76,6 +82,10 @@ private:
|
|||||||
const fileName& objectName
|
const fileName& objectName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Check whether surface is closed without calculating any permanent
|
||||||
|
// addressing.
|
||||||
|
bool isSurfaceClosed() const;
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
triSurfaceMesh(const triSurfaceMesh&);
|
triSurfaceMesh(const triSurfaceMesh&);
|
||||||
|
|
||||||
@ -97,11 +107,10 @@ public:
|
|||||||
//- Construct read
|
//- Construct read
|
||||||
triSurfaceMesh(const IOobject& io);
|
triSurfaceMesh(const IOobject& io);
|
||||||
|
|
||||||
//- Construct as searchableSurface
|
//- Construct from dictionary (used by searchableSurface)
|
||||||
triSurfaceMesh
|
triSurfaceMesh
|
||||||
(
|
(
|
||||||
const word& name,
|
const IOobject& io,
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -128,57 +137,73 @@ public:
|
|||||||
|
|
||||||
// searchableSurface implementation
|
// searchableSurface implementation
|
||||||
|
|
||||||
//- Calculate nearest point on surface. Returns
|
virtual const wordList& regions() const;
|
||||||
// - bool : any point found nearer than nearestDistSqr
|
|
||||||
// - label: relevant index in surface
|
//- Whether supports volume type below. I.e. whether is closed.
|
||||||
// - point: actual nearest point found
|
virtual bool hasVolumeType() const;
|
||||||
virtual pointIndexHit findNearest
|
|
||||||
|
|
||||||
|
// Multiple point queries.
|
||||||
|
|
||||||
|
virtual void findNearest
|
||||||
(
|
(
|
||||||
const point& sample,
|
const pointField& sample,
|
||||||
const scalar nearestDistSqr
|
const scalarField& nearestDistSqr,
|
||||||
|
List<pointIndexHit>&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Calculate nearest point on edge. Returns
|
virtual void findLine
|
||||||
// - bool : any point found nearer than nearestDistSqr
|
|
||||||
// - label: relevant index in surface
|
|
||||||
// - point: actual nearest point found
|
|
||||||
virtual pointIndexHit findNearestOnEdge
|
|
||||||
(
|
(
|
||||||
const point& sample,
|
const pointField& start,
|
||||||
const scalar nearestDistSqr
|
const pointField& end,
|
||||||
|
List<pointIndexHit>&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Find nearest to line. Returns
|
virtual void findLineAny
|
||||||
// - bool : any point found?
|
|
||||||
// - label: relevant index in shapes
|
|
||||||
// - point: actual nearest point found
|
|
||||||
// sets:
|
|
||||||
// - tightest : bounding box
|
|
||||||
// - linePoint : corresponding nearest point on line
|
|
||||||
virtual pointIndexHit findNearest
|
|
||||||
(
|
(
|
||||||
const linePointRef& ln,
|
const pointField& start,
|
||||||
treeBoundBox& tightest,
|
const pointField& end,
|
||||||
point& linePoint
|
List<pointIndexHit>&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Find nearest intersection of line between start and end.
|
//- Get all intersections in order from start to end.
|
||||||
virtual pointIndexHit findLine
|
virtual void findLineAll
|
||||||
(
|
(
|
||||||
const point& start,
|
const pointField& start,
|
||||||
const point& end
|
const pointField& end,
|
||||||
|
List<List<pointIndexHit> >&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Find any intersection of line between start and end.
|
//- From a set of points and indices get the region
|
||||||
virtual pointIndexHit findLineAny
|
virtual void getRegion
|
||||||
(
|
(
|
||||||
const point& start,
|
const List<pointIndexHit>&,
|
||||||
const point& end
|
labelList& region
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- From a set of points and indices get the normal
|
||||||
|
virtual void getNormal
|
||||||
|
(
|
||||||
|
const List<pointIndexHit>&,
|
||||||
|
vectorField& normal
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Determine type (inside/outside/mixed) for point. unknown if
|
//- Determine type (inside/outside/mixed) for point. unknown if
|
||||||
// cannot be determined (e.g. non-manifold surface)
|
// cannot be determined (e.g. non-manifold surface)
|
||||||
virtual volumeType getVolumeType(const point&) const;
|
virtual void getVolumeType
|
||||||
|
(
|
||||||
|
const pointField&,
|
||||||
|
List<volumeType>&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// regIOobject implementation
|
||||||
|
|
||||||
|
bool writeData(Ostream&) const
|
||||||
|
{
|
||||||
|
notImplemented("triSurfaceMesh::writeData(Ostream&) const");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1,247 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "searchableBox.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(searchableBox, 0);
|
|
||||||
addToRunTimeSelectionTable(searchableSurface, searchableBox, dict);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::searchableBox::searchableBox
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const treeBoundBox& bb
|
|
||||||
)
|
|
||||||
:
|
|
||||||
searchableSurface(name),
|
|
||||||
treeBoundBox(bb)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::searchableBox::searchableBox
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
searchableSurface(name),
|
|
||||||
treeBoundBox(dict.lookup("min"), dict.lookup("max"))
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::searchableBox::~searchableBox()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::searchableBox::findNearest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Point can be inside or outside. For every component direction can be
|
|
||||||
// left of min, right of max or inbetween.
|
|
||||||
// - outside points: project first one x plane (either min().x()
|
|
||||||
// or max().x()), then onto y plane and finally z. You should be left
|
|
||||||
// with intersection point
|
|
||||||
// - inside point: find nearest side (compare to mid point). Pick any
|
|
||||||
// one of three points.
|
|
||||||
|
|
||||||
const point bbMid(mid());
|
|
||||||
|
|
||||||
// Outside point projected onto cube
|
|
||||||
point interPt(sample);
|
|
||||||
bool outside = false;
|
|
||||||
|
|
||||||
// (for internal points) Per direction what nearest cube side is
|
|
||||||
point near;
|
|
||||||
|
|
||||||
for (direction dir = 0; dir < vector::nComponents; dir++)
|
|
||||||
{
|
|
||||||
if (interPt[dir] < min()[dir])
|
|
||||||
{
|
|
||||||
interPt[dir] = min()[dir];
|
|
||||||
outside = true;
|
|
||||||
}
|
|
||||||
else if (interPt[dir] > max()[dir])
|
|
||||||
{
|
|
||||||
interPt[dir] = max()[dir];
|
|
||||||
outside = true;
|
|
||||||
}
|
|
||||||
else if (interPt[dir] > bbMid[dir])
|
|
||||||
{
|
|
||||||
near[dir] = max()[dir];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
near[dir] = min()[dir];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// For outside points the interPt will be correct now. Handle inside points
|
|
||||||
// using the three near distances. Project onto the nearest plane.
|
|
||||||
if (!outside)
|
|
||||||
{
|
|
||||||
vector dist(cmptMag(interPt - near));
|
|
||||||
|
|
||||||
if (dist.x() < dist.y())
|
|
||||||
{
|
|
||||||
if (dist.x() < dist.z())
|
|
||||||
{
|
|
||||||
interPt.x() = near.x();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interPt.z() = near.z();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (dist.y() < dist.z())
|
|
||||||
{
|
|
||||||
interPt.y() = near.y();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interPt.z() = near.z();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pointIndexHit(true, interPt, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::searchableBox::findNearestOnEdge
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const point bbMid(mid());
|
|
||||||
|
|
||||||
point interPt(sample);
|
|
||||||
|
|
||||||
for (direction dir = 0; dir < vector::nComponents; dir++)
|
|
||||||
{
|
|
||||||
// Project onto left or right depending on mid
|
|
||||||
if (interPt[dir] > bbMid[dir])
|
|
||||||
{
|
|
||||||
interPt[dir] = max()[dir];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interPt[dir] = min()[dir];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pointIndexHit(true, interPt, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::searchableBox::findNearest
|
|
||||||
(
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
point& linePoint
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"searchableBox::findNearest"
|
|
||||||
"(const linePointRef&, treeBoundBox&, point&)"
|
|
||||||
);
|
|
||||||
return pointIndexHit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::searchableBox::findLine
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
point intPt;
|
|
||||||
bool foundInter = intersects(start, end, intPt);
|
|
||||||
|
|
||||||
return pointIndexHit(foundInter, intPt, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::searchableBox::findLineAny
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return findLine(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::searchableSurface::volumeType Foam::searchableBox::getVolumeType
|
|
||||||
(
|
|
||||||
const point& pt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
for (direction dir = 0; dir < vector::nComponents; dir++)
|
|
||||||
{
|
|
||||||
if (pt[dir] < min()[dir] || pt[dir] > max()[dir])
|
|
||||||
{
|
|
||||||
return OUTSIDE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return INSIDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::searchableBox
|
|
||||||
|
|
||||||
Description
|
|
||||||
Searching on bounding box
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
searchableBox.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef searchableBox_H
|
|
||||||
#define searchableBox_H
|
|
||||||
|
|
||||||
#include "searchableSurface.H"
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class searchableBox Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class searchableBox
|
|
||||||
:
|
|
||||||
public searchableSurface,
|
|
||||||
public treeBoundBox
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Private member data
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
searchableBox(const searchableBox&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const searchableBox&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("searchableBox");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
searchableBox(const word& name, const treeBoundBox& bb);
|
|
||||||
|
|
||||||
searchableBox
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
|
||||||
);
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~searchableBox();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Calculate nearest point on surface. Returns
|
|
||||||
// - bool : any point found nearer than nearestDistSqr
|
|
||||||
// - label: relevant index in surface
|
|
||||||
// - point: actual nearest point found
|
|
||||||
virtual pointIndexHit findNearest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculate nearest point on edge. Returns
|
|
||||||
// - bool : any point found nearer than nearestDistSqr
|
|
||||||
// - label: relevant index in surface
|
|
||||||
// - point: actual nearest point found
|
|
||||||
virtual pointIndexHit findNearestOnEdge
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest to line. Returns
|
|
||||||
// - bool : any point found?
|
|
||||||
// - label: relevant index in shapes
|
|
||||||
// - point: actual nearest point found
|
|
||||||
// sets:
|
|
||||||
// - tightest : bounding box
|
|
||||||
// - linePoint : corresponding nearest point on line
|
|
||||||
virtual pointIndexHit findNearest
|
|
||||||
(
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
point& linePoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest intersection of line between start and end.
|
|
||||||
virtual pointIndexHit findLine
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find any intersection of line between start and end.
|
|
||||||
virtual pointIndexHit findLineAny
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Determine type (inside/outside/mixed) for point. unknown if
|
|
||||||
// cannot be determined (e.g. non-manifold surface)
|
|
||||||
virtual volumeType getVolumeType(const point&) const;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,257 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::searchableSurface
|
|
||||||
|
|
||||||
Description
|
|
||||||
Base class of (analytical or triangulated) surface.
|
|
||||||
Encapsulates all the search routines.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
searchableSurface.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef searchableSurface_H
|
|
||||||
#define searchableSurface_H
|
|
||||||
|
|
||||||
#include "pointField.H"
|
|
||||||
#include "typeInfo.H"
|
|
||||||
#include "runTimeSelectionTables.H"
|
|
||||||
#include "pointIndexHit.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class objectRegistry;
|
|
||||||
class treeBoundBox;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class searchableSurface Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class searchableSurface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Data types
|
|
||||||
|
|
||||||
//- volume types
|
|
||||||
enum volumeType
|
|
||||||
{
|
|
||||||
UNKNOWN = 0,
|
|
||||||
MIXED = 1,
|
|
||||||
INSIDE = 2,
|
|
||||||
OUTSIDE = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
const word name_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
searchableSurface(const searchableSurface&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const searchableSurface&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("searchableSurface");
|
|
||||||
|
|
||||||
// Declare run-time constructor selection table
|
|
||||||
|
|
||||||
// For the dictionary constructor
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
searchableSurface,
|
|
||||||
dict,
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
|
||||||
),
|
|
||||||
(name, obj, dict)
|
|
||||||
);
|
|
||||||
|
|
||||||
//// For the Istream constructor
|
|
||||||
//declareRunTimeSelectionTable
|
|
||||||
//(
|
|
||||||
// autoPtr,
|
|
||||||
// searchableSurface,
|
|
||||||
// istream,
|
|
||||||
// (
|
|
||||||
// const objectRegistry& obj,
|
|
||||||
// Istream& is
|
|
||||||
// ),
|
|
||||||
// (obj, is)
|
|
||||||
//);
|
|
||||||
|
|
||||||
|
|
||||||
//- Class used for the read-construction of
|
|
||||||
// PtrLists of searchableSurface
|
|
||||||
class iNew
|
|
||||||
{
|
|
||||||
const objectRegistry& obj_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
iNew(const objectRegistry& obj)
|
|
||||||
:
|
|
||||||
obj_(obj)
|
|
||||||
{}
|
|
||||||
|
|
||||||
autoPtr<searchableSurface> operator()(Istream& is) const
|
|
||||||
{
|
|
||||||
word surfaceType(is);
|
|
||||||
word name(is);
|
|
||||||
dictionary dict(is);
|
|
||||||
return searchableSurface::New(surfaceType, name, obj_, dict);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
searchableSurface(const word& name);
|
|
||||||
|
|
||||||
//- Clone
|
|
||||||
virtual autoPtr<searchableSurface> clone() const
|
|
||||||
{
|
|
||||||
notImplemented("autoPtr<searchableSurface> clone() const");
|
|
||||||
return autoPtr<searchableSurface>(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
//- Return a reference to the selected searchableSurface
|
|
||||||
static autoPtr<searchableSurface> New
|
|
||||||
(
|
|
||||||
const word& surfaceType,
|
|
||||||
const word& name,
|
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
|
||||||
);
|
|
||||||
|
|
||||||
////- Return a reference to the selected searchableSurface
|
|
||||||
//static autoPtr<searchableSurface> New
|
|
||||||
//(
|
|
||||||
// const word& surfaceType,
|
|
||||||
// const objectRegistry& obj,
|
|
||||||
// Istream& is
|
|
||||||
//);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~searchableSurface();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return name
|
|
||||||
const word& name() const
|
|
||||||
{
|
|
||||||
return name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Calculate nearest point on surface. Returns
|
|
||||||
// - bool : any point found nearer than nearestDistSqr
|
|
||||||
// - label: relevant index in surface
|
|
||||||
// - point: actual nearest point found
|
|
||||||
virtual pointIndexHit findNearest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Calculate nearest point on edge. Returns
|
|
||||||
// - bool : any point found nearer than nearestDistSqr
|
|
||||||
// - label: relevant index in surface
|
|
||||||
// - point: actual nearest point found
|
|
||||||
virtual pointIndexHit findNearestOnEdge
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Find nearest to segment. Returns
|
|
||||||
// - bool : any point found?
|
|
||||||
// - label: relevant index in shapes
|
|
||||||
// - point: actual nearest point found
|
|
||||||
// sets:
|
|
||||||
// - tightest : bounding box
|
|
||||||
// - linePoint : corresponding nearest point on line
|
|
||||||
virtual pointIndexHit findNearest
|
|
||||||
(
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
point& linePoint
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Find nearest intersection of line between start and end.
|
|
||||||
virtual pointIndexHit findLine
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Find any intersection of line between start and end.
|
|
||||||
virtual pointIndexHit findLineAny
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Determine type (inside/outside/mixed) for point. unknown if
|
|
||||||
// cannot be determined (e.g. non-manifold surface)
|
|
||||||
virtual volumeType getVolumeType(const point&) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,271 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "triSurfaceMesh.H"
|
|
||||||
#include "Random.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(triSurfaceMesh, 0);
|
|
||||||
addToRunTimeSelectionTable(searchableSurface, triSurfaceMesh, dict);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
//- Check file existence
|
|
||||||
const Foam::fileName& Foam::triSurfaceMesh::checkFile
|
|
||||||
(
|
|
||||||
const fileName& fName,
|
|
||||||
const fileName& objectName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (fName == fileName::null)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"triSurfaceMesh::checkFile(const fileName&, const fileName&)"
|
|
||||||
) << "Cannot find triSurfaceMesh starting from "
|
|
||||||
<< objectName << exit(FatalError);
|
|
||||||
}
|
|
||||||
return fName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Foam::indexedOctree<Foam::treeDataTriSurface>&
|
|
||||||
Foam::triSurfaceMesh::tree() const
|
|
||||||
{
|
|
||||||
if (!tree_.valid())
|
|
||||||
{
|
|
||||||
treeBoundBox bb(points(), meshPoints());
|
|
||||||
|
|
||||||
// Random number generator. Bit dodgy since not exactly random ;-)
|
|
||||||
Random rndGen(65431);
|
|
||||||
|
|
||||||
tree_.reset
|
|
||||||
(
|
|
||||||
new indexedOctree<treeDataTriSurface>
|
|
||||||
(
|
|
||||||
treeDataTriSurface(*this),
|
|
||||||
bb.extend(rndGen, 1E-3), // slightly randomize bb
|
|
||||||
8, // maxLevel
|
|
||||||
10, // leafsize
|
|
||||||
3.0 // duplicity
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tree_();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Foam::indexedOctree<Foam::treeDataEdge>&
|
|
||||||
Foam::triSurfaceMesh::edgeTree() const
|
|
||||||
{
|
|
||||||
if (!edgeTree_.valid())
|
|
||||||
{
|
|
||||||
treeBoundBox bb(localPoints());
|
|
||||||
|
|
||||||
// Boundary edges
|
|
||||||
labelList bEdges
|
|
||||||
(
|
|
||||||
identity
|
|
||||||
(
|
|
||||||
nEdges()
|
|
||||||
-nInternalEdges()
|
|
||||||
)
|
|
||||||
+ nInternalEdges()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Random number generator. Bit dodgy since not exactly random ;-)
|
|
||||||
Random rndGen(65431);
|
|
||||||
|
|
||||||
edgeTree_.reset
|
|
||||||
(
|
|
||||||
new indexedOctree<treeDataEdge>
|
|
||||||
(
|
|
||||||
treeDataEdge
|
|
||||||
(
|
|
||||||
false, // cachebb
|
|
||||||
edges(), // edges
|
|
||||||
localPoints(), // points
|
|
||||||
bEdges // selected edges
|
|
||||||
),
|
|
||||||
bb.extend(rndGen, 1E-3), // slightly randomize bb
|
|
||||||
8, // maxLevel
|
|
||||||
10, // leafsize
|
|
||||||
3.0 // duplicity
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return edgeTree_();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
//- Construct from triangles, patches, points.
|
|
||||||
Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
|
|
||||||
:
|
|
||||||
searchableSurface(io.name()),
|
|
||||||
objectRegistry(io),
|
|
||||||
triSurface(s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
|
|
||||||
:
|
|
||||||
searchableSurface(io.name()),
|
|
||||||
objectRegistry(io),
|
|
||||||
triSurface(checkFile(filePath(), objectPath()))
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::triSurfaceMesh::triSurfaceMesh
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const objectRegistry& obj,
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
searchableSurface(name),
|
|
||||||
objectRegistry
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
name,
|
|
||||||
"constant",
|
|
||||||
"triSurface",
|
|
||||||
obj,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
)
|
|
||||||
),
|
|
||||||
triSurface(checkFile(filePath(), objectPath()))
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::triSurfaceMesh::~triSurfaceMesh()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::triSurfaceMesh::clearOut()
|
|
||||||
{
|
|
||||||
tree_.clear();
|
|
||||||
edgeTree_.clear();
|
|
||||||
triSurface::clearOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::triSurfaceMesh::movePoints(const pointField& newPoints)
|
|
||||||
{
|
|
||||||
tree_.clear();
|
|
||||||
edgeTree_.clear();
|
|
||||||
triSurface::movePoints(newPoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::triSurfaceMesh::findNearest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return tree().findNearest(sample, nearestDistSqr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::triSurfaceMesh::findNearestOnEdge
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
const scalar nearestDistSqr
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return edgeTree().findNearest(sample, nearestDistSqr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::triSurfaceMesh::findNearest
|
|
||||||
(
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
point& linePoint
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return tree().findNearest(ln, tightest, linePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::triSurfaceMesh::findLine
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return tree().findLine(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::pointIndexHit Foam::triSurfaceMesh::findLineAny
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return tree().findLineAny(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::searchableSurface::volumeType
|
|
||||||
Foam::triSurfaceMesh::getVolumeType
|
|
||||||
(
|
|
||||||
const point& pt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// - use cached volume type per each tree node
|
|
||||||
// - cheat conversion since same values
|
|
||||||
return static_cast<volumeType>(tree().getVolumeType(pt));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,916 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "triSurfaceMeshes.H"
|
|
||||||
#include "Random.H"
|
|
||||||
#include "Time.H"
|
|
||||||
#include "SortableList.H"
|
|
||||||
#include "IOmanip.H"
|
|
||||||
#include "plane.H"
|
|
||||||
#include "SortableList.H"
|
|
||||||
#include "triSurfaceTools.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(triSurfaceMeshes, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Calculate sum of distance to surfaces.
|
|
||||||
Foam::scalar Foam::triSurfaceMeshes::sumDistSqr
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initDistSqr,
|
|
||||||
const point& pt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
scalar sum = 0;
|
|
||||||
|
|
||||||
forAll(surfacesToTest, i)
|
|
||||||
{
|
|
||||||
label surfI = surfacesToTest[i];
|
|
||||||
|
|
||||||
pointIndexHit hit(operator[](surfI).findNearest(pt, initDistSqr));
|
|
||||||
|
|
||||||
// Note: make it fall over if not hit.
|
|
||||||
sum += magSqr(hit.hitPoint()-pt);
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Reflects the point furthest away around the triangle centre by a factor fac.
|
|
||||||
// (triangle centre is the average of all points but the ihi. pSum is running
|
|
||||||
// sum of all points)
|
|
||||||
Foam::scalar Foam::triSurfaceMeshes::tryMorphTet
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initDistSqr,
|
|
||||||
List<vector>& p,
|
|
||||||
List<scalar>& y,
|
|
||||||
vector& pSum,
|
|
||||||
const label ihi,
|
|
||||||
const scalar fac
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
scalar fac1 = (1.0-fac)/vector::nComponents;
|
|
||||||
scalar fac2 = fac1-fac;
|
|
||||||
|
|
||||||
vector ptry = pSum*fac1-p[ihi]*fac2;
|
|
||||||
|
|
||||||
scalar ytry = sumDistSqr(surfacesToTest, initDistSqr, ptry);
|
|
||||||
|
|
||||||
if (ytry < y[ihi])
|
|
||||||
{
|
|
||||||
y[ihi] = ytry;
|
|
||||||
pSum += ptry - p[ihi];
|
|
||||||
p[ihi] = ptry;
|
|
||||||
}
|
|
||||||
return ytry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::triSurfaceMeshes::morphTet
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initDistSqr,
|
|
||||||
const scalar convergenceDistSqr,
|
|
||||||
const label maxIter,
|
|
||||||
List<vector>& p,
|
|
||||||
List<scalar>& y
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
vector pSum = sum(p);
|
|
||||||
|
|
||||||
autoPtr<OFstream> str;
|
|
||||||
label vertI = 0;
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "triSurfaceMeshes::morphTet : intersection of "
|
|
||||||
<< IndirectList<fileName>(names(), surfacesToTest)()
|
|
||||||
<< " starting from points:" << p << endl;
|
|
||||||
str.reset(new OFstream("track.obj"));
|
|
||||||
meshTools::writeOBJ(str(), p[0]);
|
|
||||||
vertI++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (label iter = 0; iter < maxIter; iter++)
|
|
||||||
{
|
|
||||||
// Get the indices of highest, second-highest and lowest values.
|
|
||||||
label ihi, inhi, ilo;
|
|
||||||
{
|
|
||||||
SortableList<scalar> sortedY(y);
|
|
||||||
ilo = sortedY.indices()[0];
|
|
||||||
ihi = sortedY.indices()[sortedY.size()-1];
|
|
||||||
inhi = sortedY.indices()[sortedY.size()-2];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Iteration:" << iter
|
|
||||||
<< " lowest:" << y[ilo] << " highest:" << y[ihi]
|
|
||||||
<< " points:" << p << endl;
|
|
||||||
|
|
||||||
meshTools::writeOBJ(str(), p[ilo]);
|
|
||||||
vertI++;
|
|
||||||
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y[ihi] < convergenceDistSqr)
|
|
||||||
{
|
|
||||||
// Get point on 0th surface.
|
|
||||||
Swap(p[0], p[ilo]);
|
|
||||||
Swap(y[0], y[ilo]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reflection: point furthest away gets reflected.
|
|
||||||
scalar ytry = tryMorphTet
|
|
||||||
(
|
|
||||||
surfacesToTest,
|
|
||||||
10*y[ihi], // search box.
|
|
||||||
p,
|
|
||||||
y,
|
|
||||||
pSum,
|
|
||||||
ihi,
|
|
||||||
-1.0
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ytry <= y[ilo])
|
|
||||||
{
|
|
||||||
// If in right direction (y lower) expand by two.
|
|
||||||
ytry = tryMorphTet(surfacesToTest, 10*y[ihi], p, y, pSum, ihi, 2.0);
|
|
||||||
}
|
|
||||||
else if (ytry >= y[inhi])
|
|
||||||
{
|
|
||||||
// If inside tet try contraction.
|
|
||||||
|
|
||||||
scalar ysave = y[ihi];
|
|
||||||
|
|
||||||
ytry = tryMorphTet(surfacesToTest, 10*y[ihi], p, y, pSum, ihi, 0.5);
|
|
||||||
|
|
||||||
if (ytry >= ysave)
|
|
||||||
{
|
|
||||||
// Contract around lowest point.
|
|
||||||
forAll(p, i)
|
|
||||||
{
|
|
||||||
if (i != ilo)
|
|
||||||
{
|
|
||||||
p[i] = 0.5*(p[i] + p[ilo]);
|
|
||||||
y[i] = sumDistSqr(surfacesToTest, y[ihi], p[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pSum = sum(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
meshTools::writeOBJ(str(), p[0]);
|
|
||||||
vertI++;
|
|
||||||
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Failure to converge. Return best guess so far.
|
|
||||||
label ilo = findMin(y);
|
|
||||||
Swap(p[0], p[ilo]);
|
|
||||||
Swap(y[0], y[ilo]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::triSurfaceMeshes::triSurfaceMeshes
|
|
||||||
(
|
|
||||||
const IOobject& io,
|
|
||||||
const fileNameList& names
|
|
||||||
)
|
|
||||||
:
|
|
||||||
PtrList<triSurfaceMesh>(names.size()),
|
|
||||||
allSurfaces_(identity(names.size()))
|
|
||||||
{
|
|
||||||
forAll(names, i)
|
|
||||||
{
|
|
||||||
autoPtr<IOobject> surfaceIO = io.clone();
|
|
||||||
surfaceIO().rename(names[i]);
|
|
||||||
|
|
||||||
Info<< "Loading surface " << surfaceIO().name() << endl;
|
|
||||||
|
|
||||||
//fileName fullPath = surfaceIO().filePath();
|
|
||||||
//
|
|
||||||
//if (fullPath.size() == 0)
|
|
||||||
//{
|
|
||||||
// FatalErrorIn
|
|
||||||
// (
|
|
||||||
// "triSurfaceMeshes::triSurfaceMeshes"
|
|
||||||
// "(const IOobject&, const fileNameList&)"
|
|
||||||
// ) << "Cannot load surface " << surfaceIO().name()
|
|
||||||
// << " starting from path " << surfaceIO().path()
|
|
||||||
// << exit(FatalError);
|
|
||||||
//}
|
|
||||||
|
|
||||||
set(i, new triSurfaceMesh(surfaceIO()));
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
string oldPrefix(Pout.prefix());
|
|
||||||
Pout.prefix() += " ";
|
|
||||||
operator[](i).writeStats(Pout);
|
|
||||||
Pout.prefix() = oldPrefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::fileNameList Foam::triSurfaceMeshes::allNames(const IOobject& io)
|
|
||||||
{
|
|
||||||
return readDir(io.path(), fileName::FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::fileNameList Foam::triSurfaceMeshes::names() const
|
|
||||||
{
|
|
||||||
fileNameList surfNames(size());
|
|
||||||
|
|
||||||
forAll(surfNames, surfI)
|
|
||||||
{
|
|
||||||
surfNames[surfI] = operator[](surfI).IOobject::name();
|
|
||||||
}
|
|
||||||
return surfNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find any intersection
|
|
||||||
Foam::label Foam::triSurfaceMeshes::findAnyIntersection
|
|
||||||
(
|
|
||||||
const labelList& surfaces,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
pointIndexHit& hitInfo
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
forAll(surfaces, i)
|
|
||||||
{
|
|
||||||
label surfI = surfaces[i];
|
|
||||||
|
|
||||||
hitInfo = operator[](surfI).findLineAny(start, end);
|
|
||||||
|
|
||||||
if (hitInfo.hit())
|
|
||||||
{
|
|
||||||
return surfI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::triSurfaceMeshes::findAnyIntersection
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
pointIndexHit& hitInfo
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return findAnyIntersection
|
|
||||||
(
|
|
||||||
allSurfaces_,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
hitInfo
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find intersections of edge nearest to both endpoints.
|
|
||||||
void Foam::triSurfaceMeshes::findAllIntersections
|
|
||||||
(
|
|
||||||
const labelList& surfaces,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
|
|
||||||
labelList& surfacesIndex,
|
|
||||||
List<pointIndexHit>& surfaceHitInfo
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
DynamicList<label> hitSurfaces(surfaces.size());
|
|
||||||
DynamicList<pointIndexHit> hitInfos(surfaces.size());
|
|
||||||
DynamicList<scalar> hitDistSqr(surfaces.size());
|
|
||||||
|
|
||||||
const vector dirVec(end-start);
|
|
||||||
const scalar magSqrDirVec(magSqr(dirVec));
|
|
||||||
const vector smallVec(Foam::sqrt(SMALL)*dirVec);
|
|
||||||
|
|
||||||
forAll(surfaces, i)
|
|
||||||
{
|
|
||||||
label surfI = surfaces[i];
|
|
||||||
|
|
||||||
// Current starting point of ray.
|
|
||||||
point pt = start;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// See if any intersection between pt and end
|
|
||||||
pointIndexHit inter = operator[](surfI).findLine(pt, end);
|
|
||||||
|
|
||||||
if (!inter.hit())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
hitSurfaces.append(surfI);
|
|
||||||
hitInfos.append(inter);
|
|
||||||
hitDistSqr.append(magSqr(inter.hitPoint() - start));
|
|
||||||
|
|
||||||
pt = inter.hitPoint() + smallVec;
|
|
||||||
|
|
||||||
if (((pt-start)&dirVec) > magSqrDirVec)
|
|
||||||
{
|
|
||||||
// Adding smallVec has taken us beyond end
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
surfacesIndex.setSize(hitSurfaces.size());
|
|
||||||
surfaceHitInfo.setSize(hitSurfaces.size());
|
|
||||||
|
|
||||||
if (hitSurfaces.size() > 0)
|
|
||||||
{
|
|
||||||
// Sort and transfer to arguments
|
|
||||||
|
|
||||||
hitSurfaces.shrink();
|
|
||||||
hitInfos.shrink();
|
|
||||||
hitDistSqr.shrink();
|
|
||||||
|
|
||||||
// Sort from start to end.
|
|
||||||
SortableList<scalar> sortedDist(hitDistSqr);
|
|
||||||
|
|
||||||
forAll(sortedDist.indices(), newPos)
|
|
||||||
{
|
|
||||||
label oldPos = sortedDist.indices()[newPos];
|
|
||||||
surfacesIndex[newPos] = hitSurfaces[oldPos];
|
|
||||||
surfaceHitInfo[newPos] = hitInfos[oldPos];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::triSurfaceMeshes::findAllIntersections
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
|
|
||||||
labelList& surfacesIndex,
|
|
||||||
List<pointIndexHit>& surfaceHitInfo
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
findAllIntersections
|
|
||||||
(
|
|
||||||
allSurfaces_,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
surfacesIndex,
|
|
||||||
surfaceHitInfo
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find intersections of edge nearest to both endpoints.
|
|
||||||
void Foam::triSurfaceMeshes::findNearestIntersection
|
|
||||||
(
|
|
||||||
const labelList& surfaces,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
|
|
||||||
label& surface1,
|
|
||||||
pointIndexHit& hit1,
|
|
||||||
label& surface2,
|
|
||||||
pointIndexHit& hit2
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
surface1 = -1;
|
|
||||||
// Initialize to endpoint
|
|
||||||
hit1 = pointIndexHit(false, end, -1);
|
|
||||||
|
|
||||||
forAll(surfaces, i)
|
|
||||||
{
|
|
||||||
label surfI = surfaces[i];
|
|
||||||
|
|
||||||
if (hit1.rawPoint() == start)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if any intersection between start and current nearest
|
|
||||||
pointIndexHit inter = operator[](surfI).findLine
|
|
||||||
(
|
|
||||||
start,
|
|
||||||
hit1.rawPoint()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (inter.hit())
|
|
||||||
{
|
|
||||||
hit1 = inter;
|
|
||||||
surface1 = surfI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find the nearest intersection from end to start. Note that we initialize
|
|
||||||
// to the first intersection (if any).
|
|
||||||
surface2 = surface1;
|
|
||||||
hit2 = pointIndexHit(hit1);
|
|
||||||
|
|
||||||
if (hit1.hit())
|
|
||||||
{
|
|
||||||
// Test from the end side.
|
|
||||||
forAll(surfaces, i)
|
|
||||||
{
|
|
||||||
label surfI = surfaces[i];
|
|
||||||
|
|
||||||
if (hit2.rawPoint() == end)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if any intersection between end and current nearest
|
|
||||||
pointIndexHit inter = operator[](surfI).findLine
|
|
||||||
(
|
|
||||||
end,
|
|
||||||
hit2.rawPoint()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (inter.hit())
|
|
||||||
{
|
|
||||||
hit2 = inter;
|
|
||||||
surface2 = surfI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::triSurfaceMeshes::findNearestIntersection
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
|
|
||||||
label& surface1,
|
|
||||||
pointIndexHit& hit1,
|
|
||||||
label& surface2,
|
|
||||||
pointIndexHit& hit2
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
findNearestIntersection
|
|
||||||
(
|
|
||||||
allSurfaces_,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
surface1,
|
|
||||||
hit1,
|
|
||||||
surface2,
|
|
||||||
hit2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find nearest. Return -1 or nearest point
|
|
||||||
Foam::label Foam::triSurfaceMeshes::findNearest
|
|
||||||
(
|
|
||||||
const labelList& surfaces,
|
|
||||||
const point& pt,
|
|
||||||
const scalar nearestDistSqr,
|
|
||||||
pointIndexHit& nearestHit
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// nearest surface
|
|
||||||
label minSurface = -1;
|
|
||||||
scalar minDistSqr = Foam::sqr(GREAT);
|
|
||||||
|
|
||||||
forAll(surfaces, i)
|
|
||||||
{
|
|
||||||
label surfI = surfaces[i];
|
|
||||||
|
|
||||||
pointIndexHit hit
|
|
||||||
(
|
|
||||||
operator[](surfI).findNearest(pt, nearestDistSqr)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hit.hit())
|
|
||||||
{
|
|
||||||
scalar distSqr = magSqr(hit.hitPoint()-pt);
|
|
||||||
|
|
||||||
if (distSqr < minDistSqr)
|
|
||||||
{
|
|
||||||
minDistSqr = distSqr;
|
|
||||||
minSurface = surfI;
|
|
||||||
nearestHit = hit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minSurface == -1)
|
|
||||||
{
|
|
||||||
// maxLevel unchanged. No interesting surface hit.
|
|
||||||
nearestHit.setMiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
return minSurface;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find nearest. Return -1 or nearest point
|
|
||||||
Foam::label Foam::triSurfaceMeshes::findNearest
|
|
||||||
(
|
|
||||||
const point& pt,
|
|
||||||
const scalar nearestDistSqr,
|
|
||||||
pointIndexHit& nearestHit
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return findNearest
|
|
||||||
(
|
|
||||||
allSurfaces_,
|
|
||||||
pt,
|
|
||||||
nearestDistSqr,
|
|
||||||
nearestHit
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::triSurfaceMeshes::findNearestAndClassify
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const point& pt,
|
|
||||||
const scalar nearestDistSqr,
|
|
||||||
surfaceLocation& nearest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
pointIndexHit nearestInfo;
|
|
||||||
label surfI = findNearest
|
|
||||||
(
|
|
||||||
surfacesToTest,
|
|
||||||
pt,
|
|
||||||
nearestDistSqr,
|
|
||||||
nearestInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
if (surfI != -1)
|
|
||||||
{
|
|
||||||
nearest = triSurfaceTools::classify
|
|
||||||
(
|
|
||||||
operator[](surfI),
|
|
||||||
nearestInfo.index(), // triangle
|
|
||||||
nearestInfo.rawPoint() // point on edge/inside triangle
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return surfI;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Calculate point which is on a set of surfaces.
|
|
||||||
Foam::surfaceLocation Foam::triSurfaceMeshes::facesIntersectionTrack
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initialDistSqr,
|
|
||||||
const scalar convergenceDistSqr,
|
|
||||||
const point& start
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
autoPtr<OFstream> str;
|
|
||||||
label vertI = 0;
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
str.reset(new OFstream("track.obj"));
|
|
||||||
}
|
|
||||||
|
|
||||||
surfaceLocation current
|
|
||||||
(
|
|
||||||
pointIndexHit
|
|
||||||
(
|
|
||||||
false,
|
|
||||||
start,
|
|
||||||
-1
|
|
||||||
),
|
|
||||||
triPointRef::NONE,
|
|
||||||
-1
|
|
||||||
);
|
|
||||||
|
|
||||||
// Dump start point
|
|
||||||
if (str.valid())
|
|
||||||
{
|
|
||||||
Pout<< "Starting at " << current.info()
|
|
||||||
<< " written as point " << vertI
|
|
||||||
<< endl;
|
|
||||||
meshTools::writeOBJ(str(), current.rawPoint());
|
|
||||||
vertI++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now slide current along all faces until it settles
|
|
||||||
label iter = 0;
|
|
||||||
|
|
||||||
const label maxIter = 10;
|
|
||||||
|
|
||||||
for (; iter < maxIter; iter++)
|
|
||||||
{
|
|
||||||
// - store old position
|
|
||||||
// - slide it along all faces
|
|
||||||
// - if it hasn't changed position exit loop
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< endl
|
|
||||||
<< "Iteration " << iter << endl
|
|
||||||
<< "-----------" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
point oldCurrent = current.rawPoint();
|
|
||||||
|
|
||||||
forAll(surfacesToTest, i)
|
|
||||||
{
|
|
||||||
label surfI = surfacesToTest[i];
|
|
||||||
|
|
||||||
// Project pt onto surf
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
|
||||||
point copy(current.rawPoint()); // need to work on copy
|
|
||||||
if
|
|
||||||
(
|
|
||||||
findNearestAndClassify
|
|
||||||
(
|
|
||||||
labelList(1, surfI),
|
|
||||||
copy,
|
|
||||||
initialDistSqr, // initialDistSqr
|
|
||||||
current
|
|
||||||
)
|
|
||||||
== -1
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorIn("triSurfaceMeshes::facesIntersectionTrack(..)")
|
|
||||||
<< "Did not find a point on surface " << surfI
|
|
||||||
<< " which is within sqrt(" << initialDistSqr
|
|
||||||
<< ") of " << copy
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Nearest onto surface " << surfI
|
|
||||||
<< ' ' << operator[](surfI).IOobject::name() << " : "
|
|
||||||
<< current.info() << " written as point " << vertI
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump current
|
|
||||||
if (str.valid())
|
|
||||||
{
|
|
||||||
meshTools::writeOBJ(str(), current.rawPoint());
|
|
||||||
vertI++;
|
|
||||||
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find corresponding point on next surface
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
label nextSurfI = surfacesToTest[surfacesToTest.fcIndex(i)];
|
|
||||||
|
|
||||||
surfaceLocation next;
|
|
||||||
findNearestAndClassify
|
|
||||||
(
|
|
||||||
labelList(1, nextSurfI),
|
|
||||||
point(current.rawPoint()),
|
|
||||||
initialDistSqr, // initialDistSqr
|
|
||||||
next
|
|
||||||
);
|
|
||||||
|
|
||||||
// Since next is on a different surface we cannot compare
|
|
||||||
// indices (like in snapToEnd) so make sure this does not
|
|
||||||
// happen.
|
|
||||||
next.elementType() = triPointRef::NONE;
|
|
||||||
next.setIndex(-123);
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Nearest onto next surface " << nextSurfI
|
|
||||||
<< ' ' << operator[](nextSurfI).IOobject::name() << " : "
|
|
||||||
<< next.info() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
magSqr(current.rawPoint() - next.rawPoint())
|
|
||||||
> convergenceDistSqr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Track from current to next
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
//vector n = current.normal(surfaces[surfI]);
|
|
||||||
|
|
||||||
current = triSurfaceTools::trackToEdge
|
|
||||||
(
|
|
||||||
operator[](surfI),
|
|
||||||
current,
|
|
||||||
next,
|
|
||||||
plane(start, current.rawPoint(), next.rawPoint())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Sliding along surface "
|
|
||||||
<< surfI << ' ' << operator[](surfI).IOobject::name()
|
|
||||||
<< " in direction of "
|
|
||||||
<< nextSurfI << ' '
|
|
||||||
<< operator[](nextSurfI).IOobject::name()
|
|
||||||
<< " stopped at " << current.info()
|
|
||||||
<< " written as point " << vertI << endl;
|
|
||||||
}
|
|
||||||
if (str.valid())
|
|
||||||
{
|
|
||||||
meshTools::writeOBJ(str(), current.rawPoint());
|
|
||||||
vertI++;
|
|
||||||
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar distSqr = magSqr(oldCurrent - current.rawPoint());
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "distSqr:" << distSqr
|
|
||||||
<< " convergenceDistSqr:" << convergenceDistSqr << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distSqr < convergenceDistSqr)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter == maxIter)
|
|
||||||
{
|
|
||||||
FatalErrorIn("triSurfaceMeshes::facesIntersectionTrack(..)")
|
|
||||||
<< "Did not converge in " << iter
|
|
||||||
<< " iterations to find a point which is on surfaces "
|
|
||||||
<< IndirectList<fileName>(names(), surfacesToTest)() << nl
|
|
||||||
<< "Start point:" << start << nl
|
|
||||||
<< "Current nearest:" << current.info() << nl
|
|
||||||
<< "Please check that your surfaces actually intersect and"
|
|
||||||
<< " that the starting point is close to the intersection point."
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Calculate point which is on a set of surfaces.
|
|
||||||
Foam::pointIndexHit Foam::triSurfaceMeshes::facesIntersection
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initDistSqr,
|
|
||||||
const scalar convergenceDistSqr,
|
|
||||||
const point& start
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Get four starting points. Take these as the projection of the
|
|
||||||
// starting point onto the surfaces and the mid point
|
|
||||||
List<point> nearest(surfacesToTest.size()+1);
|
|
||||||
|
|
||||||
point sumNearest = vector::zero;
|
|
||||||
|
|
||||||
forAll(surfacesToTest, i)
|
|
||||||
{
|
|
||||||
label surfI = surfacesToTest[i];
|
|
||||||
|
|
||||||
pointIndexHit hit
|
|
||||||
(
|
|
||||||
operator[](surfI).findNearest(start, initDistSqr)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hit.hit())
|
|
||||||
{
|
|
||||||
nearest[i] = hit.hitPoint();
|
|
||||||
sumNearest += nearest[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"triSurfaceMeshes::facesIntersection"
|
|
||||||
"(const labelList&, const scalar, const scalar, const point&)"
|
|
||||||
) << "Did not find point within distance "
|
|
||||||
<< initDistSqr << " of starting point " << start
|
|
||||||
<< " on surface " << operator[](surfI).IOobject::name()
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nearest[nearest.size()-1] = sumNearest / surfacesToTest.size();
|
|
||||||
|
|
||||||
|
|
||||||
// Get the sum of distances (initial evaluation)
|
|
||||||
List<scalar> nearestDist(nearest.size());
|
|
||||||
|
|
||||||
forAll(nearestDist, i)
|
|
||||||
{
|
|
||||||
nearestDist[i] = sumDistSqr(surfacesToTest, initDistSqr, nearest[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Downhill Simplex method
|
|
||||||
|
|
||||||
bool converged = morphTet
|
|
||||||
(
|
|
||||||
surfacesToTest,
|
|
||||||
initDistSqr,
|
|
||||||
convergenceDistSqr,
|
|
||||||
2000,
|
|
||||||
nearest,
|
|
||||||
nearestDist
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
pointIndexHit intersection;
|
|
||||||
|
|
||||||
if (converged)
|
|
||||||
{
|
|
||||||
// Project nearest onto 0th surface.
|
|
||||||
intersection = operator[](surfacesToTest[0]).findNearest
|
|
||||||
(
|
|
||||||
nearest[0],
|
|
||||||
nearestDist[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (!intersection.hit())
|
|
||||||
//{
|
|
||||||
// // Restart
|
|
||||||
// scalar smallDist = Foam::sqr(convergenceDistSqr);
|
|
||||||
// nearest[0] = intersection.hitPoint();
|
|
||||||
// nearest[1] = nearest[0];
|
|
||||||
// nearest[1].x() += smallDist;
|
|
||||||
// nearest[2] = nearest[0];
|
|
||||||
// nearest[2].y() += smallDist;
|
|
||||||
// nearest[3] = nearest[0];
|
|
||||||
// nearest[3].z() += smallDist;
|
|
||||||
//
|
|
||||||
// forAll(nearestDist, i)
|
|
||||||
// {
|
|
||||||
// nearestDist[i] = sumDistSqr
|
|
||||||
// (
|
|
||||||
// surfacesToTest,
|
|
||||||
// initDistSqr,
|
|
||||||
// nearest[i]
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// intersection = morphTet
|
|
||||||
// (
|
|
||||||
// surfacesToTest,
|
|
||||||
// initDistSqr,
|
|
||||||
// convergenceDistSqr,
|
|
||||||
// 1000,
|
|
||||||
// nearest,
|
|
||||||
// nearestDist
|
|
||||||
// );
|
|
||||||
//}
|
|
||||||
|
|
||||||
return intersection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,261 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::triSurfaceMeshes
|
|
||||||
|
|
||||||
Description
|
|
||||||
Container for triSurfaces read from files.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
triSurfaceMeshes.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef triSurfaceMeshes_H
|
|
||||||
#define triSurfaceMeshes_H
|
|
||||||
|
|
||||||
#include "triSurfaceMesh.H"
|
|
||||||
#include "fileNameList.H"
|
|
||||||
#include "treeDataTriSurface.H"
|
|
||||||
#include "indexedOctree.H"
|
|
||||||
#include "surfaceLocation.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class plane;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class triSurfaceMeshes Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class triSurfaceMeshes
|
|
||||||
:
|
|
||||||
public PtrList<triSurfaceMesh>
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Indices of all surfaces. Precalculated and stored.
|
|
||||||
const labelList allSurfaces_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Calculate sum of distances to nearest point on surfaces. Is used
|
|
||||||
// in minimisation to find intersection. Returns sum of (square of)
|
|
||||||
// distances to the surfaces.
|
|
||||||
scalar sumDistSqr
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initialDistSqr, // search box
|
|
||||||
const point& pt
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Takes the tet (points p) and reflects the point with the
|
|
||||||
// highest value around the centre (pSum). Checks if it gets closer
|
|
||||||
// and updates p, y if so.
|
|
||||||
scalar tryMorphTet
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initialDistSqr,
|
|
||||||
List<vector>& p,
|
|
||||||
List<scalar>& y,
|
|
||||||
vector& pSum,
|
|
||||||
const label ihi,
|
|
||||||
const scalar fac
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Downhill simplex method: find the point with min cumulative
|
|
||||||
// distance to all surfaces. Does so by morphing a tet (points p).
|
|
||||||
// Returns the point on the 0th surface or hit if not reached within
|
|
||||||
// maxIters iterations.
|
|
||||||
bool morphTet
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initialDistSqr,
|
|
||||||
const scalar convergenceDistSqr,
|
|
||||||
const label maxIter,
|
|
||||||
List<vector>& p,
|
|
||||||
List<scalar>& y
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
triSurfaceMeshes(const triSurfaceMeshes&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const triSurfaceMeshes&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
ClassName("triSurfaceMeshes");
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from directory (io.instance()) and list of local filenames
|
|
||||||
triSurfaceMeshes(const IOobject& io, const fileNameList&);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Get all surfaces in directory
|
|
||||||
static fileNameList allNames(const IOobject&);
|
|
||||||
|
|
||||||
//- Get names of surfaces
|
|
||||||
fileNameList names() const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Find any intersection. Return hit point information and surface
|
|
||||||
// number
|
|
||||||
label findAnyIntersection
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
pointIndexHit&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
label findAnyIntersection
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
pointIndexHit&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Find all intersections in order from start to end. Returns for
|
|
||||||
// every hit the surface and the hit info.
|
|
||||||
void findAllIntersections
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
labelList& surfaces,
|
|
||||||
List<pointIndexHit>& surfaceHits
|
|
||||||
) const;
|
|
||||||
|
|
||||||
void findAllIntersections
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
labelList& surfaces,
|
|
||||||
List<pointIndexHit>& surfaceHits
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Find intersections of edge nearest to both endpoints.
|
|
||||||
void findNearestIntersection
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
|
|
||||||
label& surface1, // surface index
|
|
||||||
pointIndexHit& hit1, // hit point information
|
|
||||||
label& surface2,
|
|
||||||
pointIndexHit& hit2
|
|
||||||
) const;
|
|
||||||
|
|
||||||
void findNearestIntersection
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
|
|
||||||
label& surface1, // surface index
|
|
||||||
pointIndexHit& hit1, // hit point information
|
|
||||||
label& surface2,
|
|
||||||
pointIndexHit& hit2
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Find nearest. Return -1 (and a miss()) or surface and nearest point.
|
|
||||||
label findNearest
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const point&,
|
|
||||||
const scalar nearestDistSqr,
|
|
||||||
pointIndexHit&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
label findNearest
|
|
||||||
(
|
|
||||||
const point&,
|
|
||||||
const scalar nearestDistSqr,
|
|
||||||
pointIndexHit&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Find nearest point (like findNearest) but also return whether
|
|
||||||
// point is on edge or on point. Returns -1 if not found
|
|
||||||
// (within nearestDistSqr) on any of the surfaces.
|
|
||||||
// Returns surfaceLocation
|
|
||||||
// - hit : nearest point is inside triangle
|
|
||||||
// - elementType : none, edge or point
|
|
||||||
// - index : triI, edgeI or localPointI
|
|
||||||
label findNearestAndClassify
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const point& pt,
|
|
||||||
const scalar nearestDistSqr,
|
|
||||||
surfaceLocation& nearest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculate point which is on a set of surfaces. Takes
|
|
||||||
// - initialDistSqr : search dimensions to find point on surface
|
|
||||||
// - convergenceDistSqr : when point is converged
|
|
||||||
// Will bomb out if no stable point reached after certain number
|
|
||||||
// of iterations.
|
|
||||||
surfaceLocation facesIntersectionTrack
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initialDistSqr,
|
|
||||||
const scalar convergenceDistSqr,
|
|
||||||
const point& start
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculate point which is on a set of surfaces.
|
|
||||||
pointIndexHit facesIntersection
|
|
||||||
(
|
|
||||||
const labelList& surfacesToTest,
|
|
||||||
const scalar initialDistSqr,
|
|
||||||
const scalar convergenceDistSqr,
|
|
||||||
const point& start
|
|
||||||
) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
foamCleanTutorials cases
|
foamCleanTutorials cases
|
||||||
rm -rf processor*
|
rm -rf processor*
|
||||||
rm 0/pd.gz 0/alpha1.gz
|
rm -rf 0/pd.gz 0/alpha1.gz
|
||||||
|
|||||||
@ -4,16 +4,13 @@
|
|||||||
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
|
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
|
||||||
|
|
||||||
cd constrictedChannel
|
cd constrictedChannel
|
||||||
rm -rf 0 > /dev/null 2>&1
|
rm -rf 0
|
||||||
rm Ar-Ar Ar-Ne Ne-Ne > /dev/null 2>&1
|
rm -rf Ar-Ar Ar-Ne Ne-Ne
|
||||||
rm constant/idList
|
rm -rf constant/idList
|
||||||
|
|
||||||
cleanCase
|
cleanCase
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
cd nanoNozzle
|
cd nanoNozzle
|
||||||
rm -rf processor[0-9] > /dev/null 2>&1
|
rm -rf processor[0-9]
|
||||||
|
|
||||||
cleanCase
|
cleanCase
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,8 @@
|
|||||||
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
|
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
|
||||||
|
|
||||||
cd periodicCube
|
cd periodicCube
|
||||||
rm -rf 0 > /dev/null 2>&1
|
rm -rf 0
|
||||||
rm Ar-Ar > /dev/null 2>&1
|
rm -rf Ar-Ar
|
||||||
rm constant/idList
|
rm -rf constant/idList
|
||||||
|
|
||||||
cleanCase
|
cleanCase
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ do
|
|||||||
|
|
||||||
if [ "$case" = "biconic25-55Run35" ]
|
if [ "$case" = "biconic25-55Run35" ]
|
||||||
then
|
then
|
||||||
rm $case/constant/polyMesh/boundary
|
rm -rf $case/constant/polyMesh/boundary
|
||||||
wclean $case/datToFoam
|
wclean $case/datToFoam
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user