Merge branch 'master' of /home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
Sergio Ferraris
2013-06-07 10:11:37 +01:00
520 changed files with 102879 additions and 3007 deletions

View File

@ -1,3 +1,5 @@
#include "resetPhiPatches.H"
volScalarField rAU(1.0/UEqn().A()); volScalarField rAU(1.0/UEqn().A());
surfaceScalarField rAUf("Dp", fvc::interpolate(rAU)); surfaceScalarField rAUf("Dp", fvc::interpolate(rAU));

View File

@ -0,0 +1,8 @@
FieldField<fvsPatchField, scalar>& phibf = phi.boundaryField();
const FieldField<fvPatchField, vector>& Ubf = U.boundaryField();
const FieldField<fvsPatchField, vector>& Sfbf = mesh.Sf().boundaryField();
forAll(phibf, patchI)
{
phibf[patchI] = (Ubf[patchI] & Sfbf[patchI]);
}

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -117,6 +117,30 @@ int main(int argc, char *argv[])
<< " agglomerated size : " << " agglomerated size : "
<< returnReduce(coarseSize, sumOp<label>()) << endl; << returnReduce(coarseSize, sumOp<label>()) << endl;
labelList newAddr;
label newCoarseSize = 0;
bool ok = GAMGAgglomeration::checkRestriction
(
newAddr,
newCoarseSize,
agglom.meshLevel(level).lduAddr(),
addr,
coarseSize
);
if (!ok)
{
WarningIn(args.executable())
<< "At level " << level
<< " there are " << coarseSize
<< " agglomerated cells but " << newCoarseSize
<< " disconnected regions" << endl
<< " This means that some agglomerations (coarse cells)"
<< " consist of multiple disconnected regions."
<< endl;
}
forAll(addr, fineI) forAll(addr, fineI)
{ {
const labelList& cellLabels = coarseToCell[fineI]; const labelList& cellLabels = coarseToCell[fineI];

View File

@ -25,6 +25,7 @@ License
#include "scalarMatrices.H" #include "scalarMatrices.H"
#include "vector.H" #include "vector.H"
#include "IFstream.H"
using namespace Foam; using namespace Foam;

View File

@ -0,0 +1,3 @@
Test-vectorTools.C
EXE = $(FOAM_USER_APPBIN)/Test-vectorTools

View File

@ -0,0 +1 @@
EXE_INC = -I$(FOAM_APP)/utilities/mesh/generation/cvMesh/vectorTools

View File

@ -0,0 +1,71 @@
#include "vector.H"
#include "IOstreams.H"
#include "vectorTools.H"
#include "unitConversion.H"
using namespace Foam;
void test(const vector& a, const vector& b, const scalar tolerance)
{
Info<< "Vectors " << a << " and " << b
<< " are (to tolerance of " << tolerance << "): ";
if (vectorTools::areParallel(a, b, tolerance))
Info<< " parallel ";
if (vectorTools::areOrthogonal(a, b, tolerance))
Info<< " orthogonal ";
if (vectorTools::areAcute(a, b))
Info<< " acute ";
if (vectorTools::areObtuse(a, b))
Info<< " obtuse ";
Info<< ", angle = " << vectorTools::degAngleBetween(a, b);
Info<< endl;
}
int main()
{
vector a(1.0, 1.0, 1.0);
vector b(2.0, 2.0, 2.0);
test(a, b, 0.0);
test(a, b, VSMALL);
test(a, b, SMALL);
test(a, b, 1e-3);
test(a, b, 1e-1);
a = vector(1,0,0);
b = vector(0,2,0);
test(a, b, 0.0);
test(a, b, VSMALL);
test(a, b, SMALL);
test(a, b, 1e-3);
test(a, b, 1e-1);
a = vector(1,0,0);
b = vector(-1,0,0);
test(a, b, 0.0);
test(a, b, VSMALL);
test(a, b, SMALL);
test(a, b, 1e-3);
test(a, b, 1e-1);
a = vector(1,0,0);
b = vector(-1,2,0);
test(a, b, 0.0);
test(a, b, VSMALL);
test(a, b, SMALL);
test(a, b, 1e-3);
test(a, b, 1e-1);
return 0;
}

View File

@ -2,16 +2,24 @@
| ========= | | | ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev | | \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org | | \\ / A nd | Web: http://www.openfoam.org |
| \\/ M anipulation | | | \\/ M anipulation | |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
FoamFile FoamFile
{ {
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary;
object collapseDict; root "";
case "";
instance "";
local "";
class dictionary;
object collapseDict;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// If on, after collapsing check the quality of the mesh. If bad faces are // If on, after collapsing check the quality of the mesh. If bad faces are
@ -72,7 +80,7 @@ controlMeshQualityCoeffs
// The amount that initialFaceLengthFactor will be reduced by for each // The amount that initialFaceLengthFactor will be reduced by for each
// face if its collapse generates a poor quality face // face if its collapse generates a poor quality face
faceReductionFactor $initialFaceLengthFactor; faceReductionFactor 0.5;
// Maximum number of smoothing iterations for the reductionFactors // Maximum number of smoothing iterations for the reductionFactors
maximumSmoothingIterations 2; maximumSmoothingIterations 2;

View File

@ -72,10 +72,11 @@ int main(int argc, char *argv[])
"Collapse small and sliver faces as well as small edges" "Collapse small and sliver faces as well as small edges"
); );
argList::addBoolOption argList::addOption
( (
"collapseIndirectPatchFaces", "collapseFaceZone",
"Collapse faces that are in the face zone indirectPatchFaces" "zoneName",
"Collapse faces that are in the supplied face zone"
); );
# include "addOverwriteOption.H" # include "addOverwriteOption.H"
@ -92,8 +93,7 @@ int main(int argc, char *argv[])
const bool overwrite = args.optionFound("overwrite"); const bool overwrite = args.optionFound("overwrite");
const bool collapseFaces = args.optionFound("collapseFaces"); const bool collapseFaces = args.optionFound("collapseFaces");
const bool collapseIndirectPatchFaces = const bool collapseFaceZone = args.optionFound("collapseFaceZone");
args.optionFound("collapseIndirectPatchFaces");
forAll(timeDirs, timeI) forAll(timeDirs, timeI)
{ {
@ -115,11 +115,15 @@ int main(int argc, char *argv[])
meshMod.changeMesh(mesh, false); meshMod.changeMesh(mesh, false);
} }
if (collapseIndirectPatchFaces) if (collapseFaceZone)
{ {
const word faceZoneName = args.optionRead<word>("collapseFaceZone");
const faceZone& fZone = mesh.faceZones()[faceZoneName];
// Filter faces. Pass in the number of bad faces that are present // Filter faces. Pass in the number of bad faces that are present
// from the previous edge filtering to use as a stopping criterion. // from the previous edge filtering to use as a stopping criterion.
meshFilter.filterIndirectPatchFaces(); meshFilter.filterFaceZone(fZone);
{ {
polyTopoChange meshMod(newMesh); polyTopoChange meshMod(newMesh);

View File

@ -9,5 +9,10 @@ extrude2DMesh/Allwmake
wmake snappyHexMesh wmake snappyHexMesh
if [ -d "$CGAL_ARCH_PATH" ]
then
foamyHexMesh/Allwmake
foamyQuadMesh/Allwmake
fi
# ----------------------------------------------------------------- end-of-file # ----------------------------------------------------------------- end-of-file

View File

@ -90,6 +90,7 @@ Foam::extrude2DMesh::extrude2DMesh
dict_(dict), dict_(dict),
//patchDict_(dict.subDict("patchInfo")), //patchDict_(dict.subDict("patchInfo")),
model_(model), model_(model),
modelType_(dict.lookup("extrudeModel")),
patchType_(dict.lookup("patchType")), patchType_(dict.lookup("patchType")),
frontPatchI_(-1), frontPatchI_(-1),
backPatchI_(-1) backPatchI_(-1)

View File

@ -53,9 +53,10 @@ class polyMesh;
class polyTopoChange; class polyTopoChange;
class mapPolyMesh; class mapPolyMesh;
class mapDistributePolyMesh; class mapDistributePolyMesh;
class polyBoundaryMesh;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class extrude2DMesh Declaration Class extrude2DMesh Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class extrude2DMesh class extrude2DMesh
@ -65,24 +66,19 @@ class extrude2DMesh
//- Reference to 2D mesh //- Reference to 2D mesh
polyMesh& mesh_; polyMesh& mesh_;
//- Extrusion dictionary
const dictionary dict_; const dictionary dict_;
//const dictionary patchDict_; //const dictionary patchDict_;
//- The extrusion model
const extrudeModel& model_; const extrudeModel& model_;
//- Type of the patches that will be created by the extrusion. const word modelType_;
const word patchType_; const word patchType_;
//- Patch ID of the front patch
label frontPatchI_; label frontPatchI_;
//- Patch ID of the back patch
label backPatchI_; label backPatchI_;
// Private Member Functions // Private Member Functions
//- Check the mesh is 2D //- Check the mesh is 2D
@ -97,7 +93,6 @@ class extrude2DMesh
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const extrude2DMesh&); void operator=(const extrude2DMesh&);
public: public:
//- Runtime type information //- Runtime type information
@ -105,8 +100,6 @@ public:
// Constructors // Constructors
//- Construct from a 2D polyMesh, a dictionary and an extrusion model
extrude2DMesh extrude2DMesh
( (
polyMesh&, polyMesh&,
@ -121,36 +114,30 @@ public:
// Member Functions // Member Functions
// Access //- Add front and back patches
void addFrontBackPatches();
//- Return the patch ID of the front patch //- Play commands into polyTopoChange to extrude mesh.
inline label frontPatchI() const void setRefinement(polyTopoChange&);
{
return frontPatchI_;
}
//- Return the patch ID of the back patch //- Force recalculation of locally stored data on topological change
inline label backPatchI() const void updateMesh(const mapPolyMesh&)
{ {}
return backPatchI_;
}
//- Force recalculation of locally stored data for mesh distribution
void distribute(const mapDistributePolyMesh&)
{}
// Edit label frontPatchI() const
{
return frontPatchI_;
}
//- Add front and back patches label backPatchI() const
void addFrontBackPatches(); {
return backPatchI_;
}
//- Play commands into polyTopoChange to extrude mesh.
void setRefinement(polyTopoChange&);
//- Force recalculation of locally stored data on topological change
void updateMesh(const mapPolyMesh&)
{}
//- Force recalculation of locally stored data for mesh distribution
void distribute(const mapDistributePolyMesh&)
{}
}; };

View File

@ -5,48 +5,42 @@
| \\ / A nd | Web: www.OpenFOAM.org | | \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | | | \\/ M anipulation | |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
FoamFile FoamFile
{ {
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary;
object extrude2DMeshDict; root "";
case "";
instance "";
local "";
class dictionary;
object extrude2DMeshDict;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Type of extrusion
extrudeModel linearDirection; extrudeModel linearDirection;
//extrudeModel wedge; //extrudeModel wedge;
// Patch type the extruded patches will take
patchType empty; patchType empty;
//patchType wedge; //patchType wedge;
// Number of layers to extrude
nLayers 1; nLayers 1;
// Expansion ratio. If >1 then grows the layers
expansionRatio 1.0; expansionRatio 1.0;
linearDirectionCoeffs linearDirectionCoeffs
{ {
// Direction of extrusion
direction (0 0 1); direction (0 0 1);
// Width of newly extruded cells
thickness 0.1; thickness 0.1;
} }
wedgeCoeffs wedgeCoeffs
{ {
// Point the extrusion axis goes through axisPt (0 0 0);
axisPt (0 0 0); axis (1 0 0);
angle 10;
// Axis to extrude around
axis (1 0 0);
// Total angle of the wedge in degrees
angle 10;
} }
// ************************************************************************* //

View File

@ -0,0 +1,10 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wclean libso conformalVoronoiMesh
wclean
wclean cvMeshSurfaceSimplify
wclean cvMeshBackgroundMesh
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,11 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wmake libso conformalVoronoiMesh
wmake
#wmake cvMeshBackgroundMesh
#(cd cvMeshSurfaceSimplify && ./Allwmake)
#wmake cellSizeAndAlignmentGrid
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,3 @@
foamyHexMesh.C
EXE = $(FOAM_APPBIN)/foamyHexMesh

View File

@ -0,0 +1,38 @@
EXE_DEBUG = -DFULLDEBUG -g -O0
EXE_FROUNDING_MATH = -frounding-math
EXE_NDEBUG = -DNDEBUG
CGAL_EXACT = /*-DCGAL_DONT_USE_LAZY_KERNEL*/
CGAL_INEXACT = -DCGAL_INEXACT
include $(GENERAL_RULES)/CGAL
EXE_INC = \
${EXE_FROUNDING_MATH} \
${EXE_NDEBUG} \
${CGAL_INEXACT} \
${CGAL_INC} \
-IconformalVoronoiMesh/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-IvectorTools
EXE_LIBS = \
$(CGAL_LIBS) \
-lboost_thread \
-lmpfr \
-lconformalVoronoiMesh \
-lmeshTools \
-ldecompositionMethods \
-L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \
-ledgeMesh \
-lfileFormats \
-ltriSurface \
-ldynamicMesh \
-lsampling

View File

@ -0,0 +1,2 @@
cellSizeAndAlignmentGrid.C
EXE = $(FOAM_USER_APPBIN)/cellSizeAndAlignmentGrid

View File

@ -0,0 +1,40 @@
EXE_DEBUG = -DFULLDEBUG -g -O0
EXE_FROUNDING_MATH = -frounding-math
EXE_NDEBUG = -DNDEBUG
CGAL_EXACT = /*-DCGAL_DONT_USE_LAZY_KERNEL*/
CGAL_INEXACT = -DCGAL_INEXACT
include $(GENERAL_RULES)/CGAL
EXE_INC = \
${EXE_FROUNDING_MATH} \
${EXE_NDEBUG} \
${CGAL_INEXACT} \
${CGAL_INC} \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(FOAM_UTILITIES)/mesh/generation/cvMesh/conformalVoronoiMesh/lnInclude \
-I$(FOAM_UTILITIES)/mesh/generation/cvMesh/vectorTools
EXE_LIBS = \
$(CGAL_LIBS) \
-lmpfr \
-lboost_thread \
-lconformalVoronoiMesh \
-lfiniteVolume \
-lmeshTools \
-ldecompositionMethods \
-L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \
-ledgeMesh \
-ltriSurface \
-ldynamicMesh \
-lsampling \
-lfileFormats

View File

@ -0,0 +1,716 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-distributedDelaunayMesh
Description
\*---------------------------------------------------------------------------*/
#include "CGALTriangulation3DKernel.H"
#include "indexedVertex.H"
#include "indexedCell.H"
#include "argList.H"
#include "Time.H"
#include "DistributedDelaunayMesh.H"
#include "backgroundMeshDecomposition.H"
#include "searchableSurfaces.H"
#include "conformationSurfaces.H"
#include "PrintTable.H"
#include "Random.H"
#include "boundBox.H"
#include "point.H"
#include "cellShapeControlMesh.H"
#include "triadField.H"
#include "scalarIOField.H"
#include "pointIOField.H"
#include "triadIOField.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
template<class Triangulation, class Type>
Foam::tmp<Foam::Field<Type> > filterFarPoints
(
const Triangulation& mesh,
const Field<Type>& field
)
{
tmp<Field<Type> > tNewField(new Field<Type>(field.size()));
Field<Type>& newField = tNewField();
label added = 0;
label count = 0;
for
(
typename Triangulation::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (vit->real())
{
newField[added++] = field[count];
}
count++;
}
newField.resize(added);
return tNewField;
}
template<class T>
autoPtr<mapDistribute> buildMap
(
const T& mesh,
labelListList& pointPoints
)
{
pointPoints.setSize(mesh.vertexCount());
globalIndex globalIndexing(mesh.vertexCount());
for
(
typename T::Finite_vertices_iterator vit = mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (!vit->real())
{
continue;
}
std::list<typename T::Vertex_handle> adjVerts;
mesh.finite_adjacent_vertices(vit, std::back_inserter(adjVerts));
DynamicList<label> indices(adjVerts.size());
for
(
typename std::list<typename T::Vertex_handle>::const_iterator
adjVertI = adjVerts.begin();
adjVertI != adjVerts.end();
++adjVertI
)
{
typename T::Vertex_handle vh = *adjVertI;
if (!vh->farPoint())
{
indices.append
(
globalIndexing.toGlobal(vh->procIndex(), vh->index())
);
}
}
pointPoints[vit->index()].transfer(indices);
}
List<Map<label> > compactMap;
return autoPtr<mapDistribute>
(
new mapDistribute
(
globalIndexing,
pointPoints,
compactMap
)
);
}
template<class T>
Foam::tmp<Foam::triadField> buildAlignmentField(const T& mesh)
{
tmp<triadField> tAlignments
(
new triadField(mesh.vertexCount(), triad::unset)
);
triadField& alignments = tAlignments();
for
(
typename T::Finite_vertices_iterator vit = mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (!vit->real())
{
continue;
}
alignments[vit->index()] = vit->alignment();
}
return tAlignments;
}
template<class T>
Foam::tmp<Foam::pointField> buildPointField(const T& mesh)
{
tmp<pointField> tPoints
(
new pointField(mesh.vertexCount(), point(GREAT, GREAT, GREAT))
);
pointField& points = tPoints();
for
(
typename T::Finite_vertices_iterator vit = mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (!vit->real())
{
continue;
}
points[vit->index()] = topoint(vit->point());
}
return tPoints;
}
void refine
(
cellShapeControlMesh& mesh,
const conformationSurfaces& geometryToConformTo,
const label maxRefinementIterations,
const scalar defaultCellSize
)
{
for (label iter = 0; iter < maxRefinementIterations; ++iter)
{
DynamicList<point> ptsToInsert;
for
(
CellSizeDelaunay::Finite_cells_iterator cit =
mesh.finite_cells_begin();
cit != mesh.finite_cells_end();
++cit
)
{
const point newPoint =
topoint
(
CGAL::centroid
(
cit->vertex(0)->point(),
cit->vertex(1)->point(),
cit->vertex(2)->point(),
cit->vertex(3)->point()
)
);
if (geometryToConformTo.inside(newPoint))
{
ptsToInsert.append(newPoint);
}
}
Info<< " Adding " << returnReduce(ptsToInsert.size(), sumOp<label>())
<< endl;
forAll(ptsToInsert, ptI)
{
mesh.insert
(
ptsToInsert[ptI],
defaultCellSize,
triad::unset,
Vb::vtInternal
);
}
}
}
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
label maxRefinementIterations = 2;
label maxSmoothingIterations = 200;
scalar minResidual = 0;
scalar defaultCellSize = 0.001;
scalar nearFeatDistSqrCoeff = 1e-8;
// Need to decouple vertex and cell type from this class?
// Vertex must have:
// + index
// + procIndex
// - type should be optional
cellShapeControlMesh mesh(runTime);
IOdictionary cvMeshDict
(
IOobject
(
"cvMeshDict",
runTime.system(),
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
Random rndGen(64293*Pstream::myProcNo());
searchableSurfaces allGeometry
(
IOobject
(
"cvSearchableSurfaces",
runTime.constant(),
"triSurface",
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE
),
cvMeshDict.subDict("geometry")
);
conformationSurfaces geometryToConformTo
(
runTime,
rndGen,
allGeometry,
cvMeshDict.subDict("surfaceConformation")
);
autoPtr<backgroundMeshDecomposition> bMesh;
if (Pstream::parRun())
{
bMesh.set
(
new backgroundMeshDecomposition
(
runTime,
rndGen,
geometryToConformTo,
cvMeshDict.subDict("backgroundMeshDecomposition")
)
);
}
// Nice to have IO for the delaunay mesh
// IO depend on vertex type.
//
// Define a delaunay mesh as:
// + list of points of the triangulation
// + optionally a list of cells
Info<< nl << "Loop over surfaces" << endl;
forAll(geometryToConformTo.surfaces(), sI)
{
const label surfI = geometryToConformTo.surfaces()[sI];
const searchableSurface& surface =
geometryToConformTo.geometry()[surfI];
Info<< nl << "Inserting points from surface " << surface.name()
<< " (" << surface.type() << ")" << endl;
const tmp<pointField> tpoints(surface.points());
const pointField& points = tpoints();
Info<< " Number of points = " << points.size() << endl;
forAll(points, pI)
{
// Is the point in the extendedFeatureEdgeMesh? If so get the
// point normal, otherwise get the surface normal from
// searchableSurface
pointIndexHit info;
label infoFeature;
geometryToConformTo.findFeaturePointNearest
(
points[pI],
nearFeatDistSqrCoeff,
info,
infoFeature
);
autoPtr<triad> pointAlignment;
if (info.hit())
{
const extendedFeatureEdgeMesh& features =
geometryToConformTo.features()[infoFeature];
vectorField norms = features.featurePointNormals(info.index());
// Create a triad from these norms.
pointAlignment.set(new triad());
forAll(norms, nI)
{
pointAlignment() += norms[nI];
}
pointAlignment().normalize();
pointAlignment().orthogonalize();
}
else
{
geometryToConformTo.findEdgeNearest
(
points[pI],
nearFeatDistSqrCoeff,
info,
infoFeature
);
if (info.hit())
{
const extendedFeatureEdgeMesh& features =
geometryToConformTo.features()[infoFeature];
vectorField norms = features.edgeNormals(info.index());
// Create a triad from these norms.
pointAlignment.set(new triad());
forAll(norms, nI)
{
pointAlignment() += norms[nI];
}
pointAlignment().normalize();
pointAlignment().orthogonalize();
}
else
{
pointField ptField(1, points[pI]);
scalarField distField(1, nearFeatDistSqrCoeff);
List<pointIndexHit> infoList(1, pointIndexHit());
surface.findNearest(ptField, distField, infoList);
vectorField normals(1);
surface.getNormal(infoList, normals);
pointAlignment.set(new triad(normals[0]));
}
}
if (Pstream::parRun())
{
if (bMesh().positionOnThisProcessor(points[pI]))
{
CellSizeDelaunay::Vertex_handle vh = mesh.insert
(
points[pI],
defaultCellSize,
pointAlignment(),
Vb::vtInternalNearBoundary
);
}
}
else
{
CellSizeDelaunay::Vertex_handle vh = mesh.insert
(
points[pI],
defaultCellSize,
pointAlignment(),
Vb::vtInternalNearBoundary
);
}
}
}
// Refine the mesh
refine
(
mesh,
geometryToConformTo,
maxRefinementIterations,
defaultCellSize
);
if (Pstream::parRun())
{
mesh.distribute(bMesh);
}
labelListList pointPoints;
autoPtr<mapDistribute> meshDistributor = buildMap(mesh, pointPoints);
triadField alignments(buildAlignmentField(mesh));
pointField points(buildPointField(mesh));
mesh.printInfo(Info);
// Setup the sizes and alignments on each point
triadField fixedAlignments(mesh.vertexCount(), triad::unset);
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (vit->nearBoundary())
{
fixedAlignments[vit->index()] = vit->alignment();
}
}
Info<< nl << "Smoothing alignments" << endl;
for (label iter = 0; iter < maxSmoothingIterations; iter++)
{
Info<< "Iteration " << iter;
meshDistributor().distribute(points);
meshDistributor().distribute(alignments);
scalar residual = 0;
triadField triadAv(alignments.size(), triad::unset);
forAll(pointPoints, pI)
{
const labelList& pPoints = pointPoints[pI];
if (pPoints.empty())
{
continue;
}
const triad& oldTriad = alignments[pI];
triad& newTriad = triadAv[pI];
// Enforce the boundary conditions
const triad& fixedAlignment = fixedAlignments[pI];
forAll(pPoints, adjPointI)
{
const label adjPointIndex = pPoints[adjPointI];
scalar dist = mag(points[pI] - points[adjPointIndex]);
// dist = max(dist, SMALL);
triad tmpTriad = alignments[adjPointIndex];
for (direction dir = 0; dir < 3; dir++)
{
if (tmpTriad.set(dir))
{
tmpTriad[dir] *= (1.0/dist);
}
}
newTriad += tmpTriad;
}
newTriad.normalize();
newTriad.orthogonalize();
// newTriad = newTriad.sortxyz();
label nFixed = 0;
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
nFixed++;
}
}
if (nFixed == 1)
{
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
newTriad.align(fixedAlignment[dirI]);
}
}
}
else if (nFixed == 2)
{
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
newTriad[dirI] = fixedAlignment[dirI];
}
else
{
newTriad[dirI] = triad::unset[dirI];
}
}
newTriad.orthogonalize();
}
else if (nFixed == 3)
{
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
newTriad[dirI] = fixedAlignment[dirI];
}
}
}
for (direction dir = 0; dir < 3; ++dir)
{
if
(
newTriad.set(dir)
&& oldTriad.set(dir)
//&& !fixedAlignment.set(dir)
)
{
scalar dotProd = (oldTriad[dir] & newTriad[dir]);
scalar diff = mag(dotProd) - 1.0;
residual += mag(diff);
}
}
}
forAll(alignments, pI)
{
alignments[pI] = triadAv[pI].sortxyz();
}
reduce(residual, sumOp<scalar>());
Info<< ", Residual = " << residual << endl;
if (residual <= minResidual)
{
break;
}
}
// Write alignments to a .obj file
OFstream str(runTime.path()/"alignments.obj");
forAll(alignments, pI)
{
const triad& tri = alignments[pI];
if (tri.set())
{
forAll(tri, dirI)
{
meshTools::writeOBJ(str, points[pI], tri[dirI] + points[pI]);
}
}
}
// Remove the far points
pointIOField pointsIO
(
IOobject
(
"points",
runTime.constant(),
runTime,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
filterFarPoints(mesh, points)
);
scalarField sizes(points.size(), defaultCellSize);
scalarIOField sizesIO
(
IOobject
(
"sizes",
runTime.constant(),
runTime,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
filterFarPoints(mesh, sizes)
);
triadIOField alignmentsIO
(
IOobject
(
"alignments",
runTime.constant(),
runTime,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
filterFarPoints(mesh, alignments)
);
pointsIO.write();
sizesIO.write();
alignmentsIO.write();
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,263 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "DelaunayMesh.H"
#include "labelPair.H"
#include "PrintTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Triangulation>
Foam::DelaunayMesh<Triangulation>::DelaunayMesh()
:
Triangulation(),
vertexCount_(0),
cellCount_(0)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Triangulation>
Foam::DelaunayMesh<Triangulation>::~DelaunayMesh()
{}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::reset()
{
Info<< "Clearing triangulation" << endl;
DynamicList<Vb> vertices;
for
(
Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
vit != Triangulation::finite_vertices_end();
++vit
)
{
if (vit->fixed())
{
vertices.append
(
Vb
(
vit->point(),
vit->index(),
vit->type(),
vit->procIndex()
)
);
vertices.last().fixed() = vit->fixed();
}
}
this->clear();
resetVertexCount();
resetCellCount();
insertPoints(vertices);
Info<< "Inserted " << vertexCount() << " fixed points" << endl;
}
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::insertPoints(const List<Vb>& vertices)
{
rangeInsertWithInfo
(
vertices.begin(),
vertices.end(),
true
);
}
template<class Triangulation>
bool Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::Less_x_3::
operator()
(
const Point_3& p,
const Point_3& q
) const
{
return typename Gt::Less_x_3()(*(p.first), *(q.first));
}
template<class Triangulation>
bool Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::Less_y_3::
operator()
(
const Point_3& p,
const Point_3& q
) const
{
return typename Gt::Less_y_3()(*(p.first), *(q.first));
}
template<class Triangulation>
bool Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::Less_z_3::
operator()
(
const Point_3& p,
const Point_3& q
) const
{
return typename Gt::Less_z_3()(*(p.first), *(q.first));
}
template<class Triangulation>
typename Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::Less_x_3
Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::less_x_3_object()
const
{
return Less_x_3();
}
template<class Triangulation>
typename Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::Less_y_3
Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::less_y_3_object()
const
{
return Less_y_3();
}
template<class Triangulation>
typename Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::Less_z_3
Foam::DelaunayMesh<Triangulation>::Traits_for_spatial_sort::less_z_3_object()
const
{
return Less_z_3();
}
template<class Triangulation>
template<class PointIterator>
void Foam::DelaunayMesh<Triangulation>::rangeInsertWithInfo
(
PointIterator begin,
PointIterator end,
bool printErrors
)
{
typedef DynamicList
<
std::pair
<
const typename Triangulation::Point*,
label
>
> vectorPairPointIndex;
vectorPairPointIndex points;
label count = 0;
for (PointIterator it = begin; it != end; ++it)
{
points.append
(
std::make_pair(&(it->point()), count++)
);
}
std::random_shuffle(points.begin(), points.end());
spatial_sort
(
points.begin(),
points.end(),
Traits_for_spatial_sort()
);
Vertex_handle hint;
for
(
typename vectorPairPointIndex::const_iterator p = points.begin();
p != points.end();
++p
)
{
const size_t checkInsertion = Triangulation::number_of_vertices();
hint = this->insert(*(p->first), hint);
const Vb& vert = *(begin + p->second);
if (checkInsertion != Triangulation::number_of_vertices() - 1)
{
if (printErrors)
{
Vertex_handle nearV =
Triangulation::nearest_vertex(*(p->first));
Pout<< "Failed insertion : " << vert.info()
<< " nearest : " << nearV->info();
}
}
else
{
hint->index() = getNewVertexIndex();
hint->type() = vert.type();
hint->procIndex() = vert.procIndex();
hint->targetCellSize() = vert.targetCellSize();
hint->alignment() = vert.alignment();
}
}
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "DelaunayMeshIO.C"
// ************************************************************************* //

View File

@ -0,0 +1,240 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::DelaunayMesh
Description
The vertex and cell classes must have an index defined
SourceFiles
DelaunayMeshI.H
DelaunayMesh.C
DelaunayMeshIO.C
\*---------------------------------------------------------------------------*/
#ifndef DelaunayMesh_H
#define DelaunayMesh_H
#include "Pair.H"
#include "HashSet.H"
#include "FixedList.H"
#include "boundBox.H"
#include "indexedVertex.H"
#include "CGALTriangulation3Ddefs.H"
#include "autoPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
/*---------------------------------------------------------------------------*\
Class DelaunayMesh Declaration
\*---------------------------------------------------------------------------*/
template<class Triangulation>
class DelaunayMesh
:
public Triangulation
{
public:
typedef typename Triangulation::Cell_handle Cell_handle;
typedef typename Triangulation::Vertex_handle Vertex_handle;
typedef typename Triangulation::Edge Edge;
typedef typename Triangulation::Point Point;
typedef typename Triangulation::Facet Facet;
typedef typename Triangulation::Finite_vertices_iterator
Finite_vertices_iterator;
typedef typename Triangulation::Finite_cells_iterator
Finite_cells_iterator;
typedef typename Triangulation::Finite_facets_iterator
Finite_facets_iterator;
typedef HashSet
<
Pair<label>,
FixedList<label, 2>::Hash<>
> labelPairHashSet;
private:
// Private data
//- Keep track of the number of vertices that have been added.
// This allows a unique index to be assigned to each vertex.
mutable label vertexCount_;
//- Keep track of the number of cells that have been added.
// This allows a unique index to be assigned to each cell.
mutable label cellCount_;
//- Spatial sort traits to use with a pair of point pointers and an int.
// Taken from a post on the CGAL lists: 2010-01/msg00004.html by
// Sebastien Loriot (Geometry Factory).
struct Traits_for_spatial_sort
:
public Triangulation::Geom_traits
{
typedef typename Triangulation::Geom_traits Gt;
typedef std::pair<const typename Triangulation::Point*, int>
Point_3;
struct Less_x_3
{
bool operator()(const Point_3& p, const Point_3& q) const;
};
struct Less_y_3
{
bool operator()(const Point_3& p, const Point_3& q) const;
};
struct Less_z_3
{
bool operator()(const Point_3& p, const Point_3& q) const;
};
Less_x_3 less_x_3_object() const;
Less_y_3 less_y_3_object() const;
Less_z_3 less_z_3_object() const;
};
// Private Member Functions
void sortFaces
(
faceList& faces,
labelList& owner,
labelList& neighbour
) const;
void addPatches
(
const label nInternalFaces,
faceList& faces,
labelList& owner,
PtrList<dictionary>& patchDicts,
const List<DynamicList<face> >& patchFaces,
const List<DynamicList<label> >& patchOwners
) const;
//- Disallow default bitwise copy construct
DelaunayMesh(const DelaunayMesh<Triangulation>&);
//- Disallow default bitwise assignment
void operator=(const DelaunayMesh<Triangulation>&);
public:
// Constructors
//- Construct from components
DelaunayMesh();
//- Destructor
~DelaunayMesh();
// Member Functions
inline label getNewVertexIndex() const;
inline label getNewCellIndex() const;
inline label cellCount() const;
inline void resetCellCount();
inline label vertexCount() const;
inline void resetVertexCount();
//- Remove the entire triangulation
void reset();
void insertPoints(const List<Vb>& vertices);
//- Function inserting points into a triangulation and setting the
// index and type data of the point in the correct order. This is
// faster than inserting points individually.
//
// Adapted from a post on the CGAL lists: 2010-01/msg00004.html by
// Sebastien Loriot (Geometry Factory).
template<class PointIterator>
void rangeInsertWithInfo
(
PointIterator begin,
PointIterator end,
bool printErrors = true
);
// Queries
void printInfo(Ostream& os) const;
void printVertexInfo(Ostream& os) const;
//- Create an fvMesh from the triangulation.
// The mesh is not parallel consistent - only used for viewing
autoPtr<fvMesh> createMesh
(
const fileName& name,
const Time& runTime,
labelList& vertexMap,
labelList& cellMap
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "DelaunayMeshI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "DelaunayMesh.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Triangulation>
inline Foam::label Foam::DelaunayMesh<Triangulation>::getNewVertexIndex() const
{
label id = vertexCount_++;
if (id == labelMax)
{
WarningIn
(
"Foam::DelaunayMesh<Triangulation>::getNewVertexIndex() const"
) << "Vertex counter has overflowed." << endl;
}
return id;
}
template<class Triangulation>
inline Foam::label Foam::DelaunayMesh<Triangulation>::getNewCellIndex() const
{
label id = cellCount_++;
if (id == labelMax)
{
WarningIn
(
"Foam::DelaunayMesh<Triangulation>::getNewCellIndex() const"
) << "Cell counter has overflowed." << endl;
}
return id;
}
template<class Triangulation>
Foam::label Foam::DelaunayMesh<Triangulation>::cellCount() const
{
return cellCount_;
}
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::resetCellCount()
{
cellCount_ = 0;
}
template<class Triangulation>
Foam::label Foam::DelaunayMesh<Triangulation>::vertexCount() const
{
return vertexCount_;
}
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::resetVertexCount()
{
vertexCount_ = 0;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,576 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "DelaunayMesh.H"
#include "fvMesh.H"
#include "pointConversion.H"
#include "wallPolyPatch.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::sortFaces
(
faceList& faces,
labelList& owner,
labelList& neighbour
) const
{
// Upper triangular order:
// + owner is sorted in ascending cell order
// + within each block of equal value for owner, neighbour is sorted in
// ascending cell order.
// + faces sorted to correspond
// e.g.
// owner | neighbour
// 0 | 2
// 0 | 23
// 0 | 71
// 1 | 23
// 1 | 24
// 1 | 91
List<labelPair> ownerNeighbourPair(owner.size());
forAll(ownerNeighbourPair, oNI)
{
ownerNeighbourPair[oNI] = labelPair(owner[oNI], neighbour[oNI]);
}
Info<< nl
<< "Sorting faces, owner and neighbour into upper triangular order"
<< endl;
labelList oldToNew;
sortedOrder(ownerNeighbourPair, oldToNew);
oldToNew = invert(oldToNew.size(), oldToNew);
inplaceReorder(oldToNew, faces);
inplaceReorder(oldToNew, owner);
inplaceReorder(oldToNew, neighbour);
}
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::addPatches
(
const label nInternalFaces,
faceList& faces,
labelList& owner,
PtrList<dictionary>& patchDicts,
const List<DynamicList<face> >& patchFaces,
const List<DynamicList<label> >& patchOwners
) const
{
label nPatches = patchFaces.size();
patchDicts.setSize(nPatches);
forAll(patchDicts, patchI)
{
patchDicts.set(patchI, new dictionary());
}
label nBoundaryFaces = 0;
forAll(patchFaces, p)
{
patchDicts[p].set("nFaces", patchFaces[p].size());
patchDicts[p].set("startFace", nInternalFaces + nBoundaryFaces);
nBoundaryFaces += patchFaces[p].size();
}
faces.setSize(nInternalFaces + nBoundaryFaces);
owner.setSize(nInternalFaces + nBoundaryFaces);
label faceI = nInternalFaces;
forAll(patchFaces, p)
{
forAll(patchFaces[p], f)
{
faces[faceI] = patchFaces[p][f];
owner[faceI] = patchOwners[p][f];
faceI++;
}
}
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::printInfo(Ostream& os) const
{
PrintTable<word, label> triInfoTable("Mesh Statistics");
triInfoTable.add("Points", Triangulation::number_of_vertices());
triInfoTable.add("Edges", Triangulation::number_of_finite_edges());
triInfoTable.add("Faces", Triangulation::number_of_finite_facets());
triInfoTable.add("Cells", Triangulation::number_of_finite_cells());
scalar minSize = GREAT;
scalar maxSize = 0;
for
(
Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
vit != Triangulation::finite_vertices_end();
++vit
)
{
if (!vit->farPoint())
{
minSize = min(vit->targetCellSize(), minSize);
maxSize = max(vit->targetCellSize(), maxSize);
}
}
Info<< incrIndent;
triInfoTable.print(Info, true, true);
Info<< "Size (Min/Max) = "
<< returnReduce(minSize, minOp<scalar>()) << " "
<< returnReduce(maxSize, maxOp<scalar>()) << endl;
Info<< decrIndent;
}
template<class Triangulation>
void Foam::DelaunayMesh<Triangulation>::printVertexInfo(Ostream& os) const
{
label nInternal = 0;
label nInternalRef = 0;
label nUnassigned = 0;
label nUnassignedRef = 0;
label nInternalNearBoundary = 0;
label nInternalNearBoundaryRef = 0;
label nInternalSurface = 0;
label nInternalSurfaceRef = 0;
label nInternalFeatureEdge = 0;
label nInternalFeatureEdgeRef = 0;
label nInternalFeaturePoint = 0;
label nInternalFeaturePointRef = 0;
label nExternalSurface = 0;
label nExternalSurfaceRef = 0;
label nExternalFeatureEdge = 0;
label nExternalFeatureEdgeRef = 0;
label nExternalFeaturePoint = 0;
label nExternalFeaturePointRef = 0;
label nFar = 0;
label nReferred = 0;
for
(
Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
vit != Triangulation::finite_vertices_end();
++vit
)
{
if (vit->type() == Vb::vtInternal)
{
if (vit->referred())
{
nReferred++;
nInternalRef++;
}
nInternal++;
}
else if (vit->type() == Vb::vtUnassigned)
{
if (vit->referred())
{
nReferred++;
nUnassignedRef++;
}
nUnassigned++;
}
else if (vit->type() == Vb::vtInternalNearBoundary)
{
if (vit->referred())
{
nReferred++;
nInternalNearBoundaryRef++;
}
nInternalNearBoundary++;
}
else if (vit->type() == Vb::vtInternalSurface)
{
if (vit->referred())
{
nReferred++;
nInternalSurfaceRef++;
}
nInternalSurface++;
}
else if (vit->type() == Vb::vtInternalFeatureEdge)
{
if (vit->referred())
{
nReferred++;
nInternalFeatureEdgeRef++;
}
nInternalFeatureEdge++;
}
else if (vit->type() == Vb::vtInternalFeaturePoint)
{
if (vit->referred())
{
nReferred++;
nInternalFeaturePointRef++;
}
nInternalFeaturePoint++;
}
else if (vit->type() == Vb::vtExternalSurface)
{
if (vit->referred())
{
nReferred++;
nExternalSurfaceRef++;
}
nExternalSurface++;
}
else if (vit->type() == Vb::vtExternalFeatureEdge)
{
if (vit->referred())
{
nReferred++;
nExternalFeatureEdgeRef++;
}
nExternalFeatureEdge++;
}
else if (vit->type() == Vb::vtExternalFeaturePoint)
{
if (vit->referred())
{
nReferred++;
nExternalFeaturePointRef++;
}
nExternalFeaturePoint++;
}
else if (vit->type() == Vb::vtFar)
{
nFar++;
}
}
label nTotalVertices =
nUnassigned
+ nInternal
+ nInternalNearBoundary
+ nInternalSurface
+ nInternalFeatureEdge
+ nInternalFeaturePoint
+ nExternalSurface
+ nExternalFeatureEdge
+ nExternalFeaturePoint
+ nFar;
if (nTotalVertices != label(Triangulation::number_of_vertices()))
{
WarningIn("Foam::conformalVoronoiMesh::printVertexInfo()")
<< nTotalVertices << " does not equal "
<< Triangulation::number_of_vertices()
<< endl;
}
PrintTable<word, label> vertexTable("Vertex Type Information");
vertexTable.add("Total", nTotalVertices);
vertexTable.add("Unassigned", nUnassigned);
vertexTable.add("nInternal", nInternal);
vertexTable.add("nInternalNearBoundary", nInternalNearBoundary);
vertexTable.add("nInternalSurface", nInternalSurface);
vertexTable.add("nInternalFeatureEdge", nInternalFeatureEdge);
vertexTable.add("nInternalFeaturePoint", nInternalFeaturePoint);
vertexTable.add("nExternalSurface", nExternalSurface);
vertexTable.add("nExternalFeatureEdge", nExternalFeatureEdge);
vertexTable.add("nExternalFeaturePoint", nExternalFeaturePoint);
vertexTable.add("nFar", nFar);
vertexTable.add("nReferred", nReferred);
os << endl;
vertexTable.print(os);
}
template<class Triangulation>
Foam::autoPtr<Foam::fvMesh>
Foam::DelaunayMesh<Triangulation>::createMesh
(
const fileName& name,
const Time& runTime,
labelList& vertexMap,
labelList& cellMap
) const
{
pointField points(Triangulation::number_of_vertices());
faceList faces(Triangulation::number_of_finite_facets());
labelList owner(Triangulation::number_of_finite_facets());
labelList neighbour(Triangulation::number_of_finite_facets());
wordList patchNames(1, "foamyHexMesh_defaultPatch");
wordList patchTypes(1, wallPolyPatch::typeName);
PtrList<dictionary> patchDicts(1);
patchDicts.set(0, new dictionary());
List<DynamicList<face> > patchFaces(1, DynamicList<face>());
List<DynamicList<label> > patchOwners(1, DynamicList<label>());
vertexMap.setSize(vertexCount(), -1);
cellMap.setSize(Triangulation::number_of_finite_cells(), -1);
// Calculate pts and a map of point index to location in pts.
label vertI = 0;
for
(
Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
vit != Triangulation::finite_vertices_end();
++vit
)
{
if (!vit->farPoint())
{
vertexMap[vit->index()] = vertI;
points[vertI] = topoint(vit->point());
vertI++;
}
}
points.setSize(vertI);
// Index the cells
label cellI = 0;
for
(
Finite_cells_iterator cit = Triangulation::finite_cells_begin();
cit != Triangulation::finite_cells_end();
++cit
)
{
if
(
!cit->hasFarPoint()
&& !Triangulation::is_infinite(cit)
)
{
cellMap[cit->cellIndex()] = cellI++;
}
}
label faceI = 0;
labelList verticesOnTriFace(3, -1);
face newFace(verticesOnTriFace);
for
(
Finite_facets_iterator fit = Triangulation::finite_facets_begin();
fit != Triangulation::finite_facets_end();
++fit
)
{
const Cell_handle c1(fit->first);
const int oppositeVertex = fit->second;
const Cell_handle c2(c1->neighbor(oppositeVertex));
// Do not output if face has neither opposite vertex as an internal
// if
// (
// !c1->vertex(oppositeVertex)->internalPoint()
// || !Triangulation::mirror_vertex(c1, oppositeVertex)->internalPoint()
// )
// {
// continue;
// }
label c1I = Cb::ctFar;
bool c1Real = false;
if (!c1->hasFarPoint() && !Triangulation::is_infinite(c1))
{
c1I = cellMap[c1->cellIndex()];
c1Real = true;
}
label c2I = Cb::ctFar;
bool c2Real = false;
if (!c2->hasFarPoint() && !Triangulation::is_infinite(c2))
{
c2I = cellMap[c2->cellIndex()];
c2Real = true;
}
if (!c1Real && !c2Real)
{
// Both tets are outside, skip
continue;
}
label ownerCell = -1;
label neighbourCell = -1;
for (label i = 0; i < 3; i++)
{
verticesOnTriFace[i] = vertexMap
[
c1->vertex
(
Triangulation::vertex_triple_index(oppositeVertex, i)
)->index()
];
}
newFace = face(verticesOnTriFace);
if (!c1Real || !c2Real)
{
// Boundary face...
if (!c1Real)
{
//... with c1 outside
ownerCell = c2I;
}
else
{
// ... with c2 outside
ownerCell = c1I;
reverse(newFace);
}
patchFaces[0].append(newFace);
patchOwners[0].append(ownerCell);
}
else
{
// Internal face...
if (c1I < c2I)
{
// ...with c1 as the ownerCell
ownerCell = c1I;
neighbourCell = c2I;
reverse(newFace);
}
else
{
// ...with c2 as the ownerCell
ownerCell = c2I;
neighbourCell = c1I;
}
faces[faceI] = newFace;
owner[faceI] = ownerCell;
neighbour[faceI] = neighbourCell;
faceI++;
}
}
faces.setSize(faceI);
owner.setSize(faceI);
neighbour.setSize(faceI);
sortFaces(faces, owner, neighbour);
Info<< "Creating patches" << endl;
addPatches
(
faceI,
faces,
owner,
patchDicts,
patchFaces,
patchOwners
);
Info<< "Creating mesh" << endl;
autoPtr<fvMesh> meshPtr
(
new fvMesh
(
IOobject
(
name,
runTime.timeName(),
runTime,
IOobject::NO_READ,
IOobject::NO_WRITE
),
xferMove(points),
xferMove(faces),
xferMove(owner),
xferMove(neighbour)
)
);
Info<< "Adding patches" << endl;
List<polyPatch*> patches(patchNames.size());
label nValidPatches = 0;
forAll(patches, p)
{
patches[nValidPatches] = polyPatch::New
(
patchTypes[p],
patchNames[p],
patchDicts[p],
nValidPatches,
meshPtr().boundaryMesh()
).ptr();
nValidPatches++;
}
patches.setSize(nValidPatches);
meshPtr().addFvPatches(patches);
Info<< "Mesh created" << endl;
return meshPtr;
}
// ************************************************************************* //

View File

@ -0,0 +1,959 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "DistributedDelaunayMesh.H"
#include "meshSearch.H"
#include "mapDistribute.H"
#include "zeroGradientFvPatchFields.H"
#include "pointConversion.H"
#include "indexedVertexEnum.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
template<class Triangulation>
Foam::autoPtr<Foam::mapDistribute>
Foam::DistributedDelaunayMesh<Triangulation>::buildMap
(
const List<label>& toProc
)
{
// Determine send map
// ~~~~~~~~~~~~~~~~~~
// 1. Count
labelList nSend(Pstream::nProcs(), 0);
forAll(toProc, i)
{
label procI = toProc[i];
nSend[procI]++;
}
// Send over how many I need to receive
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelListList sendSizes(Pstream::nProcs());
sendSizes[Pstream::myProcNo()] = nSend;
combineReduce(sendSizes, UPstream::listEq());
// 2. Size sendMap
labelListList sendMap(Pstream::nProcs());
forAll(nSend, procI)
{
sendMap[procI].setSize(nSend[procI]);
nSend[procI] = 0;
}
// 3. Fill sendMap
forAll(toProc, i)
{
label procI = toProc[i];
sendMap[procI][nSend[procI]++] = i;
}
// Determine receive map
// ~~~~~~~~~~~~~~~~~~~~~
labelListList constructMap(Pstream::nProcs());
// Local transfers first
constructMap[Pstream::myProcNo()] = identity
(
sendMap[Pstream::myProcNo()].size()
);
label constructSize = constructMap[Pstream::myProcNo()].size();
forAll(constructMap, procI)
{
if (procI != Pstream::myProcNo())
{
label nRecv = sendSizes[procI][Pstream::myProcNo()];
constructMap[procI].setSize(nRecv);
for (label i = 0; i < nRecv; i++)
{
constructMap[procI][i] = constructSize++;
}
}
}
return autoPtr<mapDistribute>
(
new mapDistribute
(
constructSize,
sendMap.xfer(),
constructMap.xfer()
)
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Triangulation>
Foam::DistributedDelaunayMesh<Triangulation>::DistributedDelaunayMesh()
:
DelaunayMesh<Triangulation>(),
allBackgroundMeshBounds_()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Triangulation>
Foam::DistributedDelaunayMesh<Triangulation>::~DistributedDelaunayMesh()
{}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Triangulation>
bool Foam::DistributedDelaunayMesh<Triangulation>::distributeBoundBoxes
(
const boundBox& bb
)
{
allBackgroundMeshBounds_.reset(new List<boundBox>(Pstream::nProcs()));
// Give the bounds of every processor to every other processor
allBackgroundMeshBounds_()[Pstream::myProcNo()] = bb;
Pstream::gatherList(allBackgroundMeshBounds_());
Pstream::scatterList(allBackgroundMeshBounds_());
return true;
}
template<class Triangulation>
bool Foam::DistributedDelaunayMesh<Triangulation>::isLocal
(
const Vertex_handle& v
) const
{
return isLocal(v->procIndex());
}
template<class Triangulation>
bool Foam::DistributedDelaunayMesh<Triangulation>::isLocal
(
const label localProcIndex
) const
{
return localProcIndex == Pstream::myProcNo();
}
template<class Triangulation>
Foam::labelList Foam::DistributedDelaunayMesh<Triangulation>::overlapProcessors
(
const point& centre,
const scalar radiusSqr
) const
{
DynamicList<label> toProc(Pstream::nProcs());
forAll(allBackgroundMeshBounds_(), procI)
{
// Test against the bounding box of the processor
if
(
!isLocal(procI)
&& allBackgroundMeshBounds_()[procI].overlaps(centre, radiusSqr)
)
{
toProc.append(procI);
}
}
return toProc;
}
template<class Triangulation>
bool Foam::DistributedDelaunayMesh<Triangulation>::checkProcBoundaryCell
(
const Cell_handle& cit,
Map<labelList>& circumsphereOverlaps
) const
{
const Foam::point& cc = cit->dual();
const scalar crSqr = magSqr
(
cc - topoint(cit->vertex(0)->point())
);
labelList circumsphereOverlap = overlapProcessors
(
cc,
sqr(1.01)*crSqr
);
cit->cellIndex() = this->getNewCellIndex();
if (!circumsphereOverlap.empty())
{
circumsphereOverlaps.insert(cit->cellIndex(), circumsphereOverlap);
return true;
}
return false;
}
template<class Triangulation>
void Foam::DistributedDelaunayMesh<Triangulation>::findProcessorBoundaryCells
(
Map<labelList>& circumsphereOverlaps
) const
{
// Start by assuming that all the cells have no index
// If they do, they have already been visited so ignore them
labelHashSet cellToCheck
(
Triangulation::number_of_finite_cells()
/Pstream::nProcs()
);
for
(
All_cells_iterator cit = Triangulation::all_cells_begin();
cit != Triangulation::all_cells_end();
++cit
)
{
if (Triangulation::is_infinite(cit))
{
// Index of infinite vertex in this cell.
int i = cit->index(Triangulation::infinite_vertex());
Cell_handle c = cit->neighbor(i);
if (c->unassigned())
{
c->cellIndex() = this->getNewCellIndex();
if (checkProcBoundaryCell(c, circumsphereOverlaps))
{
cellToCheck.insert(c->cellIndex());
}
}
}
else if (cit->parallelDualVertex())
{
if (cit->unassigned())
{
if (checkProcBoundaryCell(cit, circumsphereOverlaps))
{
cellToCheck.insert(cit->cellIndex());
}
}
}
}
for
(
Finite_cells_iterator cit = Triangulation::finite_cells_begin();
cit != Triangulation::finite_cells_end();
++cit
)
{
if (cellToCheck.found(cit->cellIndex()))
{
// Get the neighbours and check them
for (label adjCellI = 0; adjCellI < 4; ++adjCellI)
{
Cell_handle citNeighbor = cit->neighbor(adjCellI);
// Ignore if has far point or previously visited
if
(
!citNeighbor->unassigned()
|| !citNeighbor->internalOrBoundaryDualVertex()
|| Triangulation::is_infinite(citNeighbor)
)
{
continue;
}
checkProcBoundaryCell
(
citNeighbor,
circumsphereOverlaps
);
}
}
}
}
template<class Triangulation>
void Foam::DistributedDelaunayMesh<Triangulation>::markVerticesToRefer
(
const Map<labelList>& circumsphereOverlaps,
PtrList<labelPairHashSet>& referralVertices,
DynamicList<label>& targetProcessor,
DynamicList<Vb>& parallelInfluenceVertices
)
{
// Relying on the order of iteration of cells being the same as before
for
(
Finite_cells_iterator cit = Triangulation::finite_cells_begin();
cit != Triangulation::finite_cells_end();
++cit
)
{
if (Triangulation::is_infinite(cit))
{
continue;
}
Map<labelList>::const_iterator iter =
circumsphereOverlaps.find(cit->cellIndex());
// Pre-tested circumsphere potential influence
if (iter != circumsphereOverlaps.cend())
{
const labelList& citOverlaps = iter();
forAll(citOverlaps, cOI)
{
label procI = citOverlaps[cOI];
for (int i = 0; i < 4; i++)
{
Vertex_handle v = cit->vertex(i);
if (v->farPoint())
{
continue;
}
label vProcIndex = v->procIndex();
label vIndex = v->index();
const labelPair procIndexPair(vProcIndex, vIndex);
// Using the hashSet to ensure that each vertex is only
// referred once to each processor.
// Do not refer a vertex to its own processor.
if (vProcIndex != procI)
{
if (referralVertices[procI].insert(procIndexPair))
{
targetProcessor.append(procI);
parallelInfluenceVertices.append
(
Vb
(
v->point(),
v->index(),
v->type(),
v->procIndex()
)
);
parallelInfluenceVertices.last().targetCellSize() =
v->targetCellSize();
parallelInfluenceVertices.last().alignment() =
v->alignment();
}
}
}
}
}
}
}
template<class Triangulation>
Foam::label Foam::DistributedDelaunayMesh<Triangulation>::referVertices
(
const DynamicList<label>& targetProcessor,
DynamicList<Vb>& parallelVertices,
PtrList<labelPairHashSet>& referralVertices,
labelPairHashSet& receivedVertices
)
{
DynamicList<Vb> referredVertices(targetProcessor.size());
const label preDistributionSize = parallelVertices.size();
mapDistribute pointMap = buildMap(targetProcessor);
// Make a copy of the original list.
DynamicList<Vb> originalParallelVertices(parallelVertices);
pointMap.distribute(parallelVertices);
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
const labelList& constructMap = pointMap.constructMap()[procI];
if (constructMap.size())
{
forAll(constructMap, i)
{
const Vb& v = parallelVertices[constructMap[i]];
if
(
v.procIndex() != Pstream::myProcNo()
&& !receivedVertices.found(labelPair(v.procIndex(), v.index()))
)
{
referredVertices.append(v);
receivedVertices.insert
(
labelPair(v.procIndex(), v.index())
);
}
}
}
}
label preInsertionSize = Triangulation::number_of_vertices();
labelPairHashSet pointsNotInserted = rangeInsertReferredWithInfo
(
referredVertices.begin(),
referredVertices.end()
);
if (!pointsNotInserted.empty())
{
for
(
typename labelPairHashSet::const_iterator iter
= pointsNotInserted.begin();
iter != pointsNotInserted.end();
++iter
)
{
if (receivedVertices.found(iter.key()))
{
receivedVertices.erase(iter.key());
}
}
}
boolList pointInserted(parallelVertices.size(), true);
forAll(parallelVertices, vI)
{
const labelPair procIndexI
(
parallelVertices[vI].procIndex(),
parallelVertices[vI].index()
);
if (pointsNotInserted.found(procIndexI))
{
pointInserted[vI] = false;
}
}
pointMap.reverseDistribute(preDistributionSize, pointInserted);
forAll(originalParallelVertices, vI)
{
const label procIndex = targetProcessor[vI];
if (!pointInserted[vI])
{
if (referralVertices[procIndex].size())
{
if
(
!referralVertices[procIndex].unset
(
labelPair
(
originalParallelVertices[vI].procIndex(),
originalParallelVertices[vI].index()
)
)
)
{
Pout<< "*** not found "
<< originalParallelVertices[vI].procIndex()
<< " " << originalParallelVertices[vI].index() << endl;
}
}
}
}
label postInsertionSize = Triangulation::number_of_vertices();
reduce(preInsertionSize, sumOp<label>());
reduce(postInsertionSize, sumOp<label>());
label nTotalToInsert = referredVertices.size();
reduce(nTotalToInsert, sumOp<label>());
if (preInsertionSize + nTotalToInsert != postInsertionSize)
{
label nNotInserted =
returnReduce(pointsNotInserted.size(), sumOp<label>());
Info<< " Inserted = "
<< setw(name(label(Triangulation::number_of_finite_cells())).size())
<< nTotalToInsert - nNotInserted
<< " / " << nTotalToInsert << endl;
nTotalToInsert -= nNotInserted;
}
else
{
Info<< " Inserted = " << nTotalToInsert << endl;
}
return nTotalToInsert;
}
template<class Triangulation>
void Foam::DistributedDelaunayMesh<Triangulation>::sync
(
const boundBox& bb,
PtrList<labelPairHashSet>& referralVertices,
labelPairHashSet& receivedVertices,
bool iterateReferral
)
{
if (!Pstream::parRun())
{
return;
}
if (allBackgroundMeshBounds_.empty())
{
distributeBoundBoxes(bb);
}
label nVerts = Triangulation::number_of_vertices();
label nCells = Triangulation::number_of_finite_cells();
DynamicList<Vb> parallelInfluenceVertices(0.1*nVerts);
DynamicList<label> targetProcessor(0.1*nVerts);
// Some of these values will not be used, i.e. for non-real cells
DynamicList<Foam::point> circumcentre(0.1*nVerts);
DynamicList<scalar> circumradiusSqr(0.1*nVerts);
Map<labelList> circumsphereOverlaps(nCells);
findProcessorBoundaryCells(circumsphereOverlaps);
Info<< " Influences = "
<< setw(name(nCells).size())
<< returnReduce(circumsphereOverlaps.size(), sumOp<label>()) << " / "
<< returnReduce(nCells, sumOp<label>());
markVerticesToRefer
(
circumsphereOverlaps,
referralVertices,
targetProcessor,
parallelInfluenceVertices
);
referVertices
(
targetProcessor,
parallelInfluenceVertices,
referralVertices,
receivedVertices
);
if (iterateReferral)
{
label oldNReferred = 0;
label nIterations = 1;
Info<< incrIndent << indent
<< "Iteratively referring referred vertices..."
<< endl;
do
{
Info<< indent << "Iteration " << nIterations++ << ":";
circumsphereOverlaps.clear();
targetProcessor.clear();
parallelInfluenceVertices.clear();
findProcessorBoundaryCells(circumsphereOverlaps);
nCells = Triangulation::number_of_finite_cells();
Info<< " Influences = "
<< setw(name(nCells).size())
<< returnReduce(circumsphereOverlaps.size(), sumOp<label>())
<< " / "
<< returnReduce(nCells, sumOp<label>());
markVerticesToRefer
(
circumsphereOverlaps,
referralVertices,
targetProcessor,
parallelInfluenceVertices
);
label nReferred = referVertices
(
targetProcessor,
parallelInfluenceVertices,
referralVertices,
receivedVertices
);
if (nReferred == 0 || nReferred == oldNReferred)
{
break;
}
oldNReferred = nReferred;
} while (true);
Info<< decrIndent;
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Triangulation>
bool Foam::DistributedDelaunayMesh<Triangulation>::distribute
(
const boundBox& bb
)
{
notImplemented
(
"Foam::DistributedDelaunayMesh<Triangulation>::distribute"
"("
" const boundBox& bb"
")"
);
if (!Pstream::parRun())
{
return false;
}
distributeBoundBoxes(bb);
return true;
}
template<class Triangulation>
Foam::autoPtr<Foam::mapDistribute>
Foam::DistributedDelaunayMesh<Triangulation>::distribute
(
const backgroundMeshDecomposition& decomposition
)
{
if (!Pstream::parRun())
{
return autoPtr<mapDistribute>();
}
distributeBoundBoxes(decomposition.procBounds());
DynamicList<point> points(Triangulation::number_of_vertices());
for
(
Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
vit != Triangulation::finite_vertices_end();
++vit
)
{
if (vit->real())
{
points.append(topoint(vit->point()));
}
}
autoPtr<mapDistribute> mapDist = decomposition.distributePoints(points);
return mapDist;
}
template<class Triangulation>
void Foam::DistributedDelaunayMesh<Triangulation>::sync(const boundBox& bb)
{
if (!Pstream::parRun())
{
return;
}
if (allBackgroundMeshBounds_.empty())
{
distributeBoundBoxes(bb);
}
const label nApproxReferred =
Triangulation::number_of_vertices()
/Pstream::nProcs();
PtrList<labelPairHashSet> referralVertices(Pstream::nProcs());
forAll(referralVertices, procI)
{
if (!isLocal(procI))
{
referralVertices.set(procI, new labelPairHashSet(nApproxReferred));
}
}
labelPairHashSet receivedVertices(nApproxReferred);
sync
(
bb,
referralVertices,
receivedVertices,
true
);
}
template<class Triangulation>
template<class PointIterator>
typename Foam::DistributedDelaunayMesh<Triangulation>::labelPairHashSet
Foam::DistributedDelaunayMesh<Triangulation>::rangeInsertReferredWithInfo
(
PointIterator begin,
PointIterator end,
bool printErrors
)
{
const boundBox& bb = allBackgroundMeshBounds_()[Pstream::myProcNo()];
typedef DynamicList
<
std::pair<scalar, label>
> vectorPairPointIndex;
vectorPairPointIndex pointsBbDistSqr;
label count = 0;
for (PointIterator it = begin; it != end; ++it)
{
const Foam::point samplePoint(topoint(it->point()));
scalar distFromBbSqr = 0;
if (!bb.contains(samplePoint))
{
const Foam::point nearestPoint = bb.nearest(samplePoint);
distFromBbSqr = magSqr(nearestPoint - samplePoint);
}
pointsBbDistSqr.append
(
std::make_pair(distFromBbSqr, count++)
);
}
std::random_shuffle(pointsBbDistSqr.begin(), pointsBbDistSqr.end());
// Sort in ascending order by the distance of the point from the centre
// of the processor bounding box
sort(pointsBbDistSqr.begin(), pointsBbDistSqr.end());
typename Triangulation::Vertex_handle hint;
typename Triangulation::Locate_type lt;
int li, lj;
label nNotInserted = 0;
labelPairHashSet uninserted
(
Triangulation::number_of_vertices()
/Pstream::nProcs()
);
for
(
typename vectorPairPointIndex::const_iterator p =
pointsBbDistSqr.begin();
p != pointsBbDistSqr.end();
++p
)
{
const size_t checkInsertion = Triangulation::number_of_vertices();
const Vb& vert = *(begin + p->second);
const Point& pointToInsert = vert.point();
// Locate the point
Cell_handle c = Triangulation::locate(pointToInsert, lt, li, lj, hint);
bool inserted = false;
if (lt == Triangulation::VERTEX)
{
if (printErrors)
{
Vertex_handle nearV =
Triangulation::nearest_vertex(pointToInsert);
Pout<< "Failed insertion, point already exists" << nl
<< "Failed insertion : " << vert.info()
<< " nearest : " << nearV->info();
}
}
else if (lt == Triangulation::OUTSIDE_AFFINE_HULL)
{
WarningIn
(
"Foam::DistributedDelaunayMesh<Triangulation>"
"::rangeInsertReferredWithInfo"
) << "Point is outside affine hull! pt = " << pointToInsert
<< endl;
}
else
{
// Get the cells that conflict with p in a vector V,
// and a facet on the boundary of this hole in f.
std::vector<Cell_handle> V;
typename Triangulation::Facet f;
Triangulation::find_conflicts
(
pointToInsert,
c,
CGAL::Oneset_iterator<typename Triangulation::Facet>(f),
std::back_inserter(V)
);
for (size_t i = 0; i < V.size(); ++i)
{
Cell_handle conflictingCell = V[i];
if
(
Triangulation::dimension() < 3 // 2D triangulation
||
(
!Triangulation::is_infinite(conflictingCell)
&& (
conflictingCell->real()
|| conflictingCell->hasFarPoint()
)
)
)
{
hint = Triangulation::insert_in_hole
(
pointToInsert,
V.begin(),
V.end(),
f.first,
f.second
);
inserted = true;
break;
}
}
}
if (inserted)
{
if (checkInsertion != Triangulation::number_of_vertices() - 1)
{
if (printErrors)
{
Vertex_handle nearV =
Triangulation::nearest_vertex(pointToInsert);
Pout<< "Failed insertion : " << vert.info()
<< " nearest : " << nearV->info();
}
}
else
{
hint->index() = vert.index();
hint->type() = vert.type();
hint->procIndex() = vert.procIndex();
hint->targetCellSize() = vert.targetCellSize();
hint->alignment() = vert.alignment();
}
}
else
{
uninserted.insert(labelPair(vert.procIndex(), vert.index()));
nNotInserted++;
}
}
return uninserted;
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::DistributedDelaunayMesh
Description
SourceFiles
DistributedDelaunayMeshI.H
DistributedDelaunayMesh.C
DistributedDelaunayMeshIO.C
\*---------------------------------------------------------------------------*/
#ifndef DistributedDelaunayMesh_H
#define DistributedDelaunayMesh_H
#include "DelaunayMesh.H"
#include "backgroundMeshDecomposition.H"
#include "autoPtr.H"
#include "boundBox.H"
#include "indexedVertex.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class mapDistribute;
/*---------------------------------------------------------------------------*\
Class DistributedDelaunayMesh Declaration
\*---------------------------------------------------------------------------*/
template<class Triangulation>
class DistributedDelaunayMesh
:
public DelaunayMesh<Triangulation>
{
public:
typedef typename Triangulation::Vertex_handle Vertex_handle;
typedef typename Triangulation::Cell_handle Cell_handle;
typedef typename Triangulation::Point Point;
typedef typename Triangulation::Finite_vertices_iterator
Finite_vertices_iterator;
typedef typename Triangulation::Finite_cells_iterator
Finite_cells_iterator;
typedef typename Triangulation::All_cells_iterator
All_cells_iterator;
typedef typename DelaunayMesh<Triangulation>::labelPairHashSet
labelPairHashSet;
private:
autoPtr<List<boundBox> > allBackgroundMeshBounds_;
// Private Member Functions
//-
bool distributeBoundBoxes(const boundBox& bb);
//-
bool isLocal(const Vertex_handle& v) const;
bool isLocal(const label localProcIndex) const;
labelList overlapProcessors
(
const point& centre,
const scalar radiusSqr
) const;
bool checkProcBoundaryCell
(
const Cell_handle& cit,
Map<labelList>& circumsphereOverlaps
) const;
void findProcessorBoundaryCells
(
Map<labelList>& circumsphereOverlaps
) const;
void markVerticesToRefer
(
const Map<labelList>& circumsphereOverlaps,
PtrList<labelPairHashSet>& referralVertices,
DynamicList<label>& targetProcessor,
DynamicList<Vb>& parallelInfluenceVertices
);
label referVertices
(
const DynamicList<label>& targetProcessor,
DynamicList<Vb>& parallelVertices,
PtrList<labelPairHashSet>& referralVertices,
labelPairHashSet& receivedVertices
);
//- Disallow default bitwise copy construct
DistributedDelaunayMesh(const DistributedDelaunayMesh<Triangulation>&);
//- Disallow default bitwise assignment
void operator=(const DistributedDelaunayMesh<Triangulation>&);
public:
// Constructors
//- Construct from components
DistributedDelaunayMesh();
//- Destructor
~DistributedDelaunayMesh();
// Member Functions
//- Build a mapDistribute for the supplied destination processor data
static autoPtr<mapDistribute> buildMap(const List<label>& toProc);
//-
bool distribute(const boundBox& bb);
autoPtr<mapDistribute> distribute
(
const backgroundMeshDecomposition& decomposition
);
//- Refer vertices so that the processor interfaces are consistent
void sync(const boundBox& bb);
//- Refer vertices so that the processor interfaces are consistent
void sync
(
const boundBox& bb,
PtrList<labelPairHashSet>& referralVertices,
labelPairHashSet& receivedVertices,
bool iterateReferral = true
);
//- Inserts points into the triangulation if the point is within
// the circumsphere of another cell. Returns HashSet of failed
// point insertions
template<class PointIterator>
labelPairHashSet rangeInsertReferredWithInfo
(
PointIterator begin,
PointIterator end,
bool printErrors = true
);
// distributeField();
// Queries
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//#include "DistributedDelaunayMeshI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "DistributedDelaunayMesh.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,74 @@
#include CGAL_FILES
conformalVoronoiMesh/indexedVertex/indexedVertexEnum.C
conformalVoronoiMesh/indexedCell/indexedCellEnum.C
conformalVoronoiMesh/conformalVoronoiMesh.C
conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
conformalVoronoiMesh/conformalVoronoiMeshIO.C
conformalVoronoiMesh/conformalVoronoiMeshFeaturePoints.C
conformalVoronoiMesh/conformalVoronoiMeshFeaturePointSpecialisations.C
cvControls/cvControls.C
conformationSurfaces/conformationSurfaces.C
backgroundMeshDecomposition/backgroundMeshDecomposition.C
cellShapeControl/cellShapeControl/cellShapeControl.C
cellShapeControl/cellShapeControlMesh/cellShapeControlMesh.C
cellSizeAndAlignmentControl = cellShapeControl/cellSizeAndAlignmentControl
$(cellSizeAndAlignmentControl)/cellSizeAndAlignmentControls.C
$(cellSizeAndAlignmentControl)/cellSizeAndAlignmentControl/cellSizeAndAlignmentControl.C
$(cellSizeAndAlignmentControl)/fileControl/fileControl.C
$(cellSizeAndAlignmentControl)/searchableSurfaceControl/searchableSurfaceControl.C
/*cellShapeControl/pQuadCoorControl/pQuadCoorControl.C*/
cellShapeControl/cellAspectRatioControl/cellAspectRatioControl.C
cellShapeControl/smoothAlignmentSolver/smoothAlignmentSolver.C
cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
/*cellSizeControlSurfaces/cellSizeControlSurfaces.C*/
cellSizeFunctions = cellSizeControlSurfaces/cellSizeFunction
$(cellSizeFunctions)/cellSizeFunction/cellSizeFunction.C
$(cellSizeFunctions)/uniform/uniform.C
$(cellSizeFunctions)/uniformDistance/uniformDistance.C
$(cellSizeFunctions)/linearDistance/linearDistance.C
$(cellSizeFunctions)/surfaceOffsetLinearDistance/surfaceOffsetLinearDistance.C
$(cellSizeFunctions)/linearSpatial/linearSpatial.C
surfaceCellSizeFunctions = cellSizeControlSurfaces/surfaceCellSizeFunction
$(surfaceCellSizeFunctions)/surfaceCellSizeFunction/surfaceCellSizeFunction.C
$(surfaceCellSizeFunctions)/uniformValue/uniformValue.C
$(surfaceCellSizeFunctions)/nonUniformField/nonUniformField.C
cellSizeCalculationType = $(surfaceCellSizeFunctions)/cellSizeCalculationType
$(cellSizeCalculationType)/cellSizeCalculationType/cellSizeCalculationType.C
$(cellSizeCalculationType)/fieldFromFile/fieldFromFile.C
$(cellSizeCalculationType)/automatic/automatic.C
initialPointsMethod/initialPointsMethod/initialPointsMethod.C
initialPointsMethod/uniformGrid/uniformGrid.C
initialPointsMethod/bodyCentredCubic/bodyCentredCubic.C
initialPointsMethod/faceCentredCubic/faceCentredCubic.C
initialPointsMethod/pointFile/pointFile.C
initialPointsMethod/autoDensity/autoDensity.C
relaxationModel/relaxationModel/relaxationModel.C
relaxationModel/adaptiveLinear/adaptiveLinear.C
relaxationModel/rampHoldFall/rampHoldFall.C
faceAreaWeightModel/faceAreaWeightModel/faceAreaWeightModel.C
faceAreaWeightModel/piecewiseLinearRamp/piecewiseLinearRamp.C
searchableSurfaceFeatures/searchableSurfaceFeatures.C
searchableSurfaceFeatures/searchableBoxFeatures.C
searchableSurfaceFeatures/triSurfaceMeshFeatures.C
LIB = $(FOAM_LIBBIN)/libconformalVoronoiMesh

View File

@ -0,0 +1,35 @@
EXE_DEBUG = -DFULLDEBUG -g -O0
EXE_FROUNDING_MATH = -frounding-math
EXE_NDEBUG = -DNDEBUG
CGAL_EXACT = /*-DCGAL_DONT_USE_LAZY_KERNEL*/
CGAL_INEXACT = -DCGAL_INEXACT
include $(GENERAL_RULES)/CGAL
FFLAGS = -DCGAL_FILES='"${CGAL_ARCH_PATH}/share/files"'
EXE_INC = \
${EXE_FROUNDING_MATH} \
${EXE_NDEBUG} \
${CGAL_INEXACT} \
${CGAL_INC} \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-IPrintTable \
-I../vectorTools
LIB_LIBS = \
-lmeshTools \
-ledgeMesh \
-lfileFormats \
-ltriSurface \
-ldynamicMesh \
-lsurfMesh \
-lsampling

View File

@ -0,0 +1,235 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "PrintTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class KeyType, class DataType>
Foam::PrintTable<KeyType, DataType>::PrintTable()
:
table_(),
title_(string::null)
{}
template<class KeyType, class DataType>
Foam::PrintTable<KeyType, DataType>::PrintTable(const string& title)
:
table_(),
title_(title)
{}
template<class KeyType, class DataType>
Foam::PrintTable<KeyType, DataType>::PrintTable
(
const PrintTable<KeyType, DataType>& table
)
:
table_(table.table_),
title_(table.title_)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class KeyType, class DataType>
Foam::PrintTable<KeyType, DataType>::~PrintTable()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class KeyType, class DataType>
void Foam::PrintTable<KeyType, DataType>::print
(
Ostream& os,
const bool printSum,
const bool printAverage
) const
{
HashTable<HashTable<DataType, label>, KeyType> combinedTable;
List<HashTableData> procData(Pstream::nProcs(), HashTableData());
procData[Pstream::myProcNo()] = table_;
Pstream::gatherList(procData);
if (Pstream::master())
{
label largestKeyLength = 6;
label largestDataLength = 0;
List<label> largestProcSize(Pstream::nProcs(), 0);
forAll(procData, procI)
{
const HashTableData& procIData = procData[procI];
for
(
typename HashTableData::const_iterator iter = procIData.begin();
iter != procIData.end();
++iter
)
{
if (!combinedTable.found(iter.key()))
{
combinedTable.insert
(
iter.key(),
HashTable<DataType, label>()
);
}
HashTable<DataType, label>& key = combinedTable[iter.key()];
key.insert(procI, iter());
for
(
typename HashTable<DataType, label>
::const_iterator dataIter = key.begin();
dataIter != key.end();
++dataIter
)
{
std::ostringstream buf;
buf << dataIter();
largestDataLength = max
(
largestDataLength,
label(buf.str().length())
);
}
std::ostringstream buf;
buf << iter.key();
largestKeyLength = max
(
largestKeyLength,
label(buf.str().length())
);
}
}
os.width(largestKeyLength);
os << nl << indent << tab << "# " << title_.c_str() << endl;
os.width(largestKeyLength);
os << indent << "# Proc No";
forAll(procData, procI)
{
os << tab;
os.width(largestDataLength);
os << procI;
}
if (printSum)
{
os << tab;
os.width(largestDataLength);
os << "Sum";
}
if (printAverage)
{
os << tab;
os.width(largestDataLength);
os << "Average";
}
os << endl;
const List<KeyType>& sortedTable = combinedTable.sortedToc();
forAll(sortedTable, keyI)
{
const HashTable<DataType, label>& procDataList
= combinedTable[sortedTable[keyI]];
os.width(largestKeyLength);
os << indent << sortedTable[keyI];
forAll(procDataList, elemI)
{
os << tab;
os.width(largestDataLength);
os << procDataList[elemI];
}
if (printSum)
{
DataType sum = 0;
forAll(procDataList, elemI)
{
sum += procDataList[elemI];
}
os << tab;
os.width(largestDataLength);
os << sum;
if (printAverage)
{
os << tab;
os.width(largestDataLength);
os << sum/Pstream::nProcs();
}
}
os << endl;
}
}
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
template<class KeyType, class DataType>
void Foam::PrintTable<KeyType, DataType>::operator=
(
const PrintTable<KeyType, DataType>& rhs
)
{
// Check for assignment to self
if (this == &rhs)
{
FatalErrorIn
(
"Foam::PrintTable<KeyType, DataType>::operator="
"(const Foam::PrintTable<KeyType, DataType>&)"
) << "Attempted assignment to self"
<< abort(FatalError);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PrintTable
Description
Print a table in parallel, e.g.;
\verbatim
Vertex Type Information
Proc # 0 1 2 3
Total 145680 145278 145751 145359
Unassigned 0 0 0 0
nExternalFeatureEdge 883 829 828 960
nExternalFeaturePoint 8 10 10 12
nExternalSurface 9533 9488 9502 9482
nFar 0 0 0 0
nInternal 125494 125198 125642 125174
nInternalFeatureEdge 238 241 241 240
nInternalFeaturePoint 2 2 2 2
nInternalNearBoundary 0 0 0 0
nInternalSurface 9522 9510 9526 9489
nReferred 7545 7497 7500 7587
\endverbatim
SourceFiles
PrintTableI.H
PrintTable.C
\*---------------------------------------------------------------------------*/
#ifndef PrintTable_H
#define PrintTable_H
#include "HashTable.H"
#include "Ostream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class PrintTable Declaration
\*---------------------------------------------------------------------------*/
template<class KeyType, class DataType>
class PrintTable
{
typedef HashTable<DataType, KeyType> HashTableData;
// Private data
//- Hash table holding the data
HashTableData table_;
//- Title of the table
string title_;
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const PrintTable<KeyType, DataType>&);
public:
// Constructors
//- Null constructor
PrintTable();
//- Construct with a title
explicit PrintTable(const string& title);
//- Copy constructor
PrintTable(const PrintTable<KeyType, DataType>& table);
//- Destructor
~PrintTable();
// Member Functions
//- Add an entry (D) to the given key(K)
void add(const KeyType& K, const DataType& D);
//- Print the table
void print
(
Ostream& os,
const bool printSum = false,
const bool printAverage = false
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "PrintTableI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "PrintTable.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class KeyType, class DataType>
void Foam::PrintTable<KeyType, DataType>::add
(
const KeyType& K,
const DataType& D
)
{
table_.set(K, D);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,341 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::backgroundMeshDecomposition
Description
Store a background polyMesh to use for the decomposition of space and
queries for parallel conformalVoronoiMesh.
The requirements are:
+ To have a decomposition of space which can quickly interrogate an
arbitrary location from any processor to reliably and unambiguously
determine which processor owns the space that the point is in, i.e. as
the vertices move, or need inserted as part of the surface conformation,
send them to the correct proc.
+ To be able to be dynamically built, refined and redistributed to other
procs the partitioning as the meshing progresses to balance the load.
+ To be able to query whether a sphere (the circumsphere of a Delaunay tet)
overlaps any part of the space defined by the structure, and whether a
ray (Voronoi edge) penetrates any part of the space defined by the
structure, this is what determines if points get referred to a processor.
SourceFiles
backgroundMeshDecompositionI.H
backgroundMeshDecomposition.C
\*---------------------------------------------------------------------------*/
#ifndef backgroundMeshDecomposition_H
#define backgroundMeshDecomposition_H
#include "fvMesh.H"
#include "hexRef8.H"
#include "cellSet.H"
#include "meshTools.H"
#include "polyTopoChange.H"
#include "mapPolyMesh.H"
#include "decompositionMethod.H"
#include "fvMeshDistribute.H"
#include "removeCells.H"
#include "mapDistributePolyMesh.H"
#include "globalIndex.H"
#include "treeBoundBox.H"
#include "primitivePatch.H"
#include "face.H"
#include "labelList.H"
#include "pointField.H"
#include "indexedOctree.H"
#include "treeDataPrimitivePatch.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef PrimitivePatch<face, List, const pointField, point> bPatch;
typedef treeDataPrimitivePatch<bPatch> treeDataBPatch;
class Time;
class Random;
class conformationSurfaces;
/*---------------------------------------------------------------------------*\
Class backgroundMeshDecomposition Declaration
\*---------------------------------------------------------------------------*/
class backgroundMeshDecomposition
{
// Private data
//- Method details dictionary
//dictionary coeffsDict_;
//- Reference to runtime
const Time& runTime_;
//- Reference to surface
const conformationSurfaces& geometryToConformTo_;
//- Random number generator
Random& rndGen_;
//- Mesh stored on for this processor, specifiying the domain that it
// is responsible for.
fvMesh mesh_;
//- Refinement object
hexRef8 meshCutter_;
//- Patch containing an independent representation of the surface of the
// mesh of this processor
autoPtr<bPatch> boundaryFacesPtr_;
//- Search tree for the boundaryFaces_ patch
autoPtr<indexedOctree<treeDataBPatch> > bFTreePtr_;
//- The bounds of all background meshes on all processors
treeBoundBoxList allBackgroundMeshBounds_;
//- The overall bounds of all of the background meshes, used to test if
// a point that is not found on any processor is in the domain at all
treeBoundBox globalBackgroundBounds_;
//- Decomposition dictionary
IOdictionary decomposeDict_;
//- Decomposition method
autoPtr<decompositionMethod> decomposerPtr_;
//- merge distance required by fvMeshDistribute
scalar mergeDist_;
//- Scale of a cell span vs cell size used to decide to refine a cell
scalar spanScale_;
//- Smallest minimum cell size allowed, i.e. to avoid high initial
// refinement of areas of small size
scalar minCellSizeLimit_;
//- Minimum normal level of refinement
label minLevels_;
//- How fine should the initial sample of the volume a box be to
// investigate the local cell size
label volRes_;
//- Allowed factor above the average cell weight before a background
// cell needs to be split
scalar maxCellWeightCoeff_;
// Private Member Functions
void initialRefinement();
//- Print details of the decomposed mesh
void printMeshData(const polyMesh& mesh) const;
//- Estimate the number of vertices that will be in this cell, returns
// true if the cell is to be split because of the density ratio inside
// it
bool refineCell
(
label cellI,
volumeType volType,
scalar& weightEstimate
) const;
//- Select cells for refinement at the surface of the geometry to be
// meshed
labelList selectRefinementCells
(
List<volumeType>& volumeStatus,
volScalarField& cellWeights
) const;
//- Build the surface patch and search tree
void buildPatchAndTree();
//- Disallow default bitwise copy construct
backgroundMeshDecomposition(const backgroundMeshDecomposition&);
//- Disallow default bitwise assignment
void operator=(const backgroundMeshDecomposition&);
public:
//- Runtime type information
ClassName("backgroundMeshDecomposition");
// Constructors
//- Construct from components in foamyHexMesh operation
backgroundMeshDecomposition
(
const Time& runTime,
Random& rndGen,
const conformationSurfaces& geometryToConformTo,
const dictionary& coeffsDict
);
//- Destructor
~backgroundMeshDecomposition();
// Member Functions
//- Build a mapDistribute for the supplied destination processor data
static autoPtr<mapDistribute> buildMap(const List<label>& toProc);
//- Redistribute the background mesh based on a supplied weight field,
// returning a map to use to redistribute vertices.
autoPtr<mapDistributePolyMesh> distribute
(
volScalarField& cellWeights
);
//- Distribute supplied the points to the appropriate processor
autoPtr<mapDistribute> distributePoints(List<point>& points) const;
//- Is the given position inside the domain of this decomposition
bool positionOnThisProcessor(const point& pt) const;
//- Are the given positions inside the domain of this decomposition
boolList positionOnThisProcessor(const List<point>& pts) const;
//- Does the given box overlap the faces of the boundary of this
// processor
bool overlapsThisProcessor(const treeBoundBox& box) const;
//- Does the given sphere overlap the faces of the boundary of this
// processor
bool overlapsThisProcessor
(
const point& centre,
const scalar radiusSqr
) const;
//- Find nearest intersection of line between start and end, (exposing
// underlying indexedOctree)
pointIndexHit findLine
(
const point& start,
const point& end
) const;
//- Find any intersection of line between start and end, (exposing
// underlying indexedOctree)
pointIndexHit findLineAny
(
const point& start,
const point& end
) const;
//- What processor is the given position on?
labelList processorPosition(const List<point>& pts) const;
//- What is the nearest processor to the given position?
labelList processorNearestPosition(const List<point>& pts) const;
//- Which processors are intersected by the line segment, returns all
// processors whose boundary patch is intersected by the sphere. By
// default this does not return the processor that the query is
// launched from, it is assumed that the point is on that processor.
// The index data member of the pointIndexHit is replaced with the
// processor index.
List<List<pointIndexHit> > intersectsProcessors
(
const List<point>& starts,
const List<point>& ends,
bool includeOwnProcessor = false
) const;
bool overlapsOtherProcessors
(
const point& centre,
const scalar& radiusSqr
) const;
labelList overlapProcessors
(
const point& centre,
const scalar radiusSqr
) const;
// //- Which processors overlap the given sphere, returns all processors
// // whose boundary patch is touched by the sphere or whom the sphere
// // is inside. By default this does not return the processor that the
// // query is launched from, it is assumed that the point is on that
// // processor.
// labelListList overlapsProcessors
// (
// const List<point>& centres,
// const List<scalar>& radiusSqrs,
// const Delaunay& T,
// bool includeOwnProcessor
// ) const;
// Access
//- Return access to the underlying mesh
inline const fvMesh& mesh() const;
//- Return access to the underlying tree
inline const indexedOctree<treeDataBPatch>& tree() const;
//- Return the boundBox of this processor
inline const treeBoundBox& procBounds() const;
//- Return the cell level of the underlying mesh
inline const labelList& cellLevel() const;
//- Return the point level of the underlying mesh
inline const labelList& pointLevel() const;
//- Return the current decomposition method
inline const decompositionMethod& decomposer() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "backgroundMeshDecompositionI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,67 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::fvMesh& Foam::backgroundMeshDecomposition::mesh() const
{
return mesh_;
}
const Foam::indexedOctree<Foam::treeDataBPatch>&
Foam::backgroundMeshDecomposition::tree() const
{
return bFTreePtr_();
}
const Foam::treeBoundBox&
Foam::backgroundMeshDecomposition::procBounds() const
{
return allBackgroundMeshBounds_[Pstream::myProcNo()];
}
const Foam::labelList& Foam::backgroundMeshDecomposition::cellLevel() const
{
return meshCutter_.cellLevel();
}
const Foam::labelList& Foam::backgroundMeshDecomposition::pointLevel() const
{
return meshCutter_.pointLevel();
}
const Foam::decompositionMethod&
Foam::backgroundMeshDecomposition::decomposer() const
{
return decomposerPtr_();
}
// ************************************************************************* //

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellAspectRatioControl.H"
#include "vectorTools.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellAspectRatioControl::cellAspectRatioControl
(
const dictionary& motionDict
)
:
aspectRatioDict_(motionDict.subOrEmptyDict("cellAspectRatioControl")),
aspectRatio_(aspectRatioDict_.lookupOrDefault<scalar>("aspectRatio", 1.0)),
aspectRatioDirection_
(
aspectRatioDict_.lookupOrDefault<vector>
(
"aspectRatioDirection",
vector(0, 0, 0)
)
)
{
Info<< nl << "Cell Aspect Ratio Control" << nl
<< " Ratio : " << aspectRatio_ << nl
<< " Direction : " << aspectRatioDirection_
<< endl;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellAspectRatioControl::~cellAspectRatioControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::cellAspectRatioControl::updateCellSizeAndFaceArea
(
vector& alignmentDir,
scalar& targetFaceArea,
scalar& targetCellSize
) const
{
const scalar cosAngle = mag
(
vectorTools::cosPhi(alignmentDir, aspectRatioDirection_)
);
// Change target face area based on aspect ratio
targetFaceArea
+= targetFaceArea
*(aspectRatio_ - 1.0)
*(1.0 - cosAngle);
// Change target cell size based on aspect ratio
targetCellSize
+= targetCellSize
*(aspectRatio_ - 1.0)
*cosAngle;
alignmentDir *= 0.5*targetCellSize;
}
void Foam::cellAspectRatioControl::updateDeltaVector
(
const vector& alignmentDir,
const scalar targetCellSize,
const scalar rABMag,
vector& delta
) const
{
const scalar cosAngle = mag
(
vectorTools::cosPhi(alignmentDir, aspectRatioDirection_)
);
delta += 0.5
*delta
*cosAngle
*(targetCellSize/rABMag)
*(aspectRatio_ - 1.0);
}
// ************************************************************************* //

View File

@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellAspectRatioControl
Description
SourceFiles
cellAspectRatioControl.C
\*---------------------------------------------------------------------------*/
#ifndef cellAspectRatioControl_H
#define cellAspectRatioControl_H
#include "dictionary.H"
#include "vector.H"
#include "scalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellAspectRatioControl Declaration
\*---------------------------------------------------------------------------*/
class cellAspectRatioControl
{
// Private data
const dictionary aspectRatioDict_;
const scalar aspectRatio_;
const vector aspectRatioDirection_;
// Private Member Functions
//- Disallow default bitwise copy construct
cellAspectRatioControl(const cellAspectRatioControl&);
//- Disallow default bitwise assignment
void operator=(const cellAspectRatioControl&);
public:
// Constructors
//- Construct from dictionary
cellAspectRatioControl
(
const dictionary& motionDict
);
//- Destructor
virtual ~cellAspectRatioControl();
// Member Functions
// Query
void updateCellSizeAndFaceArea
(
vector& alignmentDir,
scalar& targetFaceArea,
scalar& targetCellSize
) const;
void updateDeltaVector
(
const vector& alignmentDir,
const scalar targetCellSize,
const scalar rABMag,
vector& delta
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,368 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellShapeControl.H"
#include "pointField.H"
#include "scalarField.H"
#include "triadField.H"
#include "cellSizeAndAlignmentControl.H"
#include "searchableSurfaceControl.H"
#include "cellSizeFunction.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellShapeControl, 0);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellShapeControl::cellShapeControl
(
const Time& runTime,
const cvControls& foamyHexMeshControls,
const searchableSurfaces& allGeometry,
const conformationSurfaces& geometryToConformTo
)
:
dictionary
(
foamyHexMeshControls.foamyHexMeshDict().subDict("motionControl")
),
runTime_(runTime),
allGeometry_(allGeometry),
geometryToConformTo_(geometryToConformTo),
defaultCellSize_(foamyHexMeshControls.defaultCellSize()),
minimumCellSize_(foamyHexMeshControls.minimumCellSize()),
shapeControlMesh_(runTime),
aspectRatio_(*this),
sizeAndAlignment_
(
runTime,
subDict("shapeControlFunctions"),
geometryToConformTo_,
defaultCellSize_
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellShapeControl::~cellShapeControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::scalarField Foam::cellShapeControl::cellSize
(
const pointField& pts
) const
{
scalarField cellSizes(pts.size());
forAll(pts, i)
{
cellSizes[i] = cellSize(pts[i]);
}
return cellSizes;
}
Foam::scalar Foam::cellShapeControl::cellSize(const point& pt) const
{
scalarList bary;
cellShapeControlMesh::Cell_handle ch;
shapeControlMesh_.barycentricCoords(pt, bary, ch);
scalar size = 0;
if (shapeControlMesh_.dimension() < 3)
{
size = sizeAndAlignment_.cellSize(pt);
}
else if (shapeControlMesh_.is_infinite(ch))
{
// if (nFarPoints != 0)
// {
// for (label pI = 0; pI < 4; ++pI)
// {
// if (!ch->vertex(pI)->farPoint())
// {
// size = ch->vertex(pI)->targetCellSize();
// return size;
// }
// }
// }
// cellShapeControlMesh::Vertex_handle nearV =
// shapeControlMesh_.nearest_vertex_in_cell
// (
// toPoint<cellShapeControlMesh::Point>(pt),
// ch
// );
//
// size = nearV->targetCellSize();
// Find nearest surface. This can be quite slow if there are a lot of
// surfaces
size = sizeAndAlignment_.cellSize(pt);
}
else
{
label nFarPoints = 0;
for (label pI = 0; pI < 4; ++pI)
{
if (ch->vertex(pI)->farPoint())
{
nFarPoints++;
}
}
if (nFarPoints != 0)
{
for (label pI = 0; pI < 4; ++pI)
{
if (!ch->vertex(pI)->uninitialised())
{
size = ch->vertex(pI)->targetCellSize();
return size;
}
}
}
else
{
forAll(bary, pI)
{
size += bary[pI]*ch->vertex(pI)->targetCellSize();
}
}
}
return size;
}
//- Return the cell alignment at the given location
Foam::tensor Foam::cellShapeControl::cellAlignment(const point& pt) const
{
scalarList bary;
cellShapeControlMesh::Cell_handle ch;
shapeControlMesh_.barycentricCoords(pt, bary, ch);
tensor alignment = tensor::zero;
if (shapeControlMesh_.dimension() < 3 || shapeControlMesh_.is_infinite(ch))
{
alignment = tensor::I;
}
else
{
label nFarPoints = 0;
for (label pI = 0; pI < 4; ++pI)
{
if (ch->vertex(pI)->farPoint())
{
nFarPoints++;
}
}
// if (nFarPoints != 0)
// {
// for (label pI = 0; pI < 4; ++pI)
// {
// if (!ch->vertex(pI)->farPoint())
// {
// alignment = ch->vertex(pI)->alignment();
// }
// }
// }
// else
{
triad tri;
for (label pI = 0; pI < 4; ++pI)
{
if (bary[pI] > SMALL)
{
tri += triad(bary[pI]*ch->vertex(pI)->alignment());
}
}
tri.normalize();
tri.orthogonalize();
tri = tri.sortxyz();
alignment = tri;
}
// cellShapeControlMesh::Vertex_handle nearV =
// shapeControlMesh_.nearest_vertex_in_cell
// (
// toPoint<cellShapeControlMesh::Point>(pt),
// ch
// );
//
// alignment = nearV->alignment();
}
return alignment;
}
void Foam::cellShapeControl::cellSizeAndAlignment
(
const point& pt,
scalar& size,
tensor& alignment
) const
{
scalarList bary;
cellShapeControlMesh::Cell_handle ch;
shapeControlMesh_.barycentricCoords(pt, bary, ch);
alignment = tensor::zero;
size = 0;
if (shapeControlMesh_.dimension() < 3 || shapeControlMesh_.is_infinite(ch))
{
// Find nearest surface
size = sizeAndAlignment_.cellSize(pt);
alignment = tensor::I;
}
else
{
label nFarPoints = 0;
for (label pI = 0; pI < 4; ++pI)
{
if (ch->vertex(pI)->farPoint())
{
nFarPoints++;
}
}
if (nFarPoints != 0)
{
for (label pI = 0; pI < 4; ++pI)
{
if (!ch->vertex(pI)->uninitialised())
{
size = ch->vertex(pI)->targetCellSize();
alignment = ch->vertex(pI)->alignment();
}
}
}
else
{
triad tri;
for (label pI = 0; pI < 4; ++pI)
{
size += bary[pI]*ch->vertex(pI)->targetCellSize();
if (bary[pI] > SMALL)
{
tri += triad(bary[pI]*ch->vertex(pI)->alignment());
}
}
tri.normalize();
tri.orthogonalize();
tri = tri.sortxyz();
alignment = tri;
// cellShapeControlMesh::Vertex_handle nearV =
// shapeControlMesh_.nearest_vertex
// (
// toPoint<cellShapeControlMesh::Point>(pt)
// );
//
// alignment = nearV->alignment();
}
}
for (label dir = 0; dir < 3; dir++)
{
triad v = alignment;
if (!v.set(dir) || size == 0)
{
// Force orthogonalization of triad.
scalar dotProd = GREAT;
if (dir == 0)
{
dotProd = v[1] & v[2];
v[dir] = v[1] ^ v[2];
}
if (dir == 1)
{
dotProd = v[0] & v[2];
v[dir] = v[0] ^ v[2];
}
if (dir == 2)
{
dotProd = v[0] & v[1];
v[dir] = v[0] ^ v[1];
}
v.normalize();
v.orthogonalize();
Pout<< "Dot prod = " << dotProd << endl;
Pout<< "Alignment = " << v << endl;
alignment = v;
// FatalErrorIn
// (
// "Foam::conformalVoronoiMesh::setVertexSizeAndAlignment()"
// ) << "Point has bad alignment! "
// << pt << " " << size << " " << alignment << nl
// << "Bary Coords = " << bary << nl
// << ch->vertex(0)->info() << nl
// << ch->vertex(1)->info() << nl
// << ch->vertex(2)->info() << nl
// << ch->vertex(3)->info()
// << abort(FatalError);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellShapeControl
Description
SourceFiles
cellShapeControlI.H
cellShapeControl.C
\*---------------------------------------------------------------------------*/
#ifndef cellShapeControl_H
#define cellShapeControl_H
#include "dictionary.H"
#include "autoPtr.H"
#include "tensor.H"
#include "point.H"
#include "primitiveFieldsFwd.H"
#include "pointFieldFwd.H"
#include "Time.H"
#include "searchableSurfaces.H"
#include "conformationSurfaces.H"
#include "cellAspectRatioControl.H"
#include "cellSizeAndAlignmentControls.H"
#include "cellShapeControlMesh.H"
#include "backgroundMeshDecomposition.H"
#include "cvControls.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellShapeControl Declaration
\*---------------------------------------------------------------------------*/
class cellShapeControl
:
public dictionary
{
// Private data
const Time& runTime_;
const searchableSurfaces& allGeometry_;
const conformationSurfaces& geometryToConformTo_;
const scalar defaultCellSize_;
const scalar minimumCellSize_;
cellShapeControlMesh shapeControlMesh_;
cellAspectRatioControl aspectRatio_;
cellSizeAndAlignmentControls sizeAndAlignment_;
// Private Member Functions
//- Disallow default bitwise copy construct
cellShapeControl(const cellShapeControl&);
//- Disallow default bitwise assignment
void operator=(const cellShapeControl&);
public:
//- Runtime type information
ClassName("cellShapeControl");
// Constructors
//- Construct from dictionary and references to conformalVoronoiMesh and
// searchableSurfaces
cellShapeControl
(
const Time& runTime,
const cvControls& foamyHexMeshControls,
const searchableSurfaces& allGeometry,
const conformationSurfaces& geometryToConformTo
);
//- Destructor
~cellShapeControl();
// Member Functions
// Access
inline const scalar& defaultCellSize() const;
inline cellShapeControlMesh& shapeControlMesh();
inline const cellShapeControlMesh& shapeControlMesh() const;
inline const cellAspectRatioControl& aspectRatio() const;
inline const cellSizeAndAlignmentControls& sizeAndAlignment() const;
inline const scalar& minimumCellSize() const;
// Query
//- Return the cell size at the given location
scalar cellSize(const point& pt) const;
scalarField cellSize(const pointField& pts) const;
//- Return the cell alignment at the given location
tensor cellAlignment(const point& pt) const;
void cellSizeAndAlignment
(
const point& pt,
scalar& size,
tensor& alignment
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "cellShapeControlI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::cellShapeControlMesh&
Foam::cellShapeControl::shapeControlMesh()
{
return shapeControlMesh_;
}
inline const Foam::cellShapeControlMesh&
Foam::cellShapeControl::shapeControlMesh() const
{
return shapeControlMesh_;
}
inline const Foam::scalar& Foam::cellShapeControl::defaultCellSize() const
{
return defaultCellSize_;
}
inline const Foam::cellAspectRatioControl&
Foam::cellShapeControl::aspectRatio() const
{
return aspectRatio_;
}
inline const Foam::cellSizeAndAlignmentControls&
Foam::cellShapeControl::sizeAndAlignment() const
{
return sizeAndAlignment_;
}
inline const Foam::scalar& Foam::cellShapeControl::minimumCellSize() const
{
return minimumCellSize_;
}
// ************************************************************************* //

View File

@ -0,0 +1,836 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellShapeControlMesh.H"
#include "cellSizeAndAlignmentControls.H"
#include "pointIOField.H"
#include "scalarIOField.H"
#include "tensorIOField.H"
#include "tetrahedron.H"
#include "plane.H"
#include "transform.H"
#include "meshTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellShapeControlMesh, 0);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
//Foam::tensor Foam::cellShapeControlMesh::requiredAlignment
//(
// const Foam::point& pt,
// const searchableSurfaces& allGeometry,
// const conformationSurfaces& geometryToConformTo
//) const
//{
// pointIndexHit surfHit;
// label hitSurface;
//
// geometryToConformTo.findSurfaceNearest
// (
// pt,
// sqr(GREAT),
// surfHit,
// hitSurface
// );
//
// if (!surfHit.hit())
// {
// FatalErrorIn
// (
// "Foam::tensor Foam::conformalVoronoiMesh::requiredAlignment"
// ) << "findSurfaceNearest did not find a hit across the surfaces."
// << exit(FatalError) << endl;
// }
//
// // Primary alignment
//
// vectorField norm(1);
//
// allGeometry[hitSurface].getNormal
// (
// List<pointIndexHit>(1, surfHit),
// norm
// );
//
// const vector np = norm[0];
//
// // Generate equally spaced 'spokes' in a circle normal to the
// // direction from the vertex to the closest point on the surface
// // and look for a secondary intersection.
//
// const vector d = surfHit.hitPoint() - pt;
//
// const tensor Rp = rotationTensor(vector(0,0,1), np);
//
// const label s = 36;//foamyHexMeshControls().alignmentSearchSpokes();
//
// scalar closestSpokeHitDistance = GREAT;
//
// pointIndexHit closestSpokeHit;
//
// label closestSpokeSurface = -1;
//
// const scalar spanMag = geometryToConformTo.globalBounds().mag();
//
// for (label i = 0; i < s; i++)
// {
// vector spoke
// (
// Foam::cos(i*constant::mathematical::twoPi/s),
// Foam::sin(i*constant::mathematical::twoPi/s),
// 0
// );
//
// spoke *= spanMag;
//
// spoke = Rp & spoke;
//
// pointIndexHit spokeHit;
//
// label spokeSurface = -1;
//
// // internal spoke
//
// geometryToConformTo.findSurfaceNearestIntersection
// (
// pt,
// pt + spoke,
// spokeHit,
// spokeSurface
// );
//
// if (spokeHit.hit())
// {
// scalar spokeHitDistance = mag
// (
// spokeHit.hitPoint() - pt
// );
//
// if (spokeHitDistance < closestSpokeHitDistance)
// {
// closestSpokeHit = spokeHit;
// closestSpokeSurface = spokeSurface;
// closestSpokeHitDistance = spokeHitDistance;
// }
// }
//
// //external spoke
//
// Foam::point mirrorPt = pt + 2*d;
//
// geometryToConformTo.findSurfaceNearestIntersection
// (
// mirrorPt,
// mirrorPt + spoke,
// spokeHit,
// spokeSurface
// );
//
// if (spokeHit.hit())
// {
// scalar spokeHitDistance = mag
// (
// spokeHit.hitPoint() - mirrorPt
// );
//
// if (spokeHitDistance < closestSpokeHitDistance)
// {
// closestSpokeHit = spokeHit;
// closestSpokeSurface = spokeSurface;
// closestSpokeHitDistance = spokeHitDistance;
// }
// }
// }
//
// if (closestSpokeSurface == -1)
// {
//// WarningIn
//// (
//// "conformalVoronoiMesh::requiredAlignment"
//// "("
//// "const Foam::point& pt"
//// ") const"
//// ) << "No secondary surface hit found in spoke search "
//// << "using " << s
//// << " spokes, try increasing alignmentSearchSpokes."
//// << endl;
//
// return I;
// }
//
// // Auxiliary alignment generated by spoke intersection normal.
//
// allGeometry[closestSpokeSurface].getNormal
// (
// List<pointIndexHit>(1, closestSpokeHit),
// norm
// );
//
// const vector& na = norm[0];
//
// // Secondary alignment
// vector ns = np ^ na;
//
// if (mag(ns) < SMALL)
// {
// FatalErrorIn("conformalVoronoiMesh::requiredAlignment")
// << "Parallel normals detected in spoke search." << nl
// << "point: " << pt << nl
// << "closest surface point: " << surfHit.hitPoint() << nl
// << "closest spoke hit: " << closestSpokeHit.hitPoint() << nl
// << "np: " << surfHit.hitPoint() + np << nl
// << "ns: " << closestSpokeHit.hitPoint() + na << nl
// << exit(FatalError);
// }
//
// ns /= mag(ns);
//
// tensor Rs = rotationTensor((Rp & vector(0,1,0)), ns);
//
// return (Rs & Rp);
//}
Foam::label Foam::cellShapeControlMesh::removePoints()
{
label nRemoved = 0;
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
finite_vertices_begin();
vit != finite_vertices_end();
++vit
)
{
std::list<Vertex_handle> verts;
adjacent_vertices(vit, std::back_inserter(verts));
bool removePt = true;
for
(
std::list<Vertex_handle>::iterator aVit = verts.begin();
aVit != verts.end();
++aVit
)
{
Vertex_handle avh = *aVit;
scalar diff =
mag(avh->targetCellSize() - vit->targetCellSize())
/max(vit->targetCellSize(), 1e-6);
if (diff > 0.05)
{
removePt = false;
}
}
if (removePt)
{
remove(vit);
nRemoved++;
}
}
return nRemoved;
}
Foam::tmp<Foam::pointField> Foam::cellShapeControlMesh::cellCentres() const
{
tmp<pointField> tcellCentres(new pointField(number_of_finite_cells()));
pointField& cellCentres = tcellCentres();
label count = 0;
for
(
CellSizeDelaunay::Finite_cells_iterator c = finite_cells_begin();
c != finite_cells_end();
++c
)
{
if (c->hasFarPoint())
{
continue;
}
scalarList bary;
cellShapeControlMesh::Cell_handle ch;
const Foam::point centre = topoint
(
CGAL::centroid<baseK>
(
c->vertex(0)->point(),
c->vertex(1)->point(),
c->vertex(2)->point(),
c->vertex(3)->point()
)
);
cellCentres[count++] = centre;
}
cellCentres.resize(count);
return tcellCentres;
}
void Foam::cellShapeControlMesh::writeTriangulation()
{
OFstream str
(
"refinementTriangulation_"
+ name(Pstream::myProcNo())
+ ".obj"
);
label count = 0;
Info<< "Write refinementTriangulation" << endl;
for
(
CellSizeDelaunay::Finite_edges_iterator e = finite_edges_begin();
e != finite_edges_end();
++e
)
{
Cell_handle c = e->first;
Vertex_handle vA = c->vertex(e->second);
Vertex_handle vB = c->vertex(e->third);
// Don't write far edges
if (vA->farPoint() || vB->farPoint())
{
continue;
}
// Don't write unowned edges
if (vA->referred() && vB->referred())
{
continue;
}
pointFromPoint p1 = topoint(vA->point());
pointFromPoint p2 = topoint(vB->point());
meshTools::writeOBJ(str, p1, p2, count);
}
if (is_valid())
{
Info<< " Triangulation is valid" << endl;
}
else
{
FatalErrorIn
(
"Foam::triangulatedMesh::writeRefinementTriangulation()"
) << "Triangulation is not valid"
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellShapeControlMesh::cellShapeControlMesh(const Time& runTime)
:
runTime_(runTime),
defaultCellSize_(0.0)
{}
//Foam::triangulatedMesh::triangulatedMesh
//(
// const Time& runTime,
// const fileName& pointsFile,
// const fileName& sizesFile,
// const fileName& alignmentsFile,
// const scalar& defaultCellSize
//)
//:
// defaultCellSize_(defaultCellSize)
//{
// Info<< " Reading points from file : " << pointsFile << endl;
//
// pointIOField points
// (
// IOobject
// (
// pointsFile,
// runTime.constant(),
// runTime,
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// );
//
// Info<< " Reading sizes from file : " << sizesFile << endl;
//
// scalarIOField sizes
// (
// IOobject
// (
// sizesFile,
// runTime.constant(),
// runTime,
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// );
//
// Info<< " Reading alignments from file : " << alignmentsFile << endl;
//
// tensorIOField alignments
// (
// IOobject
// (
// alignmentsFile,
// runTime.constant(),
// runTime,
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// );
//
// Info<< " Number of points : " << points.size() << endl;
// Info<< " Minimum size : " << min(sizes) << endl;
// Info<< " Average size : " << average(sizes) << endl;
// Info<< " Maximum size : " << max(sizes) << endl;
//
// forAll(points, pI)
// {
// size_t nVert = number_of_vertices();
//
// Vertex_handle v = insert
// (
// Point(points[pI].x(), points[pI].y(), points[pI].z())
// );
//
// if (number_of_vertices() == nVert)
// {
// Info<< " Failed to insert point : " << points[pI] << endl;
// }
//
// v->targetCellSize() = sizes[pI];
//
// const tensor& alignment = alignments[pI];
//
//
//
// v->alignment() = alignment;
// }
//
//// scalar factor = 1.0;
//// label maxIteration = 1;
////
//// for (label iteration = 0; iteration < maxIteration; ++iteration)
//// {
//// Info<< "Iteration : " << iteration << endl;
////
//// label nRefined = refineTriangulation(factor);
////
//// Info<< " Number of cells refined in refinement iteration : "
//// << nRefined << nl << endl;
////
//// if (nRefined <= 0 && iteration != 0)
//// {
//// break;
//// }
////
//// factor *= 1.5;
//// }
//
// //writeRefinementTriangulation();
//}
//Foam::triangulatedMesh::triangulatedMesh
//(
// const Time& runTime,
// const DynamicList<Foam::point>& points,
// const DynamicList<scalar>& sizes,
// const DynamicList<tensor>& alignments,
// const scalar& defaultCellSize
//)
//:
// defaultCellSize_(defaultCellSize)
//{
// forAll(points, pI)
// {
// size_t nVert = number_of_vertices();
//
// Vertex_handle v = insert
// (
// Point(points[pI].x(), points[pI].y(), points[pI].z())
// );
//
// if (number_of_vertices() == nVert)
// {
// Info<< "Failed to insert point : " << points[pI] << endl;
// }
//
// v->targetCellSize() = sizes[pI];
//
// v->alignment() = alignments[pI];
// }
//
// //writeRefinementTriangulation();
//
// Info<< nl << "Refinement triangulation information: " << endl;
// Info<< " Number of vertices: " << label(number_of_vertices()) << endl;
// Info<< " Number of cells : "
// << label(number_of_finite_cells()) << endl;
// Info<< " Number of faces : "
// << label(number_of_finite_facets()) << endl;
// Info<< " Number of edges : "
// << label(number_of_finite_edges()) << endl;
// Info<< " Dimensionality : " << label(dimension()) << nl << endl;
//}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellShapeControlMesh::~cellShapeControlMesh()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::cellShapeControlMesh::barycentricCoords
(
const Foam::point& pt,
scalarList& bary,
Cell_handle& ch
) const
{
// Use the previous cell handle as a hint on where to start searching
// Giving a hint causes strange errors...
ch = locate(toPoint<Point>(pt));
if (dimension() > 2 && !is_infinite(ch))
{
oldCellHandle_ = ch;
tetPointRef tet
(
topoint(ch->vertex(0)->point()),
topoint(ch->vertex(1)->point()),
topoint(ch->vertex(2)->point()),
topoint(ch->vertex(3)->point())
);
tet.barycentric(pt, bary);
}
}
Foam::boundBox Foam::cellShapeControlMesh::bounds() const
{
DynamicList<Foam::point> pts(number_of_vertices());
for
(
Finite_vertices_iterator vit = finite_vertices_begin();
vit != finite_vertices_end();
++vit
)
{
if (vit->real())
{
pts.append(topoint(vit->point()));
}
}
boundBox bb(pts);
return bb;
}
void Foam::cellShapeControlMesh::distribute
(
const backgroundMeshDecomposition& decomposition
)
{
if (!Pstream::parRun())
{
return;
}
autoPtr<mapDistribute> mapDist =
DistributedDelaunayMesh<CellSizeDelaunay>::distribute(decomposition);
DynamicList<Foam::point> points(number_of_vertices());
DynamicList<scalar> sizes(number_of_vertices());
DynamicList<tensor> alignments(number_of_vertices());
DynamicList<Vb> farPts(8);
for
(
Finite_vertices_iterator vit = finite_vertices_begin();
vit != finite_vertices_end();
++vit
)
{
if (vit->real())
{
points.append(topoint(vit->point()));
sizes.append(vit->targetCellSize());
alignments.append(vit->alignment());
}
else if (vit->farPoint())
{
farPts.append
(
Vb
(
vit->point(),
-1,
Vb::vtFar,
Pstream::myProcNo()
)
);
farPts.last().targetCellSize() = vit->targetCellSize();
farPts.last().alignment() = vit->alignment();
}
}
mapDist().distribute(points);
mapDist().distribute(sizes);
mapDist().distribute(alignments);
// Reset the entire tessellation
DelaunayMesh<CellSizeDelaunay>::reset();
// Internal points have to be inserted first
DynamicList<Vb> verticesToInsert(points.size());
forAll(farPts, ptI)
{
verticesToInsert.append(farPts[ptI]);
}
forAll(points, pI)
{
verticesToInsert.append
(
Vb
(
toPoint<Point>(points[pI]),
-1,
Vb::vtInternal,
Pstream::myProcNo()
)
);
verticesToInsert.last().targetCellSize() = sizes[pI];
verticesToInsert.last().alignment() = alignments[pI];
}
Info<< nl << " Inserting distributed background tessellation..." << endl;
this->rangeInsertWithInfo
(
verticesToInsert.begin(),
verticesToInsert.end(),
true
);
sync(decomposition.procBounds());
Info<< " Total number of vertices after redistribution "
<< returnReduce(label(number_of_vertices()), sumOp<label>()) << endl;
}
Foam::tensorField Foam::cellShapeControlMesh::dumpAlignments() const
{
tensorField alignmentsTmp(number_of_vertices(), tensor::zero);
label count = 0;
for
(
Finite_vertices_iterator vit = finite_vertices_begin();
vit != finite_vertices_end();
++vit
)
{
alignmentsTmp[count++] = vit->alignment();
}
return alignmentsTmp;
}
void Foam::cellShapeControlMesh::insertBoundingPoints
(
const boundBox& bb,
const cellSizeAndAlignmentControls& sizeControls
)
{
// Loop over bound box points and get cell size and alignment
const pointField bbPoints(bb.points());
forAll(bbPoints, pI)
{
const Foam::point& pt = bbPoints[pI];
// Cell size here will return default cell size
const scalar cellSize = sizeControls.cellSize(pt);
if (debug)
{
Info<< "Insert Bounding Point: " << pt << " " << cellSize << endl;
}
// Get the cell size of the nearest surface.
// geometryToConformTo_.findSurfaceNearest
// (
// pt,
// GREAT,
// surfHit,
// hitSurface
// );
const tensor alignment = tensor::I;
insert
(
pt,
cellSize,
alignment,
Vb::vtInternalNearBoundary
);
}
}
void Foam::cellShapeControlMesh::write() const
{
Info<< "Writing cell size and alignment mesh" << endl;
const fileName name("cellSizeAndAlignmentMesh");
// Reindex the cells
label cellCount = 0;
for
(
Finite_cells_iterator cit = finite_cells_begin();
cit != finite_cells_end();
++cit
)
{
if (!cit->hasFarPoint() && !is_infinite(cit))
{
cit->cellIndex() = cellCount++;
}
}
labelList vertexMap;
labelList cellMap;
autoPtr<fvMesh> meshPtr = DelaunayMesh<CellSizeDelaunay>::createMesh
(
name,
runTime_,
vertexMap,
cellMap
);
const fvMesh& mesh = meshPtr();
pointScalarField sizes
(
IOobject
(
"sizes",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pointMesh::New(mesh),
scalar(0)
);
OFstream str(runTime_.path()/"alignments.obj");
for
(
Finite_vertices_iterator vit = finite_vertices_begin();
vit != finite_vertices_end();
++vit
)
{
if (!vit->farPoint())
{
// Populate sizes
sizes[vertexMap[vit->index()]] = vit->targetCellSize();
// Write alignments
const tensor& alignment = vit->alignment();
pointFromPoint pt = topoint(vit->point());
if
(
alignment.x() == triad::unset[0]
|| alignment.y() == triad::unset[0]
|| alignment.z() == triad::unset[0]
)
{
Info<< "Bad alignment = " << vit->info();
vit->alignment() = tensor::I;
Info<< "New alignment = " << vit->info();
continue;
}
meshTools::writeOBJ(str, pt, alignment.x() + pt);
meshTools::writeOBJ(str, pt, alignment.y() + pt);
meshTools::writeOBJ(str, pt, alignment.z() + pt);
}
}
mesh.write();
}
// ************************************************************************* //

View File

@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellShapeControlMesh
Description
SourceFiles
cellShapeControlMeshI.H
cellShapeControlMesh.C
\*---------------------------------------------------------------------------*/
#ifndef cellShapeControlMesh_H
#define cellShapeControlMesh_H
#include "Time.H"
#include "scalar.H"
#include "point.H"
#include "tensor.H"
#include "triad.H"
#include "fileName.H"
#include "searchableSurfaces.H"
#include "conformationSurfaces.H"
#include "DistributedDelaunayMesh.H"
#include "CGALTriangulation3Ddefs.H"
#include "backgroundMeshDecomposition.H"
#include "boundBox.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class cellSizeAndAlignmentControls;
/*---------------------------------------------------------------------------*\
Class cellShapeControlMesh Declaration
\*---------------------------------------------------------------------------*/
class cellShapeControlMesh
:
public DistributedDelaunayMesh<CellSizeDelaunay>
{
public:
typedef CellSizeDelaunay::Cell_handle Cell_handle;
typedef CellSizeDelaunay::Vertex_handle Vertex_handle;
typedef CellSizeDelaunay::Point Point;
private:
// Private data
const Time& runTime_;
mutable Cell_handle oldCellHandle_;
const scalar defaultCellSize_;
// Private Member Functions
//- Disallow default bitwise copy construct
cellShapeControlMesh(const cellShapeControlMesh&);
//- Disallow default bitwise assignment
void operator=(const cellShapeControlMesh&);
public:
//- Runtime type information
ClassName("cellShapeControlMesh");
// Constructors
explicit cellShapeControlMesh(const Time& runTime);
//- Destructor
~cellShapeControlMesh();
// Member Functions
// Query
const Time& time() const
{
return runTime_;
}
//- Calculate and return the barycentric coordinates for
// interpolating quantities on the background mesh
void barycentricCoords
(
const Foam::point& pt,
scalarList& bary,
Cell_handle& ch
) const;
boundBox bounds() const;
// Edit
label removePoints();
//- Get the centres of all the tets
tmp<pointField> cellCentres() const;
inline Vertex_handle insert
(
const Foam::point& pt,
const scalar& size,
const triad& alignment,
const Foam::indexedVertexEnum::vertexType type = Vb::vtInternal
);
inline Vertex_handle insertFar
(
const Foam::point& pt
);
void distribute(const backgroundMeshDecomposition& decomposition);
tensorField dumpAlignments() const;
void insertBoundingPoints
(
const boundBox& bb,
const cellSizeAndAlignmentControls& sizeControls
);
void writeTriangulation();
void write() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "cellShapeControlMeshI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::cellShapeControlMesh::Vertex_handle Foam::cellShapeControlMesh::insert
(
const Foam::point& pt,
const scalar& size,
const triad& alignment,
const Foam::indexedVertexEnum::vertexType type
)
{
Vertex_handle v = CellSizeDelaunay::insert
(
Point(pt.x(), pt.y(), pt.z())
);
v->type() = type;
v->index() = getNewVertexIndex();
v->procIndex() = Pstream::myProcNo();
v->targetCellSize() = size;
v->alignment() = tensor(alignment.x(), alignment.y(), alignment.z());
return v;
}
Foam::cellShapeControlMesh::Vertex_handle Foam::cellShapeControlMesh::insertFar
(
const Foam::point& pt
)
{
Vertex_handle v = CellSizeDelaunay::insert
(
Point(pt.x(), pt.y(), pt.z())
);
v->type() = Vb::vtFar;
// v->type() = Vb::vtExternalFeaturePoint;
v->index() = getNewVertexIndex();
v->procIndex() = Pstream::myProcNo();
return v;
}
// ************************************************************************* //

View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellSizeAndAlignmentControl.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellSizeAndAlignmentControl, 0);
defineRunTimeSelectionTable(cellSizeAndAlignmentControl, dictionary);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControl::cellSizeAndAlignmentControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
)
:
runTime_(runTime),
defaultCellSize_(defaultCellSize),
forceInitialPointInsertion_
(
controlFunctionDict.lookupOrDefault<Switch>
(
"forceInitialPointInsertion",
"off"
)
),
name_(name)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cellSizeAndAlignmentControl>
Foam::cellSizeAndAlignmentControl::New
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
)
{
word cellSizeAndAlignmentControlTypeName
(
controlFunctionDict.lookup("type")
);
Info<< indent << "Selecting cellSizeAndAlignmentControl "
<< cellSizeAndAlignmentControlTypeName << endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find
(
cellSizeAndAlignmentControlTypeName
);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"cellSizeAndAlignmentControl::New()"
) << "Unknown cellSizeAndAlignmentControl type "
<< cellSizeAndAlignmentControlTypeName
<< endl << endl
<< "Valid cellSizeAndAlignmentControl types are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<cellSizeAndAlignmentControl>
(
cstrIter()
(
runTime,
name,
controlFunctionDict,
geometryToConformTo,
defaultCellSize
)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControl::~cellSizeAndAlignmentControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,184 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellSizeAndAlignmentControl
Description
SourceFiles
cellSizeAndAlignmentControlI.H
cellSizeAndAlignmentControl.C
\*---------------------------------------------------------------------------*/
#ifndef cellSizeAndAlignmentControl_H
#define cellSizeAndAlignmentControl_H
#include "dictionary.H"
#include "conformationSurfaces.H"
#include "Time.H"
#include "quaternion.H"
#include "triadField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSizeAndAlignmentControl Declaration
\*---------------------------------------------------------------------------*/
class cellSizeAndAlignmentControl
{
protected:
const Time& runTime_;
const scalar& defaultCellSize_;
Switch forceInitialPointInsertion_;
private:
// Private data
const word name_;
// Private Member Functions
//- Disallow default bitwise copy construct
cellSizeAndAlignmentControl(const cellSizeAndAlignmentControl&);
//- Disallow default bitwise assignment
void operator=(const cellSizeAndAlignmentControl&);
public:
//- Runtime type information
TypeName("cellSizeAndAlignmentControl");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
cellSizeAndAlignmentControl,
dictionary,
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
),
(
runTime,
name,
controlFunctionDict,
geometryToConformTo,
defaultCellSize
)
);
// Constructors
//- Construct from dictionary and references to conformalVoronoiMesh and
// searchableSurfaces
cellSizeAndAlignmentControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
);
// Selectors
//- Return a reference to the selected cellShapeControl
static autoPtr<cellSizeAndAlignmentControl> New
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
);
//- Destructor
virtual ~cellSizeAndAlignmentControl();
// Member Functions
// Access
const word& name() const
{
return name_;
}
const Switch& forceInitialPointInsertion() const
{
return forceInitialPointInsertion_;
}
// Query
virtual label maxPriority() const = 0;
virtual void cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const = 0;
virtual void initialVertices
(
pointField& pts,
scalarField& sizes,
triadField& alignments
) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellSizeAndAlignmentControls.H"
#include "searchableSurfaceControl.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellSizeAndAlignmentControls, 0);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
bool Foam::cellSizeAndAlignmentControls::evalCellSizeFunctions
(
const point& pt,
scalar& minSize,
label& maxPriority
) const
{
bool anyFunctionFound = false;
// Regions requesting with the same priority take the smallest
if (controlFunctions_.size())
{
// Maintain priority of current hit. Initialise so it always goes
// through at least once.
label previousPriority = labelMin;
forAll(controlFunctions_, i)
{
const cellSizeAndAlignmentControl& cSF = controlFunctions_[i];
if (isA<searchableSurfaceControl>(cSF))
{
const searchableSurfaceControl& sSC =
refCast<const searchableSurfaceControl>(cSF);
anyFunctionFound = sSC.cellSize(pt, minSize, previousPriority);
if (previousPriority > maxPriority)
{
maxPriority = previousPriority;
}
}
}
}
return anyFunctionFound;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControls::cellSizeAndAlignmentControls
(
const Time& runTime,
const dictionary& shapeControlDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
)
:
shapeControlDict_(shapeControlDict),
geometryToConformTo_(geometryToConformTo),
controlFunctions_(shapeControlDict_.size()),
defaultCellSize_(defaultCellSize)
{
label functionI = 0;
forAllConstIter(dictionary, shapeControlDict_, iter)
{
word shapeControlEntryName = iter().keyword();
const dictionary& controlFunctionDict
(
shapeControlDict_.subDict(shapeControlEntryName)
);
Info<< nl << "Shape Control : " << shapeControlEntryName << endl;
Info<< incrIndent;
controlFunctions_.set
(
functionI,
cellSizeAndAlignmentControl::New
(
runTime,
shapeControlEntryName,
controlFunctionDict,
geometryToConformTo_,
defaultCellSize_
)
);
Info<< decrIndent;
functionI++;
}
// Sort controlFunctions_ by maxPriority
SortableList<label> functionPriorities(functionI);
forAll(controlFunctions_, funcI)
{
functionPriorities[funcI] = controlFunctions_[funcI].maxPriority();
}
functionPriorities.reverseSort();
labelList invertedFunctionPriorities =
invert(functionPriorities.size(), functionPriorities.indices());
controlFunctions_.reorder(invertedFunctionPriorities);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControls::~cellSizeAndAlignmentControls()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::scalar Foam::cellSizeAndAlignmentControls::cellSize
(
const point& pt
) const
{
scalar size = defaultCellSize_;
label maxPriority = -1;
evalCellSizeFunctions(pt, size, maxPriority);
return size;
}
Foam::scalar Foam::cellSizeAndAlignmentControls::cellSize
(
const point& pt,
label& maxPriority
) const
{
scalar size = defaultCellSize_;
maxPriority = -1;
evalCellSizeFunctions(pt, size, maxPriority);
return size;
}
// ************************************************************************* //

View File

@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellSizeAndAlignmentControls
Description
SourceFiles
cellSizeAndAlignmentControls.C
\*---------------------------------------------------------------------------*/
#ifndef cellSizeAndAlignmentControls_H
#define cellSizeAndAlignmentControls_H
#include "dictionary.H"
#include "cellSizeAndAlignmentControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSizeAndAlignmentControls Declaration
\*---------------------------------------------------------------------------*/
class cellSizeAndAlignmentControls
{
// Private data
const dictionary& shapeControlDict_;
const conformationSurfaces& geometryToConformTo_;
PtrList<cellSizeAndAlignmentControl> controlFunctions_;
const scalar defaultCellSize_;
// Private Member Functions
bool evalCellSizeFunctions
(
const point& pt,
scalar& minSize,
label& maxPriority
) const;
//- Disallow default bitwise copy construct
cellSizeAndAlignmentControls(const cellSizeAndAlignmentControls&);
//- Disallow default bitwise assignment
void operator=(const cellSizeAndAlignmentControls&);
public:
//- Runtime type information
ClassName("cellSizeAndAlignmentControls");
// Constructors
//- Construct from dictionary
cellSizeAndAlignmentControls
(
const Time& runTime,
const dictionary& shapeControlDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
);
//- Destructor
virtual ~cellSizeAndAlignmentControls();
// Member Functions
// Access
inline const PtrList<cellSizeAndAlignmentControl>&
controlFunctions() const
{
return controlFunctions_;
}
inline const conformationSurfaces& geometryToConformTo() const
{
return geometryToConformTo_;
}
// Query
scalar cellSize(const point& pt) const;
scalar cellSize(const point& pt, label& maxPriority) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,256 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fileControl.H"
#include "addToRunTimeSelectionTable.H"
#include "tetrahedron.H"
#include "scalarList.H"
#include "vectorTools.H"
#include "pointIOField.H"
#include "scalarIOField.H"
#include "triadIOField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fileControl, 0);
addToRunTimeSelectionTable
(
cellSizeAndAlignmentControl,
fileControl,
dictionary
);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fileControl::fileControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
)
:
cellSizeAndAlignmentControl
(
runTime,
name,
controlFunctionDict,
geometryToConformTo,
defaultCellSize
),
pointsFile_(controlFunctionDict.lookup("pointsFile")),
sizesFile_(controlFunctionDict.lookup("sizesFile")),
alignmentsFile_(controlFunctionDict.lookup("alignmentsFile")),
maxPriority_(readLabel(controlFunctionDict.lookup("priority")))
{
Info<< indent << "Loading " << name << " from file:" << nl
<< indent << " priority : " << maxPriority_ << nl
<< indent << " points : " << pointsFile_ << nl
<< indent << " sizes : " << sizesFile_ << nl
<< indent << " alignments : " << alignmentsFile_
<< endl;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fileControl::~fileControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
//
//Foam::scalar Foam::fileControl::cellSize(const point& pt) const
//{
// scalarList bary;
// Cell_handle ch;
//
// triangulatedMesh_.barycentricCoords(pt, bary, ch);
//
// scalar size = 0;
// forAll(bary, pI)
// {
// size += bary[pI]*ch->vertex(pI)->size();
// }
//
// return size;
//}
//
//
////- Return the cell alignment at the given location
//Foam::tensor Foam::fileControl::cellAlignment(const point& pt) const
//{
// scalarList bary;
// Cell_handle ch;
//
// triangulatedMesh_.barycentricCoords(pt, bary, ch);
//
// label nearest = 0;
//
// tensor alignment = Foam::tensor::zero;
// forAll(bary, pI)
// {
// //alignment += bary[pI]*ch->vertex(pI)->alignment();
//
// // Find nearest point
// if (bary[pI] > nearest)
// {
// alignment = ch->vertex(pI)->alignment();
// nearest = bary[pI];
// }
// }
//
// return alignment;
//}
//
//
////- Return the cell alignment at the given location
//void Foam::fileControl::cellSizeAndAlignment
//(
// const point& pt,
// scalar& size,
// tensor& alignment
//) const
//{
// scalarList bary;
// Cell_handle ch;
//
// triangulatedMesh_.barycentricCoords(pt, bary, ch);
//
// size = 0;
// forAll(bary, pI)
// {
// size += bary[pI]*ch->vertex(pI)->size();
// }
//
//// alignment = Foam::tensor::zero;
//// forAll(bary, pI)
//// {
//// alignment += bary[pI]*ch->vertex(pI)->alignment();
//// }
//
// alignment = cellAlignment(pt);
//}
void Foam::fileControl::cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const
{
return;
}
void Foam::fileControl::initialVertices
(
pointField& pts,
scalarField& sizes,
triadField& alignments
) const
{
Info<< " Reading points from file : " << pointsFile_ << endl;
pointIOField pointsTmp
(
IOobject
(
pointsFile_,
runTime_.constant(),
runTime_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
pts.transfer(pointsTmp);
Info<< " Reading sizes from file : " << sizesFile_ << endl;
scalarIOField sizesTmp
(
IOobject
(
sizesFile_,
runTime_.constant(),
runTime_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
sizes.transfer(sizesTmp);
Info<< " Reading alignments from file : " << alignmentsFile_ << endl;
triadIOField alignmentsTmp
(
IOobject
(
alignmentsFile_,
runTime_.constant(),
runTime_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
alignments.transfer(alignmentsTmp);
if ((pts.size() != sizes.size()) || (pts.size() != alignments.size()))
{
FatalErrorIn
(
"Foam::fileControl::initialVertices"
"("
" pointField&,"
" scalarField&,"
" Field<triad>&"
")"
) << "Size of list of points, sizes and alignments do not match:"
<< nl
<< "Points size = " << pts.size() << nl
<< "Sizes size = " << sizes.size() << nl
<< "Alignments size = " << alignments.size()
<< abort(FatalError);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::fileControl
Description
SourceFiles
fileControl.C
\*---------------------------------------------------------------------------*/
#ifndef fileControl_H
#define fileControl_H
#include "cellSizeAndAlignmentControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fileControl Declaration
\*---------------------------------------------------------------------------*/
class fileControl
:
public cellSizeAndAlignmentControl
{
// Private data
const fileName pointsFile_;
const fileName sizesFile_;
const fileName alignmentsFile_;
label maxPriority_;
// Private Member Functions
//- Disallow default bitwise copy construct
fileControl(const fileControl&);
//- Disallow default bitwise assignment
void operator=(const fileControl&);
public:
//- Runtime type information
TypeName("fileControl");
// Constructors
//- Construct from dictionary and references to conformalVoronoiMesh and
// searchableSurfaces
fileControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
);
//- Destructor
~fileControl();
// Member Functions
// Access
// Query
// //- Return the cell size at the given location
// virtual scalar cellSize(const point& pt) const;
//
// //- Return the cell alignment at the given location
// virtual tensor cellAlignment(const point& pt) const;
//
// virtual void cellSizeAndAlignment
// (
// const point& pt,
// scalar& size,
// tensor& alignment
// ) const;
virtual label maxPriority() const
{
return maxPriority_;
}
// Edit
virtual void cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const;
virtual void initialVertices
(
pointField& pts,
scalarField& sizes,
triadField& alignments
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,574 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "searchableSurfaceControl.H"
#include "addToRunTimeSelectionTable.H"
#include "cellSizeFunction.H"
#include "triSurfaceMesh.H"
#include "searchableBox.H"
#include "tetrahedron.H"
#include "vectorTools.H"
#include "quaternion.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(searchableSurfaceControl, 0);
addToRunTimeSelectionTable
(
cellSizeAndAlignmentControl,
searchableSurfaceControl,
dictionary
);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
//Foam::tensor Foam::surfaceControl::requiredAlignment
//(
// const Foam::point& pt,
// const vectorField& ptNormals
//) const
//{
//// pointIndexHit surfHit;
//// label hitSurface;
////
//// geometryToConformTo_.findSurfaceNearest
//// (
//// pt,
//// sqr(GREAT),
//// surfHit,
//// hitSurface
//// );
////
//// if (!surfHit.hit())
//// {
//// FatalErrorIn
//// (
//// "Foam::tensor Foam::conformalVoronoiMesh::requiredAlignment"
//// )
//// << "findSurfaceNearest did not find a hit across the surfaces."
//// << exit(FatalError) << endl;
//// }
////
////// Primary alignment
////
//// vectorField norm(1);
////
//// allGeometry_[hitSurface].getNormal
//// (
//// List<pointIndexHit>(1, surfHit),
//// norm
//// );
////
//// const vector np = norm[0];
////
//// const tensor Rp = rotationTensor(vector(0,0,1), np);
////
//// return (Rp);
//
//// Info<< "Point : " << pt << endl;
//// forAll(ptNormals, pnI)
//// {
//// Info<< " normal " << pnI << " : " << ptNormals[pnI] << endl;
//// }
//
// vector np = ptNormals[0];
//
// const tensor Rp = rotationTensor(vector(0,0,1), np);
//
// vector na = vector::zero;
//
// scalar smallestAngle = GREAT;
//
// for (label pnI = 1; pnI < ptNormals.size(); ++pnI)
// {
// const vector& nextNormal = ptNormals[pnI];
//
// const scalar cosPhi = vectorTools::cosPhi(np, nextNormal);
//
// if (mag(cosPhi) < smallestAngle)
// {
// na = nextNormal;
// smallestAngle = cosPhi;
// }
// }
//
// // Secondary alignment
// vector ns = np ^ na;
//
// if (mag(ns) < SMALL)
// {
// WarningIn("conformalVoronoiMesh::requiredAlignment")
// << "Parallel normals detected in spoke search." << nl
// << "point: " << pt << nl
// << "np : " << np << nl
// << "na : " << na << nl
// << "ns : " << ns << nl
// << endl;
//
// ns = np;
// }
//
// ns /= mag(ns);
//
// tensor Rs = rotationTensor((Rp & vector(0,1,0)), ns);
//
//// Info<< "Point " << pt << nl
//// << " np : " << np << nl
//// << " ns : " << ns << nl
//// << " Rp : " << Rp << nl
//// << " Rs : " << Rs << nl
//// << " Rs&Rp: " << (Rs & Rp) << endl;
//
// return (Rs & Rp);
//}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::searchableSurfaceControl::searchableSurfaceControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
)
:
cellSizeAndAlignmentControl
(
runTime,
name,
controlFunctionDict,
geometryToConformTo,
defaultCellSize
),
surfaceName_(controlFunctionDict.lookupOrDefault<word>("surface", name)),
searchableSurface_(geometryToConformTo.geometry()[surfaceName_]),
geometryToConformTo_(geometryToConformTo),
cellSizeFunctions_(1),
regionToCellSizeFunctions_(geometryToConformTo_.patchNames().size(), -1),
maxPriority_(-1)
{
Info<< indent << "Master settings:" << endl;
Info<< incrIndent;
cellSizeFunctions_.set
(
0,
cellSizeFunction::New
(
controlFunctionDict,
searchableSurface_,
defaultCellSize_,
labelList()
)
);
Info<< decrIndent;
PtrList<cellSizeFunction> regionCellSizeFunctions;
DynamicList<label> defaultCellSizeRegions;
label nRegionCellSizeFunctions = 0;
// Loop over regions - if any entry is not specified they should
// inherit values from the parent surface.
if (controlFunctionDict.found("regions"))
{
const dictionary& regionsDict = controlFunctionDict.subDict("regions");
const wordList& regionNames = geometryToConformTo_.patchNames();
label nRegions = regionsDict.size();
regionCellSizeFunctions.setSize(nRegions + 1);
defaultCellSizeRegions.setCapacity(nRegions);
forAll(regionNames, regionI)
{
const word& regionName = regionNames[regionI];
label regionID = geometryToConformTo_.geometry().findSurfaceRegionID
(
this->name(),
regionName
);
if (regionsDict.found(regionName))
{
// Get the dictionary for region
const dictionary& regionDict = regionsDict.subDict(regionName);
Info<< indent << "Region " << regionName
<< " (ID = " << regionID << ")" << " settings:"
<< endl;
Info<< incrIndent;
regionCellSizeFunctions.set
(
nRegionCellSizeFunctions,
cellSizeFunction::New
(
regionDict,
searchableSurface_,
defaultCellSize_,
labelList(1, regionID)
)
);
Info<< decrIndent;
regionToCellSizeFunctions_[regionID] = nRegionCellSizeFunctions;
nRegionCellSizeFunctions++;
}
else
{
// Add to default list
defaultCellSizeRegions.append(regionID);
}
}
}
if (defaultCellSizeRegions.empty() && !regionCellSizeFunctions.empty())
{
cellSizeFunctions_.transfer(regionCellSizeFunctions);
}
else if (nRegionCellSizeFunctions > 0)
{
regionCellSizeFunctions.set
(
nRegionCellSizeFunctions,
cellSizeFunction::New
(
controlFunctionDict,
searchableSurface_,
defaultCellSize_,
labelList()
)
);
const wordList& regionNames = geometryToConformTo_.patchNames();
forAll(regionNames, regionI)
{
if (regionToCellSizeFunctions_[regionI] == -1)
{
regionToCellSizeFunctions_[regionI] = nRegionCellSizeFunctions;
}
}
cellSizeFunctions_.transfer(regionCellSizeFunctions);
}
else
{
const wordList& regionNames = geometryToConformTo_.patchNames();
forAll(regionNames, regionI)
{
if (regionToCellSizeFunctions_[regionI] == -1)
{
regionToCellSizeFunctions_[regionI] = 0;
}
}
}
forAll(cellSizeFunctions_, funcI)
{
const label funcPriority = cellSizeFunctions_[funcI].priority();
if (funcPriority > maxPriority_)
{
maxPriority_ = funcPriority;
}
}
// Sort controlFunctions_ by maxPriority
SortableList<label> functionPriorities(cellSizeFunctions_.size());
forAll(cellSizeFunctions_, funcI)
{
functionPriorities[funcI] = cellSizeFunctions_[funcI].priority();
}
functionPriorities.reverseSort();
labelList invertedFunctionPriorities =
invert(functionPriorities.size(), functionPriorities.indices());
cellSizeFunctions_.reorder(invertedFunctionPriorities);
Info<< nl << "There are " << cellSizeFunctions_.size()
<< " region control functions" << endl;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::searchableSurfaceControl::~searchableSurfaceControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::searchableSurfaceControl::initialVertices
(
pointField& pts,
scalarField& sizes,
triadField& alignments
) const
{
pts = searchableSurface_.points();
sizes.setSize(pts.size());
alignments.setSize(pts.size());
const scalar nearFeatDistSqrCoeff = 1e-8;
forAll(pts, pI)
{
// Is the point in the extendedFeatureEdgeMesh? If so get the
// point normal, otherwise get the surface normal from
// searchableSurface
pointIndexHit info;
label infoFeature;
geometryToConformTo_.findFeaturePointNearest
(
pts[pI],
nearFeatDistSqrCoeff,
info,
infoFeature
);
scalar limitedCellSize = GREAT;
autoPtr<triad> pointAlignment;
if (info.hit())
{
const extendedFeatureEdgeMesh& features =
geometryToConformTo_.features()[infoFeature];
vectorField norms = features.featurePointNormals(info.index());
// Create a triad from these norms.
pointAlignment.set(new triad());
forAll(norms, nI)
{
pointAlignment() += norms[nI];
}
pointAlignment().normalize();
pointAlignment().orthogonalize();
}
else
{
geometryToConformTo_.findEdgeNearest
(
pts[pI],
nearFeatDistSqrCoeff,
info,
infoFeature
);
if (info.hit())
{
const extendedFeatureEdgeMesh& features =
geometryToConformTo_.features()[infoFeature];
vectorField norms = features.edgeNormals(info.index());
// Create a triad from these norms.
pointAlignment.set(new triad());
forAll(norms, nI)
{
pointAlignment() += norms[nI];
}
pointAlignment().normalize();
pointAlignment().orthogonalize();
}
else
{
pointField ptField(1, pts[pI]);
scalarField distField(1, nearFeatDistSqrCoeff);
List<pointIndexHit> infoList(1, pointIndexHit());
searchableSurface_.findNearest(ptField, distField, infoList);
vectorField normals(1);
searchableSurface_.getNormal(infoList, normals);
pointAlignment.set(new triad(normals[0]));
// Limit cell size
const vector vN =
infoList[0].hitPoint()
- 2.0*normals[0]*defaultCellSize_;
List<pointIndexHit> intersectionList;
searchableSurface_.findLineAny
(
ptField,
pointField(1, vN),
intersectionList
);
// if (intersectionList[0].hit())
// {
// scalar dist =
// mag(intersectionList[0].hitPoint() - pts[pI]);
//
// limitedCellSize = dist/2.0;
// }
}
}
label priority = -1;
if (!cellSize(pts[pI], sizes[pI], priority))
{
FatalErrorIn
(
"Foam::searchableSurfaceControl::initialVertices"
"(pointField&, scalarField&, tensorField&)"
) << "Could not calculate cell size"
<< abort(FatalError);
}
sizes[pI] = min(limitedCellSize, sizes[pI]);
alignments[pI] = pointAlignment();
}
}
void Foam::searchableSurfaceControl::cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const
{
const tmp<pointField> tmpPoints = searchableSurface_.points();
const pointField& points = tmpPoints();
const scalar nearFeatDistSqrCoeff = 1e-8;
forAll(points, pI)
{
// Is the point in the extendedFeatureEdgeMesh? If so get the
// point normal, otherwise get the surface normal from
// searchableSurface
pointField ptField(1, points[pI]);
scalarField distField(1, nearFeatDistSqrCoeff);
List<pointIndexHit> infoList(1, pointIndexHit());
searchableSurface_.findNearest(ptField, distField, infoList);
if (infoList[0].hit())
{
vectorField normals(1);
searchableSurface_.getNormal(infoList, normals);
labelList region(1, -1);
searchableSurface_.getRegion(infoList, region);
const cellSizeFunction& sizeFunc =
sizeFunctions()[regionToCellSizeFunctions_[region[0]]];
pointField extraPts;
scalarField extraSizes;
sizeFunc.sizeLocations
(
infoList[0],
normals[0],
extraPts,
extraSizes
);
pts.append(extraPts);
sizes.append(extraSizes);
}
}
}
bool Foam::searchableSurfaceControl::cellSize
(
const Foam::point& pt,
scalar& cellSize,
label& priority
) const
{
bool anyFunctionFound = false;
forAll(sizeFunctions(), funcI)
{
const cellSizeFunction& sizeFunc = sizeFunctions()[funcI];
if (sizeFunc.priority() < priority)
{
continue;
}
scalar sizeI = -1;
if (sizeFunc.cellSize(pt, sizeI))
{
anyFunctionFound = true;
if (sizeFunc.priority() == priority)
{
if (sizeI < cellSize)
{
cellSize = sizeI;
}
}
else
{
cellSize = sizeI;
priority = sizeFunc.priority();
}
if (debug)
{
Info<< " sizeI " << sizeI
<<" minSize " << cellSize << endl;
}
}
}
return anyFunctionFound;
}
// ************************************************************************* //

View File

@ -0,0 +1,191 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::searchableSurfaceControl
Description
SourceFiles
searchableSurfaceControl.C
\*---------------------------------------------------------------------------*/
#ifndef searchableSurfaceControl_H
#define searchableSurfaceControl_H
#include "cellSizeFunction.H"
#include "triad.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class surfaceControl Declaration
\*---------------------------------------------------------------------------*/
class searchableSurfaceControl
:
public cellSizeAndAlignmentControl
{
// Private data
//- Name of the surface
const word surfaceName_;
//- Reference to the searchableSurface object holding the geometry data
const searchableSurface& searchableSurface_;
const conformationSurfaces& geometryToConformTo_;
PtrList<cellSizeFunction> cellSizeFunctions_;
labelList regionToCellSizeFunctions_;
label maxPriority_;
// const conformationSurfaces& geometryToConformTo_;
//
// //- Indices of surfaces in allGeometry that are to be conformed to
// labelList surfaces_;
//
// //- A list of all of the cellSizeFunction objects
// PtrList<cellSizeFunction> cellSizeFunctions_;
//
// autoPtr<triangulatedMesh> triangulatedMesh_;
//
//
// // Private Member Functions
//
// //-
// tensor requiredAlignment
// (
// const point& pt,
// const vectorField& ptNormals
// ) const;
//- Disallow default bitwise copy construct
searchableSurfaceControl(const searchableSurfaceControl&);
//- Disallow default bitwise assignment
void operator=(const searchableSurfaceControl&);
public:
//- Runtime type information
TypeName("searchableSurfaceControl");
// Constructors
//- Construct from dictionary and references to conformalVoronoiMesh and
// searchableSurfaces
searchableSurfaceControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& geometryToConformTo,
const scalar& defaultCellSize
);
//- Destructor
~searchableSurfaceControl();
// Member Functions
// Access
// //- Return reference to the searchableSurfaces object containing
// // all of the geometry
// inline const searchableSurfaces& geometry() const;
//
// //- Return the surface indices
// inline const labelList& surfaces() const;
//
//
// // Query
//
// //- Return the cell size at the given location
// virtual scalar cellSize(const point& pt) const;
//
// //- Return the cell alignment at the given location
// virtual tensor cellAlignment(const point& pt) const;
//
// virtual void cellSizeAndAlignment
// (
// const point& pt,
// scalar& size,
// tensor& alignment
// ) const;
virtual void cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const;
virtual void initialVertices
(
pointField& pts,
scalarField& sizes,
triadField& alignments
) const;
const PtrList<cellSizeFunction>& sizeFunctions() const
{
return cellSizeFunctions_;
}
virtual label maxPriority() const
{
return maxPriority_;
}
bool cellSize
(
const Foam::point& pt,
scalar& cellSize,
label& priority
) const;
// Edit
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,784 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "controlMeshRefinement.H"
#include "cellSizeAndAlignmentControl.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(controlMeshRefinement, 0);
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::scalar Foam::controlMeshRefinement::calcFirstDerivative
(
const Foam::point& a,
const scalar& cellSizeA,
const Foam::point& b,
const scalar& cellSizeB
) const
{
return (cellSizeA - cellSizeB)/mag(a - b);
}
//Foam::scalar Foam::controlMeshRefinement::calcSecondDerivative
//(
// const Foam::point& a,
// const scalar& cellSizeA,
// const Foam::point& midPoint,
// const scalar& cellSizeMid,
// const Foam::point& b,
// const scalar& cellSizeB
//) const
//{
// return (cellSizeA - 2*cellSizeMid + cellSizeB)/magSqr((a - b)/2);
//}
bool Foam::controlMeshRefinement::detectEdge
(
const Foam::point& startPt,
const Foam::point& endPt,
pointHit& pointFound,
const scalar tolSqr,
const scalar secondDerivTolSqr
) const
{
Foam::point a(startPt);
Foam::point b(endPt);
Foam::point midPoint = (a + b)/2.0;
label nIterations = 0;
while (true)
{
nIterations++;
if
(
magSqr(a - b) < tolSqr
)
{
pointFound.setPoint(midPoint);
pointFound.setHit();
return true;
}
// Split into two regions
scalar cellSizeA = sizeControls_.cellSize(a);
scalar cellSizeB = sizeControls_.cellSize(b);
// if (magSqr(cellSizeA - cellSizeB) < 1e-6)
// {
// return false;
// }
scalar cellSizeMid = sizeControls_.cellSize(midPoint);
// Region 1
Foam::point midPoint1 = (a + midPoint)/2.0;
const scalar cellSizeMid1 = sizeControls_.cellSize(midPoint1);
// scalar firstDerivative1 =
// calcFirstDerivative(cellSizeA, cellSizeMid);
scalar secondDerivative1 =
calcSecondDerivative
(
a,
cellSizeA,
midPoint1,
cellSizeMid1,
midPoint,
cellSizeMid
);
// Region 2
Foam::point midPoint2 = (midPoint + b)/2.0;
const scalar cellSizeMid2 = sizeControls_.cellSize(midPoint2);
// scalar firstDerivative2 =
// calcFirstDerivative(f, cellSizeMid, cellSizeB);
scalar secondDerivative2 =
calcSecondDerivative
(
midPoint,
cellSizeMid,
midPoint2,
cellSizeMid2,
b,
cellSizeB
);
// Neither region appears to have an inflection
// To be sure should use higher order derivatives
if
(
magSqr(secondDerivative1) < secondDerivTolSqr
&& magSqr(secondDerivative2) < secondDerivTolSqr
)
{
return false;
}
// Pick region with greatest second derivative
if (magSqr(secondDerivative1) > magSqr(secondDerivative2))
{
b = midPoint;
midPoint = midPoint1;
}
else
{
a = midPoint;
midPoint = midPoint2;
}
}
}
Foam::pointHit Foam::controlMeshRefinement::findDiscontinuities
(
const linePointRef& l
) const
{
pointHit p(point::max);
const scalar tolSqr = sqr(1e-3);
const scalar secondDerivTolSqr = sqr(1e-3);
detectEdge
(
l.start(),
l.end(),
p,
tolSqr,
secondDerivTolSqr
);
return p;
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::controlMeshRefinement::controlMeshRefinement
(
cellShapeControl& shapeController
)
:
shapeController_(shapeController),
mesh_(shapeController.shapeControlMesh()),
sizeControls_(shapeController.sizeAndAlignment()),
geometryToConformTo_(sizeControls_.geometryToConformTo())
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::controlMeshRefinement::~controlMeshRefinement()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::controlMeshRefinement::initialMeshPopulation
(
const autoPtr<backgroundMeshDecomposition>& decomposition
)
{
autoPtr<boundBox> overallBoundBox;
// Need to pass in the background mesh decomposition so that can test if
// a point to insert is on the processor.
if (Pstream::parRun())
{
// overallBoundBox.set(new boundBox(decomposition().procBounds()));
}
else
{
// overallBoundBox.set
// (
// new boundBox(geometryToConformTo_.geometry().bounds())
// );
//
// mesh_.insertBoundingPoints
// (
// overallBoundBox(),
// sizeControls_
// );
}
Map<label> priorityMap;
const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
sizeControls_.controlFunctions();
forAll(controlFunctions, fI)
{
const cellSizeAndAlignmentControl& controlFunction =
controlFunctions[fI];
const Switch& forceInsertion =
controlFunction.forceInitialPointInsertion();
Info<< "Inserting points from " << controlFunction.name()
<< " (" << controlFunction.type() << ")" << endl;
Info<< " Force insertion is " << forceInsertion.asText() << endl;
pointField pts;
scalarField sizes;
triadField alignments;
controlFunction.initialVertices(pts, sizes, alignments);
Info<< " Got initial vertices list" << endl;
List<Vb> vertices(pts.size());
// Clip the minimum size
for (label vI = 0; vI < pts.size(); ++vI)
{
vertices[vI] = Vb(pts[vI], Vb::vtInternalNearBoundary);
// Info<< "Find size of vertex " << vI << endl;
label maxPriority = -1;
scalar size = sizeControls_.cellSize(pts[vI], maxPriority);
// Info<< " Size = " << size << ", priority = " << maxPriority
// << endl;
if (maxPriority > controlFunction.maxPriority())
{
vertices[vI].targetCellSize() = max
(
size,
shapeController_.minimumCellSize()
);
}
else if (maxPriority == controlFunction.maxPriority())
{
vertices[vI].targetCellSize() = max
(
min(sizes[vI], size),
shapeController_.minimumCellSize()
);
}
else
{
vertices[vI].targetCellSize() = max
(
sizes[vI],
shapeController_.minimumCellSize()
);
}
vertices[vI].alignment() = alignments[vI];
}
Info<< " Clipped minimum size" << endl;
pts.clear();
sizes.clear();
alignments.clear();
PackedBoolList keepVertex(vertices.size(), true);
forAll(vertices, vI)
{
bool keep = true;
pointFromPoint pt = topoint(vertices[vI].point());
if (Pstream::parRun())
{
keep = decomposition().positionOnThisProcessor(pt);
}
if (keep && geometryToConformTo_.wellOutside(pt, SMALL))
{
keep = false;
}
if (!keep)
{
keepVertex[vI] = false;
}
}
inplaceSubset(keepVertex, vertices);
const label preInsertedSize = mesh_.number_of_vertices();
Info<< " Check sizes" << endl;
forAll(vertices, vI)
{
bool insertPoint = false;
pointFromPoint pt(topoint(vertices[vI].point()));
if
(
mesh_.dimension() < 3
|| mesh_.is_infinite
(
mesh_.locate(vertices[vI].point())
)
)
{
insertPoint = true;
}
const scalar interpolatedCellSize = shapeController_.cellSize(pt);
const triad interpolatedAlignment =
shapeController_.cellAlignment(pt);
const scalar calculatedCellSize = vertices[vI].targetCellSize();
const triad calculatedAlignment = vertices[vI].alignment();
if (debug)
{
Info<< "Point = " << pt << nl
<< " Size(interp) = " << interpolatedCellSize << nl
<< " Size(calc) = " << calculatedCellSize << nl
<< " Align(interp) = " << interpolatedAlignment << nl
<< " Align(calc) = " << calculatedAlignment << nl
<< endl;
}
const scalar sizeDiff =
mag(interpolatedCellSize - calculatedCellSize);
const scalar alignmentDiff =
diff(interpolatedAlignment, calculatedAlignment);
if (debug)
{
Info<< " size difference = " << sizeDiff << nl
<< ", alignment difference = " << alignmentDiff << endl;
}
// @todo Also need to base it on the alignments
if
(
sizeDiff/interpolatedCellSize > 0.1
|| alignmentDiff > 0.15
)
{
insertPoint = true;
}
if (forceInsertion || insertPoint)
{
const label oldSize = mesh_.vertexCount();
cellShapeControlMesh::Vertex_handle insertedVert = mesh_.insert
(
pt,
calculatedCellSize,
vertices[vI].alignment(),
Vb::vtInternalNearBoundary
);
if (oldSize == mesh_.vertexCount() - 1)
{
priorityMap.insert
(
insertedVert->index(),
controlFunction.maxPriority()
);
}
}
}
//mesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
Info<< " Inserted "
<< returnReduce
(
label(mesh_.number_of_vertices()) - preInsertedSize,
sumOp<label>()
)
<< "/" << returnReduce(vertices.size(), sumOp<label>())
<< endl;
}
forAll(controlFunctions, fI)
{
const cellSizeAndAlignmentControl& controlFunction =
controlFunctions[fI];
const Switch& forceInsertion =
controlFunction.forceInitialPointInsertion();
Info<< "Inserting points from " << controlFunction.name()
<< " (" << controlFunction.type() << ")" << endl;
Info<< " Force insertion is " << forceInsertion.asText() << endl;
DynamicList<Foam::point> extraPts;
DynamicList<scalar> extraSizes;
controlFunction.cellSizeFunctionVertices(extraPts, extraSizes);
List<Vb> vertices(extraPts.size());
// Clip the minimum size
for (label vI = 0; vI < extraPts.size(); ++vI)
{
vertices[vI] = Vb(extraPts[vI], Vb::vtUnassigned);
label maxPriority = -1;
scalar size = sizeControls_.cellSize(extraPts[vI], maxPriority);
if (maxPriority > controlFunction.maxPriority())
{
vertices[vI].targetCellSize() = max
(
size,
shapeController_.minimumCellSize()
);
}
else if (maxPriority == controlFunction.maxPriority())
{
vertices[vI].targetCellSize() = max
(
min(extraSizes[vI], size),
shapeController_.minimumCellSize()
);
}
else
{
vertices[vI].targetCellSize() = max
(
extraSizes[vI],
shapeController_.minimumCellSize()
);
}
}
PackedBoolList keepVertex(vertices.size(), true);
forAll(vertices, vI)
{
bool keep = true;
pointFromPoint pt = topoint(vertices[vI].point());
if (Pstream::parRun())
{
keep = decomposition().positionOnThisProcessor(pt);
}
if (keep && geometryToConformTo_.wellOutside(pt, SMALL))
{
keep = false;
}
if (!keep)
{
keepVertex[vI] = false;
}
}
inplaceSubset(keepVertex, vertices);
const label preInsertedSize = mesh_.number_of_vertices();
forAll(vertices, vI)
{
bool insertPoint = false;
pointFromPoint pt(topoint(vertices[vI].point()));
if
(
mesh_.dimension() < 3
|| mesh_.is_infinite
(
mesh_.locate(vertices[vI].point())
)
)
{
insertPoint = true;
}
const scalar interpolatedCellSize = shapeController_.cellSize(pt);
const scalar calculatedCellSize = vertices[vI].targetCellSize();
if (debug)
{
Info<< "Point = " << pt << nl
<< " Size(interp) = " << interpolatedCellSize << nl
<< " Size(calc) = " << calculatedCellSize << nl
<< endl;
}
const scalar sizeDiff =
mag(interpolatedCellSize - calculatedCellSize);
if (debug)
{
Info<< " size difference = " << sizeDiff << endl;
}
// @todo Also need to base it on the alignments
if (sizeDiff/interpolatedCellSize > 0.1)
{
insertPoint = true;
}
if (forceInsertion || insertPoint)
{
// Check the priority
// cellShapeControlMesh::Cell_handle ch =
// mesh_.locate(toPoint<cellShapeControlMesh::Point>(pt));
// if (mesh_.is_infinite(ch))
// {
// continue;
// }
// const label newPtPriority = controlFunction.maxPriority();
// label highestPriority = -1;
// for (label cI = 0; cI < 4; ++cI)
// {
// if (mesh_.is_infinite(ch->vertex(cI)))
// {
// continue;
// }
// const label vertPriority =
// priorityMap[ch->vertex(cI)->index()];
// if (vertPriority > highestPriority)
// {
// highestPriority = vertPriority;
// }
// }
// if (newPtPriority >= highestPriority)
// {
// const label oldSize = mesh_.vertexCount();
//
// cellShapeControlMesh::Vertex_handle insertedVert =
mesh_.insert
(
pt,
calculatedCellSize,
vertices[vI].alignment(),
Vb::vtInternal
);
// if (oldSize == mesh_.vertexCount() - 1)
// {
// priorityMap.insert
// (
// insertedVert->index(),
// newPtPriority
// );
// }
// }
}
}
//mesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
Info<< " Inserted extra points "
<< returnReduce
(
label(mesh_.number_of_vertices()) - preInsertedSize,
sumOp<label>()
)
<< "/" << returnReduce(vertices.size(), sumOp<label>())
<< endl;
}
// Change cell size function of bounding points to be consistent
// with their nearest neighbours
// for
// (
// CellSizeDelaunay::Finite_vertices_iterator vit =
// mesh_.finite_vertices_begin();
// vit != mesh_.finite_vertices_end();
// ++vit
// )
// {
// if (vit->uninitialised())
// {
// // Get its adjacent vertices
// std::list<CellSizeDelaunay::Vertex_handle> adjacentVertices;
//
// mesh_.adjacent_vertices
// (
// vit,
// std::back_inserter(adjacentVertices)
// );
//
// scalar totalCellSize = 0;
// label nVerts = 0;
//
// for
// (
// std::list<CellSizeDelaunay::Vertex_handle>::iterator avit =
// adjacentVertices.begin();
// avit != adjacentVertices.end();
// ++avit
// )
// {
// if (!(*avit)->uninitialised())
// {
// totalCellSize += (*avit)->targetCellSize();
// nVerts++;
// }
// }
//
// Pout<< "Changing " << vit->info();
//
// vit->targetCellSize() = totalCellSize/nVerts;
// vit->type() = Vb::vtInternalNearBoundary;
//
// Pout<< "to " << vit->info() << endl;
// }
// }
}
Foam::label Foam::controlMeshRefinement::refineMesh
(
const autoPtr<backgroundMeshDecomposition>& decomposition
)
{
Info<< "Iterate over "
<< returnReduce(label(mesh_.number_of_finite_edges()), sumOp<label>())
<< " cell size mesh edges" << endl;
DynamicList<Vb> verts(mesh_.number_of_vertices());
label count = 0;
for
(
CellSizeDelaunay::Finite_edges_iterator eit =
mesh_.finite_edges_begin();
eit != mesh_.finite_edges_end();
++eit
)
{
if (count % 10000 == 0)
{
Info<< count << " edges, inserted " << verts.size()
<< " Time = " << mesh_.time().elapsedCpuTime()
<< endl;
}
count++;
CellSizeDelaunay::Cell_handle c = eit->first;
CellSizeDelaunay::Vertex_handle vA = c->vertex(eit->second);
CellSizeDelaunay::Vertex_handle vB = c->vertex(eit->third);
if
(
mesh_.is_infinite(vA)
|| mesh_.is_infinite(vB)
|| (vA->referred() && vB->referred())
|| (vA->referred() && (vA->procIndex() > vB->procIndex()))
|| (vB->referred() && (vB->procIndex() > vA->procIndex()))
)
{
continue;
}
pointFromPoint ptA(topoint(vA->point()));
pointFromPoint ptB(topoint(vB->point()));
linePointRef l(ptA, ptB);
const pointHit hitPt = findDiscontinuities(l);
if (hitPt.hit())
{
const Foam::point& pt = hitPt.hitPoint();
if (!geometryToConformTo_.inside(pt))
{
continue;
}
if (Pstream::parRun())
{
if (!decomposition().positionOnThisProcessor(pt))
{
continue;
}
}
verts.append
(
Vb
(
toPoint<cellShapeControlMesh::Point>(pt),
Vb::vtInternal
)
);
verts.last().targetCellSize() = sizeControls_.cellSize(pt);
verts.last().alignment() = triad::unset;
}
}
mesh_.insertPoints(verts);
return verts.size();
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::controlMeshRefinement
Description
SourceFiles
controlMeshRefinementI.H
controlMeshRefinement.C
controlMeshRefinementIO.C
\*---------------------------------------------------------------------------*/
#ifndef controlMeshRefinement_H
#define controlMeshRefinement_H
#include "cellShapeControl.H"
#include "cellShapeControlMesh.H"
#include "cellSizeAndAlignmentControls.H"
#include "conformationSurfaces.H"
#include "backgroundMeshDecomposition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class controlMeshRefinement Declaration
\*---------------------------------------------------------------------------*/
class controlMeshRefinement
{
// Private data
const cellShapeControl& shapeController_;
cellShapeControlMesh& mesh_;
const cellSizeAndAlignmentControls& sizeControls_;
const conformationSurfaces& geometryToConformTo_;
// Private Member Functions
scalar calcFirstDerivative
(
const Foam::point& a,
const scalar& cellSizeA,
const Foam::point& b,
const scalar& cellSizeB
) const;
scalar calcSecondDerivative
(
const Foam::point& a,
const scalar& cellSizeA,
const Foam::point& midPoint,
const scalar& cellSizeMid,
const Foam::point& b,
const scalar& cellSizeB
) const
{
return (cellSizeA - 2*cellSizeMid + cellSizeB)/magSqr((a - b)/2);
}
bool detectEdge
(
const Foam::point& startPt,
const Foam::point& endPt,
pointHit& pointFound,
const scalar tolSqr,
const scalar secondDerivTolSqr
) const;
pointHit findDiscontinuities(const linePointRef& l) const;
//- Disallow default bitwise copy construct
controlMeshRefinement(const controlMeshRefinement&);
//- Disallow default bitwise assignment
void operator=(const controlMeshRefinement&);
public:
//- Runtime type information
ClassName("controlMeshRefinement");
// Constructors
//- Construct null
controlMeshRefinement(cellShapeControl& shapeController);
//- Destructor
~controlMeshRefinement();
// Member Functions
// Edit
void initialMeshPopulation
(
const autoPtr<backgroundMeshDecomposition>& decomposition
);
label refineMesh
(
const autoPtr<backgroundMeshDecomposition>& decomposition
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,480 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "smoothAlignmentSolver.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Triangulation, class Type>
Foam::tmp<Foam::Field<Type> > Foam::smoothAlignmentSolver::filterFarPoints
(
const Triangulation& mesh,
const Field<Type>& field
)
{
tmp<Field<Type> > tNewField(new Field<Type>(field.size()));
Field<Type>& newField = tNewField();
label added = 0;
label count = 0;
for
(
typename Triangulation::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (vit->real())
{
newField[added++] = field[count];
}
count++;
}
newField.resize(added);
return tNewField;
}
template<class Triangulation>
Foam::autoPtr<Foam::mapDistribute> Foam::smoothAlignmentSolver::buildReferredMap
(
const Triangulation& mesh,
labelList& indices
)
{
globalIndex globalIndexing(mesh.vertexCount());
DynamicList<label> dynIndices(mesh.vertexCount()/10);
for
(
typename Triangulation::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (vit->referred())
{
dynIndices.append
(
globalIndexing.toGlobal(vit->procIndex(), vit->index())
);
}
}
indices.transfer(dynIndices);
List<Map<label> > compactMap;
return autoPtr<mapDistribute>
(
new mapDistribute
(
globalIndexing,
indices,
compactMap
)
);
}
template<class Triangulation>
Foam::autoPtr<Foam::mapDistribute> Foam::smoothAlignmentSolver::buildMap
(
const Triangulation& mesh,
labelListList& pointPoints
)
{
pointPoints.setSize(mesh.vertexCount());
globalIndex globalIndexing(mesh.vertexCount());
for
(
typename Triangulation::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (!vit->real())
{
continue;
}
std::list<typename Triangulation::Vertex_handle> adjVerts;
mesh.finite_adjacent_vertices(vit, std::back_inserter(adjVerts));
DynamicList<label> indices(adjVerts.size());
for
(
typename std::list<typename Triangulation::Vertex_handle>::
const_iterator adjVertI = adjVerts.begin();
adjVertI != adjVerts.end();
++adjVertI
)
{
typename Triangulation::Vertex_handle vh = *adjVertI;
if (!vh->farPoint())
{
indices.append
(
globalIndexing.toGlobal(vh->procIndex(), vh->index())
);
}
}
pointPoints[vit->index()].transfer(indices);
}
List<Map<label> > compactMap;
return autoPtr<mapDistribute>
(
new mapDistribute
(
globalIndexing,
pointPoints,
compactMap
)
);
}
template<class Triangulation>
Foam::tmp<Foam::triadField> Foam::smoothAlignmentSolver::buildAlignmentField
(
const Triangulation& mesh
)
{
tmp<triadField> tAlignments
(
new triadField(mesh.vertexCount(), triad::unset)
);
triadField& alignments = tAlignments();
for
(
typename Triangulation::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (!vit->real())
{
continue;
}
alignments[vit->index()] = vit->alignment();
}
return tAlignments;
}
template<class Triangulation>
Foam::tmp<Foam::pointField> Foam::smoothAlignmentSolver::buildPointField
(
const Triangulation& mesh
)
{
tmp<pointField> tPoints
(
new pointField(mesh.vertexCount(), point(GREAT, GREAT, GREAT))
);
pointField& points = tPoints();
for
(
typename Triangulation::Finite_vertices_iterator vit =
mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
if (!vit->real())
{
continue;
}
points[vit->index()] = topoint(vit->point());
}
return tPoints;
}
void Foam::smoothAlignmentSolver::applyBoundaryConditions
(
const triad& fixedAlignment,
triad& t
) const
{
label nFixed = 0;
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
nFixed++;
}
}
if (nFixed == 1)
{
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
t.align(fixedAlignment[dirI]);
}
}
}
else if (nFixed == 2)
{
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
t[dirI] = fixedAlignment[dirI];
}
else
{
t[dirI] = triad::unset[dirI];
}
}
t.orthogonalize();
}
else if (nFixed == 3)
{
forAll(fixedAlignment, dirI)
{
if (fixedAlignment.set(dirI))
{
t[dirI] = fixedAlignment[dirI];
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::smoothAlignmentSolver::smoothAlignmentSolver(cellShapeControlMesh& mesh)
:
mesh_(mesh)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::smoothAlignmentSolver::~smoothAlignmentSolver()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::smoothAlignmentSolver::smoothAlignments
(
const label maxSmoothingIterations
)
{
scalar minResidual = 0;
labelListList pointPoints;
autoPtr<mapDistribute> meshDistributor = buildMap
(
mesh_,
pointPoints
);
triadField alignments(buildAlignmentField(mesh_));
pointField points(buildPointField(mesh_));
// Setup the sizes and alignments on each point
triadField fixedAlignments(mesh_.vertexCount(), triad::unset);
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
mesh_.finite_vertices_begin();
vit != mesh_.finite_vertices_end();
++vit
)
{
if (vit->real())
{
fixedAlignments[vit->index()] = vit->alignment();
}
}
Info<< nl << "Smoothing alignments" << endl;
for (label iter = 0; iter < maxSmoothingIterations; iter++)
{
Info<< "Iteration " << iter;
meshDistributor().distribute(points);
meshDistributor().distribute(fixedAlignments);
meshDistributor().distribute(alignments);
scalar residual = 0;
triadField triadAv(alignments.size(), triad::unset);
forAll(pointPoints, pI)
{
const labelList& pPoints = pointPoints[pI];
if (pPoints.empty())
{
continue;
}
triad& newTriad = triadAv[pI];
forAll(pPoints, adjPointI)
{
const label adjPointIndex = pPoints[adjPointI];
scalar dist = mag(points[pI] - points[adjPointIndex]);
triad tmpTriad = alignments[adjPointIndex];
for (direction dir = 0; dir < 3; dir++)
{
if (tmpTriad.set(dir))
{
tmpTriad[dir] *= 1.0/(dist + SMALL);
}
}
newTriad += tmpTriad;
}
}
// Update the alignment field
forAll(alignments, pI)
{
const triad& oldTriad = alignments[pI];
triad& newTriad = triadAv[pI];
newTriad.normalize();
newTriad.orthogonalize();
// Enforce the boundary conditions
const triad& fixedAlignment = fixedAlignments[pI];
applyBoundaryConditions
(
fixedAlignment,
newTriad
);
newTriad = newTriad.sortxyz();
// Residual Calculation
for (direction dir = 0; dir < 3; ++dir)
{
if
(
newTriad.set(dir)
&& oldTriad.set(dir)
&& !fixedAlignment.set(dir)
)
{
residual += diff(oldTriad, newTriad);
}
}
alignments[pI] = newTriad;
}
reduce(residual, sumOp<scalar>());
Info<< ", Residual = "
<< residual
/returnReduce(points.size(), sumOp<label>())
<< endl;
if (iter > 0 && residual <= minResidual)
{
break;
}
}
meshDistributor().distribute(alignments);
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
mesh_.finite_vertices_begin();
vit != mesh_.finite_vertices_end();
++vit
)
{
if (vit->real())
{
vit->alignment() = alignments[vit->index()];
}
}
labelList referredPoints;
autoPtr<mapDistribute> referredDistributor = buildReferredMap
(
mesh_,
referredPoints
);
alignments.setSize(mesh_.vertexCount());
referredDistributor().distribute(alignments);
label referredI = 0;
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
mesh_.finite_vertices_begin();
vit != mesh_.finite_vertices_end();
++vit
)
{
if (vit->referred())
{
vit->alignment() = alignments[referredPoints[referredI++]];
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::smoothAlignmentSolver
Description
SourceFiles
smoothAlignmentSolverI.H
smoothAlignmentSolver.C
smoothAlignmentSolverIO.C
\*---------------------------------------------------------------------------*/
#ifndef smoothAlignmentSolver_H
#define smoothAlignmentSolver_H
#include "cellShapeControlMesh.H"
#include "triadField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class smoothAlignmentSolver Declaration
\*---------------------------------------------------------------------------*/
class smoothAlignmentSolver
{
// Private data
cellShapeControlMesh& mesh_;
// Private Member Functions
template<class Triangulation, class Type>
tmp<Field<Type> > filterFarPoints
(
const Triangulation& mesh,
const Field<Type>& field
);
template<class Triangulation>
autoPtr<mapDistribute> buildMap
(
const Triangulation& mesh,
labelListList& pointPoints
);
template<class Triangulation>
autoPtr<mapDistribute> buildReferredMap
(
const Triangulation& mesh,
labelList& indices
);
template<class Triangulation>
tmp<triadField> buildAlignmentField(const Triangulation& mesh);
template<class Triangulation>
tmp<pointField> buildPointField(const Triangulation& mesh);
//- Apply the fixed alignments to the triad
void applyBoundaryConditions
(
const triad& fixedAlignment,
triad& t
) const;
//- Disallow default bitwise copy construct
smoothAlignmentSolver(const smoothAlignmentSolver&);
//- Disallow default bitwise assignment
void operator=(const smoothAlignmentSolver&);
public:
// Constructors
//- Construct null
smoothAlignmentSolver(cellShapeControlMesh& mesh);
//- Destructor
~smoothAlignmentSolver();
// Member Functions
// Edit
//- Smooth the alignments on the mesh
void smoothAlignments(const label maxSmoothingIterations);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,169 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellSizeFunction.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellSizeFunction, 0);
defineRunTimeSelectionTable(cellSizeFunction, dictionary);
scalar cellSizeFunction::snapToSurfaceTol_ = 1e-10;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellSizeFunction::cellSizeFunction
(
const word& type,
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
:
dictionary(cellSizeFunctionDict),
surface_(surface),
surfaceCellSizeFunction_
(
surfaceCellSizeFunction::New
(
cellSizeFunctionDict,
surface,
defaultCellSize
)
),
coeffsDict_(subDict(type + "Coeffs")),
defaultCellSize_(defaultCellSize),
regionIndices_(regionIndices),
sideMode_(),
priority_(readLabel(cellSizeFunctionDict.lookup("priority", true)))
{
word mode = cellSizeFunctionDict.lookup("mode", true);
if (surface_.hasVolumeType())
{
if (mode == "inside")
{
sideMode_ = smInside;
}
else if (mode == "outside")
{
sideMode_ = smOutside;
}
else if (mode == "bothSides")
{
sideMode_ = rmBothsides;
}
else
{
FatalErrorIn("searchableSurfaceControl::searchableSurfaceControl")
<< "Unknown mode, expected: inside, outside or bothSides" << nl
<< exit(FatalError);
}
}
else
{
if (mode != "bothSides")
{
WarningIn("searchableSurfaceControl::searchableSurfaceControl")
<< "surface does not support volumeType, defaulting mode to "
<< "bothSides."
<< endl;
}
sideMode_ = rmBothsides;
}
if (debug)
{
Info<< nl
<< "Cell size function for surface " << surface.name()
<< ", " << mode
<< ", priority = " << priority_
<< ", regions = " << regionIndices_
<< endl;
}
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cellSizeFunction> Foam::cellSizeFunction::New
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
{
word cellSizeFunctionTypeName
(
cellSizeFunctionDict.lookup("cellSizeFunction")
);
Info<< indent << "Selecting cellSizeFunction " << cellSizeFunctionTypeName
<< endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(cellSizeFunctionTypeName);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"cellSizeFunction::New(dictionary&, "
"const conformalVoronoiMesh&, const searchableSurface&)"
) << "Unknown cellSizeFunction type "
<< cellSizeFunctionTypeName
<< endl << endl
<< "Valid cellSizeFunction types are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<cellSizeFunction>
(
cstrIter()
(
cellSizeFunctionDict,
surface,
defaultCellSize,
regionIndices
)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellSizeFunction::~cellSizeFunction()
{}
// ************************************************************************* //

View File

@ -0,0 +1,221 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellSizeFunction
Description
Abstract base class for specifying target cell sizes
SourceFiles
cellSizeFunction.C
\*---------------------------------------------------------------------------*/
#ifndef cellSizeFunction_H
#define cellSizeFunction_H
#include "point.H"
#include "conformalVoronoiMesh.H"
#include "searchableSurface.H"
#include "dictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "surfaceCellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSizeFunction Declaration
\*---------------------------------------------------------------------------*/
class cellSizeFunction
:
public dictionary
{
public:
//- Surface side mode
enum sideMode
{
smInside, // Control inside the surface
smOutside, // Control outside the surface
rmBothsides // Control on both sides of a surface
};
//- Runtime type information
TypeName("cellSizeFunction");
protected:
// Static data
//- Point closeness tolerance to a surface where the function "snaps" to
// including the surface
static scalar snapToSurfaceTol_;
// Protected data
//- Reference to the searchableSurface that cellSizeFunction
// relates to
const searchableSurface& surface_;
//- Cell size at the surface
scalarField surfaceCellSize_;
autoPtr<surfaceCellSizeFunction> surfaceCellSizeFunction_;
//- Method details dictionary
dictionary coeffsDict_;
const scalar& defaultCellSize_;
//- Index of the region of the surface that this cell size function
// applies to
const labelList regionIndices_;
//- Mode of size specification, i.e. inside, outside or bothSides
sideMode sideMode_;
label priority_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
cellSizeFunction(const cellSizeFunction&);
//- Disallow default bitwise assignment
void operator=(const cellSizeFunction&);
public:
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
cellSizeFunction,
dictionary,
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
),
(cellSizeFunctionDict, surface, defaultCellSize, regionIndices)
);
// Constructors
//- Construct from components
cellSizeFunction
(
const word& type,
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
// Selectors
//- Return a reference to the selected cellSizeFunction
static autoPtr<cellSizeFunction> New
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
//- Destructor
virtual ~cellSizeFunction();
// Member Functions
//- Const access to the details dictionary
inline const dictionary& coeffsDict() const
{
return coeffsDict_;
}
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const = 0;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying
// size.
virtual bool cellSize
(
const point& pt,
scalar& size
) const = 0;
virtual bool setCellSize
(
const pointField& pts
)
{
WarningIn("cellSizeFunction::setCellSize(const pointField&)")
<< "Not overloaded."
<< endl;
return false;
}
label priority() const
{
return priority_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,256 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "linearDistance.H"
#include "addToRunTimeSelectionTable.H"
#include "triSurfaceMesh.H"
#include "triSurfaceFields.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(linearDistance, 0);
addToRunTimeSelectionTable(cellSizeFunction, linearDistance, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
linearDistance::linearDistance
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
:
cellSizeFunction
(
typeName,
initialPointsDict,
surface,
defaultCellSize,
regionIndices
),
distanceCellSize_
(
readScalar(coeffsDict().lookup("distanceCellSizeCoeff"))
*defaultCellSize
),
distance_
(
readScalar(coeffsDict().lookup("distanceCoeff"))*defaultCellSize
),
distanceSqr_(sqr(distance_))
{}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
scalar linearDistance::sizeFunction
(
const point& pt,
scalar d,
label index
) const
{
const scalar interpolatedSize
= surfaceCellSizeFunction_().interpolate(pt, index);
scalar gradient
= (distanceCellSize_ - interpolatedSize)
/distance_;
scalar size = gradient*d + interpolatedSize;
return size;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool linearDistance::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
const Foam::point& pt = hitPt.hitPoint();
if (sideMode_ == rmBothsides)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize_;
shapePts[1] = pt + n*distance_;
shapeSizes[1] = distanceCellSize_;
}
else if (sideMode_ == smInside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize_;
}
else if (sideMode_ == smOutside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt + n*distance_;
shapeSizes[0] = distanceCellSize_;
}
return false;
}
bool linearDistance::cellSize(const point& pt, scalar& size) const
{
size = 0;
List<pointIndexHit> hits;
surface_.findNearest
(
pointField(1, pt),
scalarField(1, distanceSqr_),
regionIndices_,
hits
);
const pointIndexHit& hitInfo = hits[0];
if (hitInfo.hit())
{
const point& hitPt = hitInfo.hitPoint();
const label hitIndex = hitInfo.index();
const scalar dist = mag(pt - hitPt);
if (sideMode_ == rmBothsides)
{
size = sizeFunction(hitPt, dist, hitIndex);
return true;
}
// If the nearest point is essentially on the surface, do not do a
// getVolumeType calculation, as it will be prone to error.
if (dist < snapToSurfaceTol_)
{
size = sizeFunction(hitPt, 0, hitIndex);
return true;
}
pointField ptF(1, pt);
List<volumeType> vTL;
surface_.getVolumeType(ptF, vTL);
bool functionApplied = false;
if
(
sideMode_ == smInside
&& vTL[0] == volumeType::INSIDE
)
{
size = sizeFunction(hitPt, dist, hitIndex);
functionApplied = true;
}
else if
(
sideMode_ == smOutside
&& vTL[0] == volumeType::OUTSIDE
)
{
size = sizeFunction(hitPt, dist, hitIndex);
functionApplied = true;
}
return functionApplied;
}
return false;
}
bool linearDistance::setCellSize(const pointField& pts)
{
// labelHashSet surfaceAlreadyHit(surfaceCellSize_.size());
// forAll(pts, ptI)
// {
// const Foam::point& pt = pts[ptI];
// List<pointIndexHit> hits;
// surface_.findNearest
// (
// pointField(1, pt),
// scalarField(1, distanceSqr_),
// regionIndices_,
// hits
// );
// const label surfHitI = hits[0].index();
// if
// (
// hits[0].hit()
// && !surfaceAlreadyHit.found(surfHitI)
// )
// {
// // Halving cell size is arbitrary
// surfaceCellSizeFunction_().refineSurfaceSize(surfHitI);
// surfaceAlreadyHit.insert(surfHitI);
// }
// }
// return true;
return false;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::linearDistance
Description
SourceFiles
linearDistance.C
\*---------------------------------------------------------------------------*/
#ifndef linearDistance_H
#define linearDistance_H
#include "cellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class linearDistance Declaration
\*---------------------------------------------------------------------------*/
class linearDistance
:
public cellSizeFunction
{
private:
// Private data
//- cell size at distance_ from the surface
scalar distanceCellSize_;
//- distance from the surface to control over
scalar distance_;
//- distance squared
scalar distanceSqr_;
// Private Member Functions
//- Calculate the cell size as a function of the given distance
scalar sizeFunction(const point& pt, scalar d, label index) const;
public:
//- Runtime type information
TypeName("linearDistance");
// Constructors
//- Construct from components
linearDistance
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
//- Destructor
virtual ~linearDistance()
{}
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying
// size.
virtual bool cellSize
(
const point& pt,
scalar& size
) const;
//- Adapt local cell size. Return true if anything changed.
virtual bool setCellSize
(
const pointField& pts
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "linearSpatial.H"
#include "addToRunTimeSelectionTable.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(linearSpatial, 0);
addToRunTimeSelectionTable(cellSizeFunction, linearSpatial, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
linearSpatial::linearSpatial
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
:
cellSizeFunction
(
typeName,
initialPointsDict,
surface,
defaultCellSize,
regionIndices
),
referencePoint_(coeffsDict().lookup("referencePoint")),
referenceCellSize_
(
readScalar(coeffsDict().lookup("referenceCellSizeCoeff"))
*defaultCellSize
),
direction_(coeffsDict().lookup("direction")),
cellSizeGradient_(readScalar(coeffsDict().lookup("cellSizeGradient")))
{
direction_ /= mag(direction_);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
scalar linearSpatial::sizeFunction(const point& pt) const
{
return
referenceCellSize_
+ ((pt - referencePoint_) & direction_)*cellSizeGradient_;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool linearSpatial::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
if (sideMode_ == rmBothsides)
{
}
else if (sideMode_ == smInside)
{
}
else if (sideMode_ == smOutside)
{
}
return false;
}
bool linearSpatial::cellSize
(
const point& pt,
scalar& size
) const
{
if (sideMode_ == rmBothsides)
{
size = sizeFunction(pt);
return true;
}
size = 0;
List<pointIndexHit> hits;
surface_.findNearest
(
pointField(1, pt),
scalarField(1, sqr(snapToSurfaceTol_)),
regionIndices_,
hits
);
const pointIndexHit& hitInfo = hits[0];
// If the nearest point is essentially on the surface, do not do a
// getVolumeType calculation, as it will be prone to error.
if (hitInfo.hit())
{
size = sizeFunction(pt);
return true;
}
pointField ptF(1, pt);
List<volumeType> vTL;
surface_.getVolumeType(ptF, vTL);
bool functionApplied = false;
if
(
sideMode_ == smInside
&& vTL[0] == volumeType::INSIDE
)
{
size = sizeFunction(pt);
functionApplied = true;
}
else if
(
sideMode_ == smOutside
&& vTL[0] == volumeType::OUTSIDE
)
{
size = sizeFunction(pt);
functionApplied = true;
}
return functionApplied;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::linearSpatial
Description
SourceFiles
linearSpatial.C
\*---------------------------------------------------------------------------*/
#ifndef linearSpatial_H
#define linearSpatial_H
#include "cellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class linearSpatial Declaration
\*---------------------------------------------------------------------------*/
class linearSpatial
:
public cellSizeFunction
{
private:
// Private data
//- Reference point for spatial size grading
point referencePoint_;
//- Cell size at reference point
scalar referenceCellSize_;
//- Direction of cell size grading, stored as unit vector, may be
// supplied with any magnitude
vector direction_;
//- Gradient of cell size change in direction of direction_
scalar cellSizeGradient_;
// Private Member Functions
//- Calculate the cell size as a function of the given position
scalar sizeFunction(const point& pt) const;
public:
//- Runtime type information
TypeName("linearSpatial");
// Constructors
//- Construct from components
linearSpatial
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
//- Destructor
virtual ~linearSpatial()
{}
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying
// size.
virtual bool cellSize
(
const point& pt,
scalar& size
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,298 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "surfaceOffsetLinearDistance.H"
#include "addToRunTimeSelectionTable.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(surfaceOffsetLinearDistance, 0);
addToRunTimeSelectionTable
(
cellSizeFunction,
surfaceOffsetLinearDistance,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
surfaceOffsetLinearDistance::surfaceOffsetLinearDistance
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
:
cellSizeFunction
(
typeName,
initialPointsDict,
surface,
defaultCellSize,
regionIndices
),
distanceCellSize_
(
readScalar(coeffsDict().lookup("distanceCellSizeCoeff"))
*defaultCellSize
),
surfaceOffset_
(
readScalar(coeffsDict().lookup("surfaceOffsetCoeff"))*defaultCellSize
),
totalDistance_(),
totalDistanceSqr_()
{
if
(
coeffsDict().found("totalDistanceCoeff")
|| coeffsDict().found("linearDistanceCoeff")
)
{
if
(
coeffsDict().found("totalDistanceCoeff")
&& coeffsDict().found("linearDistanceCoeff")
)
{
FatalErrorIn
(
"surfaceOffsetLinearDistance::surfaceOffsetLinearDistance"
"("
" const dictionary& initialPointsDict,"
" const searchableSurface& surface,"
" const scalar& defaultCellSize"
")"
)
<< "totalDistanceCoeff and linearDistanceCoeff found, "
<< "specify one or other, not both."
<< nl << exit(FatalError) << endl;
}
if (coeffsDict().found("totalDistanceCoeff"))
{
totalDistance_ =
readScalar(coeffsDict().lookup("totalDistanceCoeff"))
*defaultCellSize;
}
else
{
totalDistance_ =
readScalar(coeffsDict().lookup("linearDistanceCoeff"))
*defaultCellSize
+ surfaceOffset_;
}
}
else
{
FatalErrorIn
(
"surfaceOffsetLinearDistance::surfaceOffsetLinearDistance"
"("
" const dictionary& initialPointsDict,"
" const searchableSurface& surface,"
" const scalar& defaultCellSize"
")"
)
<< "totalDistanceCoeff or linearDistanceCoeff not found."
<< nl << exit(FatalError) << endl;
}
totalDistanceSqr_ = sqr(totalDistance_);
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
scalar surfaceOffsetLinearDistance::sizeFunction
(
const point& pt,
scalar d,
label index
) const
{
const scalar interpolatedSize
= surfaceCellSizeFunction_().interpolate(pt, index);
if (d <= surfaceOffset_)
{
return interpolatedSize;
}
scalar gradient =
(distanceCellSize_ - interpolatedSize)
/(totalDistance_ - surfaceOffset_);
scalar intercept = interpolatedSize - gradient*surfaceOffset_;
return gradient*d + intercept;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool surfaceOffsetLinearDistance::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
const Foam::point& pt = hitPt.hitPoint();
const scalar offsetCellSize =
surfaceCellSizeFunction_().interpolate(pt, hitPt.index());
if (sideMode_ == rmBothsides)
{
shapePts.resize(4);
shapeSizes.resize(4);
shapePts[0] = pt - n*surfaceOffset_;
shapeSizes[0] = offsetCellSize;
shapePts[1] = pt - n*totalDistance_;
shapeSizes[1] = distanceCellSize_;
shapePts[2] = pt + n*surfaceOffset_;
shapeSizes[2] = offsetCellSize;
shapePts[3] = pt + n*totalDistance_;
shapeSizes[3] = distanceCellSize_;
}
else if (sideMode_ == smInside)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt - n*surfaceOffset_;
shapeSizes[0] = offsetCellSize;
shapePts[1] = pt - n*totalDistance_;
shapeSizes[1] = distanceCellSize_;
}
else if (sideMode_ == smOutside)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt + n*surfaceOffset_;
shapeSizes[0] = offsetCellSize;
shapePts[1] = pt + n*totalDistance_;
shapeSizes[1] = distanceCellSize_;
}
return true;
}
bool surfaceOffsetLinearDistance::cellSize
(
const point& pt,
scalar& size
) const
{
size = 0;
List<pointIndexHit> hits;
surface_.findNearest
(
pointField(1, pt),
scalarField(1, totalDistanceSqr_),
regionIndices_,
hits
);
const pointIndexHit& hitInfo = hits[0];
if (hitInfo.hit())
{
const point& hitPt = hitInfo.hitPoint();
const label hitIndex = hitInfo.index();
const scalar dist = mag(pt - hitPt);
if (sideMode_ == rmBothsides)
{
size = sizeFunction(hitPt, dist, hitIndex);
return true;
}
// If the nearest point is essentially on the surface, do not do a
// getVolumeType calculation, as it will be prone to error.
if (mag(pt - hitInfo.hitPoint()) < snapToSurfaceTol_)
{
size = sizeFunction(hitPt, 0, hitIndex);
return true;
}
pointField ptF(1, pt);
List<volumeType> vTL;
surface_.getVolumeType(ptF, vTL);
bool functionApplied = false;
if
(
sideMode_ == smInside
&& vTL[0] == volumeType::INSIDE
)
{
size = sizeFunction(hitPt, dist, hitIndex);
functionApplied = true;
}
else if
(
sideMode_ == smOutside
&& vTL[0] == volumeType::OUTSIDE
)
{
size = sizeFunction(hitPt, dist, hitIndex);
functionApplied = true;
}
return functionApplied;
}
return false;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::surfaceOffsetLinearDistance
Description
SourceFiles
surfaceOffsetLinearDistance.C
\*---------------------------------------------------------------------------*/
#ifndef surfaceOffsetLinearDistance_H
#define surfaceOffsetLinearDistance_H
#include "cellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class surfaceOffsetLinearDistance Declaration
\*---------------------------------------------------------------------------*/
class surfaceOffsetLinearDistance
:
public cellSizeFunction
{
private:
// Private data
//- cell size at distance_ from the surface
scalar distanceCellSize_;
//- Offset distance from surface for constant size portion
scalar surfaceOffset_;
//- Total distance from the surface to control over (distance +
// surfaceOffset)
scalar totalDistance_;
//- totalDistance squared
scalar totalDistanceSqr_;
// Private Member Functions
//- Calculate the cell size as a function of the given distance
scalar sizeFunction(const point& pt, scalar d, label index) const;
public:
//- Runtime type information
TypeName("surfaceOffsetLinearDistance");
// Constructors
//- Construct from components
surfaceOffsetLinearDistance
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
//- Destructor
virtual ~surfaceOffsetLinearDistance()
{}
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying
// size.
virtual bool cellSize
(
const point& pt,
scalar& size
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "uniform.H"
#include "addToRunTimeSelectionTable.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(uniform, 0);
addToRunTimeSelectionTable(cellSizeFunction, uniform, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
uniform::uniform
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
:
cellSizeFunction
(
typeName,
initialPointsDict,
surface,
defaultCellSize,
regionIndices
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool uniform::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
shapePts.setSize(0);
shapeSizes.setSize(0);
return true;
}
bool uniform::cellSize
(
const point& pt,
scalar& size
) const
{
List<pointIndexHit> hits;
surface_.findNearest
(
pointField(1, pt),
scalarField(1, sqr(GREAT)),
regionIndices_,
hits
);
const pointIndexHit& hitInfo = hits[0];
if (hitInfo.hit())
{
const point& hitPt = hitInfo.hitPoint();
const label index = hitInfo.index();
if (sideMode_ == rmBothsides)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
return true;
}
size = 0;
List<pointIndexHit> closeToSurfaceHits;
surface_.findNearest
(
pointField(1, pt),
scalarField(1, sqr(snapToSurfaceTol_)),
regionIndices_,
closeToSurfaceHits
);
const pointIndexHit& closeToSurface = closeToSurfaceHits[0];
// If the nearest point is essentially on the surface, do not do a
// getVolumeType calculation, as it will be prone to error.
if (closeToSurface.hit())
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
return true;
}
pointField ptF(1, pt);
List<volumeType> vTL(1);
surface_.getVolumeType(ptF, vTL);
bool functionApplied = false;
if
(
sideMode_ == smInside
&& vTL[0] == volumeType::INSIDE
)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
functionApplied = true;
}
else if
(
sideMode_ == smOutside
&& vTL[0] == volumeType::OUTSIDE
)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
functionApplied = true;
}
return functionApplied;
}
return false;
}
bool uniform::setCellSize
(
const pointField& pts
)
{
// labelHashSet surfaceAlreadyHit(cellSize_.size());
//
// forAll(pts, ptI)
// {
// const Foam::point& pt = pts[ptI];
//
// List<pointIndexHit> hits;
//
// surface_.findNearest
// (
// pointField(1, pt),
// scalarField(1, sqr(GREAT)),
// hits
// );
//
// if (hits[0].hit() && !surfaceAlreadyHit.found(hits[0].index()))
// {
// surfaceCellSizeFunction_().refineCellSize(hits[0].index());
//
// surfaceAlreadyHit.insert(hits[0].index());
// }
// }
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::uniform
Description
SourceFiles
uniform.C
\*---------------------------------------------------------------------------*/
#ifndef uniform_H
#define uniform_H
#include "cellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class uniform Declaration
\*---------------------------------------------------------------------------*/
class uniform
:
public cellSizeFunction
{
private:
// Private data
public:
//- Runtime type information
TypeName("uniform");
// Constructors
//- Construct from components
uniform
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
//- Destructor
virtual ~uniform()
{}
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying
// size.
virtual bool cellSize
(
const point& pt,
scalar& size
) const;
//- Adapt local cell size. Return true if anything changed.
virtual bool setCellSize
(
const pointField& pts
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,229 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "uniformDistance.H"
#include "addToRunTimeSelectionTable.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(uniformDistance, 0);
addToRunTimeSelectionTable(cellSizeFunction, uniformDistance, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
uniformDistance::uniformDistance
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
)
:
cellSizeFunction
(
typeName,
initialPointsDict,
surface,
defaultCellSize,
regionIndices
),
distance_
(
readScalar(coeffsDict().lookup("distanceCoeff"))*defaultCellSize
),
distanceSqr_(sqr(distance_))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool uniformDistance::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
const Foam::point& pt = hitPt.hitPoint();
const scalar distanceCellSize =
surfaceCellSizeFunction_().interpolate(pt, hitPt.index());
if (sideMode_ == rmBothsides)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize;
shapePts[1] = pt + n*distance_;
shapeSizes[1] = distanceCellSize;
}
else if (sideMode_ == smInside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize;
}
else if (sideMode_ == smOutside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize;
}
return false;
}
bool uniformDistance::cellSize
(
const point& pt,
scalar& size
) const
{
size = 0;
List<pointIndexHit> hits;
surface_.findNearest
(
pointField(1, pt),
scalarField(1, distanceSqr_),
regionIndices_,
hits
);
const pointIndexHit& hitInfo = hits[0];
if (hitInfo.hit())
{
const point& hitPt = hitInfo.hitPoint();
const label index = hitInfo.index();
if (sideMode_ == rmBothsides)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
return true;
}
// If the nearest point is essentially on the surface, do not do a
// getVolumeType calculation, as it will be prone to error.
if (mag(pt - hitInfo.hitPoint()) < snapToSurfaceTol_)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
return true;
}
pointField ptF(1, pt);
List<volumeType> vTL;
surface_.getVolumeType(ptF, vTL);
bool functionApplied = false;
if
(
sideMode_ == smInside
&& vTL[0] == volumeType::INSIDE
)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
functionApplied = true;
}
else if
(
sideMode_ == smOutside
&& vTL[0] == volumeType::OUTSIDE
)
{
size = surfaceCellSizeFunction_().interpolate(hitPt, index);
functionApplied = true;
}
return functionApplied;
}
return false;
}
bool uniformDistance::setCellSize
(
const pointField& pts
)
{
// labelHashSet surfaceAlreadyHit(surface_.size());
//
// forAll(pts, ptI)
// {
// const Foam::point& pt = pts[ptI];
//
// List<pointIndexHit> hits;
//
// surface_.findNearest
// (
// pointField(1, pt),
// scalarField(1, distanceSqr_),
// regionIndices_,
// hits
// );
//
// if (hits[0].hit() && !surfaceAlreadyHit.found(hits[0].index()))
// {
// surfaceCellSizeFunction_().refineSurfaceSize(hits[0].index());
//
// surfaceAlreadyHit.insert(hits[0].index());
// }
// }
//
// return true;
return false;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::uniformDistance
Description
SourceFiles
uniformDistance.C
\*---------------------------------------------------------------------------*/
#ifndef uniformDistance_H
#define uniformDistance_H
#include "cellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class uniformDistance Declaration
\*---------------------------------------------------------------------------*/
class uniformDistance
:
public cellSizeFunction
{
private:
// Private data
//- Distance
scalar distance_;
//- Distance squared
scalar distanceSqr_;
public:
//- Runtime type information
TypeName("uniformDistance");
// Constructors
//- Construct from components
uniformDistance
(
const dictionary& initialPointsDict,
const searchableSurface& surface,
const scalar& defaultCellSize,
const labelList regionIndices
);
//- Destructor
virtual ~uniformDistance()
{}
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying
// size.
virtual bool cellSize
(
const point& pt,
scalar& size
) const;
//- Adapt local cell size. Return true if anything changed.
virtual bool setCellSize
(
const pointField& pts
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,301 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "automatic.H"
#include "addToRunTimeSelectionTable.H"
#include "triSurfaceMesh.H"
#include "vtkSurfaceWriter.H"
#include "primitivePatchInterpolation.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(automatic, 0);
addToRunTimeSelectionTable(cellSizeCalculationType, automatic, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::automatic::smoothField(triSurfaceScalarField& surf)
{
label nSmoothingIterations = 10;
for (label iter = 0; iter < nSmoothingIterations; ++iter)
{
const pointField& faceCentres = surface_.faceCentres();
forAll(surf, sI)
{
const labelList& faceFaces = surface_.faceFaces()[sI];
const point& fC = faceCentres[sI];
const scalar value = surf[sI];
scalar newValue = 0;
scalar totalDist = 0;
label nFaces = 0;
forAll(faceFaces, fI)
{
const label faceLabel = faceFaces[fI];
const point& faceCentre = faceCentres[faceLabel];
const scalar faceValue = surf[faceLabel];
const scalar distance = mag(faceCentre - fC);
newValue += faceValue/(distance + SMALL);
totalDist += 1.0/(distance + SMALL);
if (value < faceValue)
{
nFaces++;
}
}
// Do not smooth out the peak values
if (nFaces == faceFaces.size())
{
continue;
}
surf[sI] = newValue/totalDist;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::automatic::automatic
(
const dictionary& cellSizeCalcTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
)
:
cellSizeCalculationType
(
typeName,
cellSizeCalcTypeDict,
surface,
defaultCellSize
),
coeffsDict_(cellSizeCalcTypeDict.subDict(typeName + "Coeffs")),
surfaceName_(surface.searchableSurface::name()),
readCurvature_(Switch(coeffsDict_.lookup("curvature"))),
curvatureFile_(coeffsDict_.lookup("curvatureFile")),
readFeatureProximity_(Switch(coeffsDict_.lookup("featureProximity"))),
featureProximityFile_(coeffsDict_.lookup("featureProximityFile")),
readInternalCloseness_(Switch(coeffsDict_.lookup("internalCloseness"))),
internalClosenessFile_(coeffsDict_.lookup("internalClosenessFile")),
curvatureCellSizeCoeff_
(
readScalar(coeffsDict_.lookup("curvatureCellSizeCoeff"))
),
maximumCellSize_
(
readScalar(coeffsDict_.lookup("maximumCellSizeCoeff"))*defaultCellSize
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::triSurfacePointScalarField> Foam::automatic::load()
{
Info<< indent
<< "Calculating cell size on surface: " << surfaceName_ << endl;
tmp<triSurfacePointScalarField> tPointCellSize
(
new triSurfacePointScalarField
(
IOobject
(
surfaceName_ + ".cellSize",
surface_.searchableSurface::time().constant(),
"triSurface",
surface_.searchableSurface::time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
surface_,
dimLength,
scalarField(surface_.nPoints(), maximumCellSize_)
)
);
triSurfacePointScalarField& pointCellSize = tPointCellSize();
if (readCurvature_)
{
Info<< indent
<< "Reading curvature : " << curvatureFile_ << endl;
triSurfacePointScalarField curvature
(
IOobject
(
curvatureFile_,
surface_.searchableSurface::time().constant(),
"triSurface",
surface_.searchableSurface::time(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
surface_,
dimLength,
true
);
forAll(pointCellSize, pI)
{
pointCellSize[pI] =
min
(
1.0
/max
(
(1.0/curvatureCellSizeCoeff_)*mag(curvature[pI]),
1.0/maximumCellSize_
),
pointCellSize[pI]
);
}
}
PrimitivePatchInterpolation
<
PrimitivePatch<labelledTri, ::Foam::List, pointField, point>
> patchInterpolate(surface_);
const Map<label>& meshPointMap = surface_.meshPointMap();
if (readInternalCloseness_)
{
Info<< indent
<< "Reading internal closeness: " << internalClosenessFile_ << endl;
triSurfaceScalarField internalCloseness
(
IOobject
(
internalClosenessFile_,
surface_.searchableSurface::time().constant(),
"triSurface",
surface_.searchableSurface::time(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
surface_,
dimLength,
true
);
scalarField internalClosenessPointField =
patchInterpolate.faceToPointInterpolate(internalCloseness);
forAll(pointCellSize, pI)
{
pointCellSize[pI] =
min
(
internalClosenessPointField[meshPointMap[pI]],
pointCellSize[pI]
);
}
}
if (readFeatureProximity_)
{
Info<< indent
<< "Reading feature proximity : " << featureProximityFile_ << endl;
triSurfaceScalarField featureProximity
(
IOobject
(
featureProximityFile_,
surface_.searchableSurface::time().constant(),
"triSurface",
surface_.searchableSurface::time(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
surface_,
dimLength,
true
);
scalarField featureProximityPointField =
patchInterpolate.faceToPointInterpolate(featureProximity);
forAll(pointCellSize, pI)
{
pointCellSize[pI] =
min
(
featureProximityPointField[meshPointMap[pI]],
pointCellSize[pI]
);
}
}
//smoothField(surfaceCellSize);
pointCellSize.write();
if (debug)
{
faceList faces(surface_.size());
forAll(surface_, fI)
{
faces[fI] = surface_.triSurface::operator[](fI).triFaceFace();
}
vtkSurfaceWriter().write
(
surface_.searchableSurface::time().constant()/"triSurface",
surfaceName_.lessExt().name(),
surface_.points(),
faces,
"cellSize",
pointCellSize,
true,
true
);
}
return tPointCellSize;
}
// ************************************************************************* //

View File

@ -0,0 +1,127 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::automatic
Description
SourceFiles
automatic.C
\*---------------------------------------------------------------------------*/
#ifndef automatic_H
#define automatic_H
#include "cellSizeCalculationType.H"
#include "triSurfaceFields.H"
#include "PrimitivePatchInterpolation.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class triSurfaceMesh;
/*---------------------------------------------------------------------------*\
Class automatic Declaration
\*---------------------------------------------------------------------------*/
class automatic
:
public cellSizeCalculationType
{
private:
// Private data
//- Dictionary of coefficients for automatic cell sizing
const dictionary& coeffsDict_;
//- Name of the surface. Used to write the cell size field
const fileName surfaceName_;
const Switch readCurvature_;
const word curvatureFile_;
const Switch readFeatureProximity_;
const word featureProximityFile_;
const Switch readInternalCloseness_;
const word internalClosenessFile_;
//- The curvature values are multiplied by the inverse of this value to
// get the cell size
const scalar curvatureCellSizeCoeff_;
//- The maximum allowable sell size
const scalar maximumCellSize_;
// Private Member Functions
void smoothField(triSurfaceScalarField& surf);
public:
//- Runtime type information
TypeName("automatic");
// Constructors
//- Construct from components
automatic
(
const dictionary& cellSizeCalcTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
);
//- Destructor
virtual ~automatic()
{}
// Member Functions
//- Load the cell size field
virtual tmp<triSurfacePointScalarField> load();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cellSizeCalculationType.H"
#include "addToRunTimeSelectionTable.H"
#include "triSurfaceMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cellSizeCalculationType, 0);
defineRunTimeSelectionTable(cellSizeCalculationType, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellSizeCalculationType::cellSizeCalculationType
(
const word& type,
const dictionary& cellSizeCalculationTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
)
:
cellSizeCalculationTypeDict_(cellSizeCalculationTypeDict),
surface_(surface),
defaultCellSize_(defaultCellSize)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cellSizeCalculationType> Foam::cellSizeCalculationType::New
(
const dictionary& cellSizeCalculationTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
)
{
word cellSizeCalculationTypeTypeName
(
cellSizeCalculationTypeDict.lookup("cellSizeCalculationType")
);
Info<< indent << "Selecting cellSizeCalculationType "
<< cellSizeCalculationTypeTypeName << endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(cellSizeCalculationTypeTypeName);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"cellSizeCalculationType::New(dictionary&, "
"const conformalVoronoiMesh&, const searchableSurface&)"
) << "Unknown cellSizeCalculationType type "
<< cellSizeCalculationTypeTypeName
<< endl << endl
<< "Valid cellSizeCalculationType types are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<cellSizeCalculationType>
(
cstrIter()(cellSizeCalculationTypeDict, surface, defaultCellSize)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellSizeCalculationType::~cellSizeCalculationType()
{}
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellSizeCalculationType
Description
Abstract base class for specifying target cell sizes
SourceFiles
cellSizeCalculationType.C
\*---------------------------------------------------------------------------*/
#ifndef cellSizeCalculationType_H
#define cellSizeCalculationType_H
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "triSurfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class triSurfaceMesh;
/*---------------------------------------------------------------------------*\
Class cellSizeCalculationType Declaration
\*---------------------------------------------------------------------------*/
class cellSizeCalculationType
{
protected:
const dictionary& cellSizeCalculationTypeDict_;
//- Reference to the triSurfaceMesh
const triSurfaceMesh& surface_;
const scalar& defaultCellSize_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
cellSizeCalculationType(const cellSizeCalculationType&);
//- Disallow default bitwise assignment
void operator=(const cellSizeCalculationType&);
public:
//- Runtime type information
TypeName("cellSizeCalculationType");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
cellSizeCalculationType,
dictionary,
(
const dictionary& cellSizeCalculationTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
),
(cellSizeCalculationTypeDict, surface, defaultCellSize)
);
// Constructors
//- Construct from components
cellSizeCalculationType
(
const word& type,
const dictionary& cellSizeCalculationTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
);
// Selectors
//- Return a reference to the selected cellSizeCalculationType
static autoPtr<cellSizeCalculationType> New
(
const dictionary& cellSizeCalculationTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
);
//- Destructor
virtual ~cellSizeCalculationType();
// Member Functions
//- Load the cell size
virtual tmp<triSurfacePointScalarField> load() = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fieldFromFile.H"
#include "addToRunTimeSelectionTable.H"
#include "triSurfaceMesh.H"
#include "triSurfaceFields.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fieldFromFile, 0);
addToRunTimeSelectionTable
(
cellSizeCalculationType,
fieldFromFile,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldFromFile::fieldFromFile
(
const dictionary& cellSizeCalcTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
)
:
cellSizeCalculationType
(
typeName,
cellSizeCalcTypeDict,
surface,
defaultCellSize
),
fileName_
(
cellSizeCalcTypeDict.subDict(typeName + "Coeffs").lookup("fieldFile")
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::triSurfacePointScalarField> Foam::fieldFromFile::load()
{
Info<< indent << "Loading: " << fileName_ << endl;
tmp<triSurfacePointScalarField> pointCellSize
(
new triSurfacePointScalarField
(
IOobject
(
fileName_,
surface_.searchableSurface::time().constant(),
"triSurface",
surface_.searchableSurface::time(),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
surface_,
dimLength,
true
)
);
return pointCellSize;
}
// ************************************************************************* //

View File

@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::fieldFromFile
Description
SourceFiles
fieldFromFile.C
\*---------------------------------------------------------------------------*/
#ifndef fieldFromFile_H
#define fieldFromFile_H
#include "cellSizeCalculationType.H"
#include "triSurfaceFields.H"
#include "PrimitivePatchInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class triSurfaceMesh;
/*---------------------------------------------------------------------------*\
Class fieldFromFile Declaration
\*---------------------------------------------------------------------------*/
class fieldFromFile
:
public cellSizeCalculationType
{
private:
// Private data
//- Name of the triSurfaceScalarField file to load in. Must be in
// constant/triSurface
const word fileName_;
public:
//- Runtime type information
TypeName("fieldFromFile");
// Constructors
//- Construct from components
fieldFromFile
(
const dictionary& cellSizeCalcTypeDict,
const triSurfaceMesh& surface,
const scalar& defaultCellSize
);
//- Destructor
virtual ~fieldFromFile()
{}
// Member Functions
//- Load the cell size field
virtual tmp<triSurfacePointScalarField> load();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,131 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "nonUniformField.H"
#include "triSurfaceMesh.H"
#include "searchableSurface.H"
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(nonUniformField, 0);
addToRunTimeSelectionTable
(
surfaceCellSizeFunction,
nonUniformField,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::nonUniformField::nonUniformField
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
)
:
surfaceCellSizeFunction
(
typeName,
cellSizeFunctionDict,
surface,
defaultCellSize
),
surfaceTriMesh_(refCast<const triSurfaceMesh>(surface)),
cellSizeCalculationType_
(
cellSizeCalculationType::New
(
coeffsDict(),
surfaceTriMesh_,
defaultCellSize
)
),
pointCellSize_
(
IOobject
(
"pointCellSize.cellSize",
surfaceTriMesh_.searchableSurface::time().constant(),
"triSurface",
surfaceTriMesh_.searchableSurface::time(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
surfaceTriMesh_,
dimLength,
false
)
{
Info<< incrIndent;
pointCellSize_ = cellSizeCalculationType_().load();
Info<< indent << "Cell size field statistics:" << nl
<< indent << " Minimum: " << min(pointCellSize_).value() << nl
<< indent << " Average: " << average(pointCellSize_).value() << nl
<< indent << " Maximum: " << max(pointCellSize_).value() << endl;
Info<< decrIndent;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::nonUniformField::interpolate
(
const point& pt,
const label index
) const
{
const face& faceHitByPt = surfaceTriMesh_.triSurface::operator[](index);
const pointField& pts = surfaceTriMesh_.points();
const Map<label>& pMap = surfaceTriMesh_.meshPointMap();
triPointRef tri
(
pts[faceHitByPt[0]],
pts[faceHitByPt[1]],
pts[faceHitByPt[2]]
);
scalarList bary(3, 0.0);
tri.barycentric(pt, bary);
return pointCellSize_[pMap[faceHitByPt[0]]]*bary[0]
+ pointCellSize_[pMap[faceHitByPt[1]]]*bary[1]
+ pointCellSize_[pMap[faceHitByPt[2]]]*bary[2];
}
// ************************************************************************* //

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::nonUniformField
Description
SourceFiles
nonUniformField.C
\*---------------------------------------------------------------------------*/
#ifndef nonUniformField_H
#define nonUniformField_H
#include "triSurfaceFields.H"
#include "PrimitivePatchInterpolation.H"
#include "surfaceCellSizeFunction.H"
#include "cellSizeCalculationType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class triSurfaceMesh;
class searchableSurface;
/*---------------------------------------------------------------------------*\
Class nonUniformField Declaration
\*---------------------------------------------------------------------------*/
class nonUniformField
:
public surfaceCellSizeFunction
{
protected:
// Private typedef
typedef PrimitivePatchInterpolation
<
PrimitivePatch<labelledTri, List, pointField, point>
> primitivePatchInterpolation;
// Private data
const triSurfaceMesh& surfaceTriMesh_;
autoPtr<cellSizeCalculationType> cellSizeCalculationType_;
triSurfacePointScalarField pointCellSize_;
public:
//- Runtime type information
TypeName("nonUniformField");
// Constructors
//- Construct from components
nonUniformField
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
);
//- Destructor
virtual ~nonUniformField()
{}
// Member Functions
// Query
//- Return the interpolated cell size for a point in the given
// surface triangle
virtual scalar interpolate
(
const point& pt,
const label index
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "surfaceCellSizeFunction.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(surfaceCellSizeFunction, 0);
defineRunTimeSelectionTable(surfaceCellSizeFunction, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceCellSizeFunction::surfaceCellSizeFunction
(
const word& type,
const dictionary& surfaceCellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
)
:
dictionary(surfaceCellSizeFunctionDict),
surface_(surface),
coeffsDict_(subDict(type + "Coeffs")),
defaultCellSize_(defaultCellSize),
refinementFactor_
(
lookupOrDefault<scalar>("refinementFactor", 1.0)
)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::surfaceCellSizeFunction> Foam::surfaceCellSizeFunction::New
(
const dictionary& surfaceCellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
)
{
word surfaceCellSizeFunctionTypeName
(
surfaceCellSizeFunctionDict.lookup("surfaceCellSizeFunction")
);
Info<< indent << "Selecting surfaceCellSizeFunction "
<< surfaceCellSizeFunctionTypeName << endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(surfaceCellSizeFunctionTypeName);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"surfaceCellSizeFunction::New(dictionary&, "
"const conformalVoronoiMesh&, const searchableSurface&)"
) << "Unknown surfaceCellSizeFunction type "
<< surfaceCellSizeFunctionTypeName
<< endl << endl
<< "Valid surfaceCellSizeFunction types are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<surfaceCellSizeFunction>
(
cstrIter()(surfaceCellSizeFunctionDict, surface, defaultCellSize)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::surfaceCellSizeFunction::~surfaceCellSizeFunction()
{}
// ************************************************************************* //

View File

@ -0,0 +1,158 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::surfaceCellSizeFunction
Description
Abstract base class for specifying target cell sizes
SourceFiles
surfaceCellSizeFunction.C
\*---------------------------------------------------------------------------*/
#ifndef surfaceCellSizeFunction_H
#define surfaceCellSizeFunction_H
#include "searchableSurface.H"
#include "dictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class surfaceCellSizeFunction Declaration
\*---------------------------------------------------------------------------*/
class surfaceCellSizeFunction
:
public dictionary
{
protected:
// Protected data
//- Reference to the searchableSurface that surfaceCellSizeFunction
// relates to
const searchableSurface& surface_;
const dictionary coeffsDict_;
const scalar& defaultCellSize_;
//- If cell resizing is allowed, this is the factor of the old cell size
// to get the new cell size
scalar refinementFactor_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
surfaceCellSizeFunction(const surfaceCellSizeFunction&);
//- Disallow default bitwise assignment
void operator=(const surfaceCellSizeFunction&);
public:
//- Runtime type information
TypeName("surfaceCellSizeFunction");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
surfaceCellSizeFunction,
dictionary,
(
const dictionary& surfaceCellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
),
(surfaceCellSizeFunctionDict, surface, defaultCellSize)
);
// Constructors
//- Construct from components
surfaceCellSizeFunction
(
const word& type,
const dictionary& surfaceCellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
);
// Selectors
//- Return a reference to the selected surfaceCellSizeFunction
static autoPtr<surfaceCellSizeFunction> New
(
const dictionary& surfaceCellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
);
//- Destructor
virtual ~surfaceCellSizeFunction();
// Member Functions
//- Const access to the details dictionary
inline const dictionary& coeffsDict() const
{
return coeffsDict_;
}
virtual scalar interpolate
(
const point& pt,
const label index
) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "uniformValue.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(uniformValue, 0);
addToRunTimeSelectionTable
(
surfaceCellSizeFunction,
uniformValue,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::uniformValue::uniformValue
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
)
:
surfaceCellSizeFunction
(
typeName,
cellSizeFunctionDict,
surface,
defaultCellSize
),
surfaceCellSize_
(
readScalar(coeffsDict().lookup("surfaceCellSizeCoeff"))*defaultCellSize
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::uniformValue::interpolate
(
const point& pt,
const label index
) const
{
return surfaceCellSize_;
}
// ************************************************************************* //

View File

@ -0,0 +1,100 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::uniformValue
Description
SourceFiles
uniformValue.C
\*---------------------------------------------------------------------------*/
#ifndef uniformValue_H
#define uniformValue_H
#include "surfaceCellSizeFunction.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class uniformValue Declaration
\*---------------------------------------------------------------------------*/
class uniformValue
:
public surfaceCellSizeFunction
{
private:
// Private data
scalar surfaceCellSize_;
public:
//- Runtime type information
TypeName("uniformValue");
// Constructors
//- Construct from components
uniformValue
(
const dictionary& cellSizeFunctionDict,
const searchableSurface& surface,
const scalar& defaultCellSize
);
//- Destructor
virtual ~uniformValue()
{}
// Member Functions
virtual scalar interpolate
(
const point& pt,
const label index
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedefs
CGALTriangulation3DKernel
Description
\*---------------------------------------------------------------------------*/
#ifndef CGALTriangulation3DKernel_H
#define CGALTriangulation3DKernel_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "CGAL/Delaunay_triangulation_3.h"
#ifdef CGAL_INEXACT
// Fast kernel using a double as the storage type but the triangulation may
// fail. Adding robust circumcentre traits
#include "CGAL/Exact_predicates_inexact_constructions_kernel.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel baseK;
// #include <CGAL/Robust_circumcenter_traits_3.h>
#include <CGAL/Robust_circumcenter_filtered_traits_3.h>
// typedef CGAL::Robust_circumcenter_traits_3<baseK> K;
typedef CGAL::Robust_circumcenter_filtered_traits_3<baseK> K;
#else
// Very robust but expensive kernel
#include "CGAL/Exact_predicates_exact_constructions_kernel.h"
typedef CGAL::Exact_predicates_exact_constructions_kernel baseK;
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedefs
CGALTriangulation3Ddefs
Description
CGAL data structures used for 3D Delaunay meshing.
Define CGAL_INEXACT to use Exact_predicates_inexact_constructions kernel
otherwise the more robust but much less efficient
Exact_predicates_exact_constructions will be used.
\*---------------------------------------------------------------------------*/
#ifndef CGALTriangulation3Ddefs_H
#define CGALTriangulation3Ddefs_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "CGALTriangulation3DKernel.H"
#include "indexedVertex.H"
#include "indexedCell.H"
typedef CGAL::indexedVertex<K> Vb;
typedef CGAL::indexedCell<K> Cb;
typedef CGAL::Compact_location CompactLocator;
typedef CGAL::Fast_location FastLocator;
typedef CGAL::Triangulation_data_structure_3<Vb, Cb> Tds;
typedef CGAL::Delaunay_triangulation_3<K, Tds, CompactLocator> Delaunay;
typedef CGAL::Delaunay_triangulation_3<K, Tds, FastLocator> CellSizeDelaunay;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,765 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "conformalVoronoiMesh.H"
#include "vectorTools.H"
using namespace Foam::vectorTools;
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::List<Foam::extendedFeatureEdgeMesh::edgeStatus>
Foam::conformalVoronoiMesh::calcPointFeatureEdgesTypes
(
const extendedFeatureEdgeMesh& feMesh,
const labelList& pEds,
pointFeatureEdgesTypes& pFEdgeTypes
) const
{
List<extendedFeatureEdgeMesh::edgeStatus> allEdStat(pEds.size());
forAll(pEds, i)
{
label edgeI = pEds[i];
extendedFeatureEdgeMesh::edgeStatus& eS = allEdStat[i];
eS = feMesh.getEdgeStatus(edgeI);
pFEdgeTypes(eS)++;
}
return allEdStat;
}
bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
(
const extendedFeatureEdgeMesh& feMesh,
const labelList& pEds,
const pointFeatureEdgesTypes& pFEdgesTypes,
const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat,
const label ptI,
DynamicList<Vb>& pts
)
{
if
(
!pFEdgesTypes.found(extendedFeatureEdgeMesh::EXTERNAL)
|| !pFEdgesTypes.found(extendedFeatureEdgeMesh::INTERNAL)
)
{
return false;
}
if
(
pFEdgesTypes[extendedFeatureEdgeMesh::EXTERNAL] == 2
&& pFEdgesTypes[extendedFeatureEdgeMesh::INTERNAL] == 1
&& pEds.size() == 3
)
{
Info<< "nExternal == 2 && nInternal == 1" << endl;
const Foam::point& featPt = feMesh.points()[ptI];
if (!positionOnThisProc(featPt))
{
return false;
}
label nVert = number_of_vertices();
const label initialNumOfPoints = pts.size();
const scalar ppDist = pointPairDistance(featPt);
const vectorField& normals = feMesh.normals();
const labelListList& edgeNormals = feMesh.edgeNormals();
label concaveEdgeI = -1;
labelList convexEdgesI(2, -1);
label nConvex = 0;
forAll(pEds, i)
{
const extendedFeatureEdgeMesh::edgeStatus& eS = allEdStat[i];
if (eS == extendedFeatureEdgeMesh::INTERNAL)
{
concaveEdgeI = pEds[i];
}
else if (eS == extendedFeatureEdgeMesh::EXTERNAL)
{
convexEdgesI[nConvex++] = pEds[i];
}
else if (eS == extendedFeatureEdgeMesh::FLAT)
{
WarningIn("Foam::conformalVoronoiMesh::"
"createSpecialisedFeaturePoint")
<< "Edge " << eS << " is flat"
<< endl;
}
else
{
FatalErrorIn("Foam::conformalVoronoiMesh::"
"createSpecialisedFeaturePoint")
<< "Edge " << eS << " not concave/convex"
<< exit(FatalError);
}
}
const vector& concaveEdgePlaneANormal =
normals[edgeNormals[concaveEdgeI][0]];
const vector& concaveEdgePlaneBNormal =
normals[edgeNormals[concaveEdgeI][1]];
// Intersect planes parallel to the concave edge planes offset
// by ppDist and the plane defined by featPt and the edge vector.
plane planeA
(
featPt + ppDist*concaveEdgePlaneANormal,
concaveEdgePlaneANormal
);
plane planeB
(
featPt + ppDist*concaveEdgePlaneBNormal,
concaveEdgePlaneBNormal
);
const vector& concaveEdgeDir = feMesh.edgeDirection
(
concaveEdgeI,
ptI
);
// Todo,needed later but want to get rid of this.
const Foam::point concaveEdgeLocalFeatPt =
featPt + ppDist*concaveEdgeDir;
// Finding the nearest point on the intersecting line to the edge
// point. Floating point errors often occur using planePlaneIntersect
plane planeF(concaveEdgeLocalFeatPt, concaveEdgeDir);
const Foam::point concaveEdgeExternalPt = planeF.planePlaneIntersect
(
planeA,
planeB
);
// Redefine planes to be on the feature surfaces to project through
planeA = plane(featPt, concaveEdgePlaneANormal);
planeB = plane(featPt, concaveEdgePlaneBNormal);
const Foam::point internalPtA =
concaveEdgeExternalPt
- 2.0*planeA.distance(concaveEdgeExternalPt)
*concaveEdgePlaneANormal;
pts.append
(
Vb(internalPtA, Vb::vtInternalFeaturePoint)
);
const Foam::point internalPtB =
concaveEdgeExternalPt
- 2.0*planeB.distance(concaveEdgeExternalPt)
*concaveEdgePlaneBNormal;
pts.append
(
Vb(internalPtB, Vb::vtInternalFeaturePoint)
);
// Add the external points
Foam::point externalPtD;
Foam::point externalPtE;
vector convexEdgePlaneCNormal(0,0,0);
vector convexEdgePlaneDNormal(0,0,0);
const labelList& concaveEdgeNormals = edgeNormals[concaveEdgeI];
const labelList& convexEdgeANormals = edgeNormals[convexEdgesI[0]];
const labelList& convexEdgeBNormals = edgeNormals[convexEdgesI[1]];
forAll(concaveEdgeNormals, edgeNormalI)
{
bool convexEdgeA = false;
bool convexEdgeB = false;
forAll(convexEdgeANormals, edgeAnormalI)
{
const vector& concaveNormal
= normals[concaveEdgeNormals[edgeNormalI]];
const vector& convexNormal
= normals[convexEdgeANormals[edgeAnormalI]];
Info<< "Angle between vectors = "
<< degAngleBetween(concaveNormal, convexNormal) << endl;
// Need a looser tolerance, because sometimes adjacent triangles
// on the same surface will be slightly out of alignment.
if (areParallel(concaveNormal, convexNormal, tolParallel))
{
convexEdgeA = true;
}
}
forAll(convexEdgeBNormals, edgeBnormalI)
{
const vector& concaveNormal
= normals[concaveEdgeNormals[edgeNormalI]];
const vector& convexNormal
= normals[convexEdgeBNormals[edgeBnormalI]];
Info<< "Angle between vectors = "
<< degAngleBetween(concaveNormal, convexNormal) << endl;
// Need a looser tolerance, because sometimes adjacent triangles
// on the same surface will be slightly out of alignment.
if (areParallel(concaveNormal, convexNormal, tolParallel))
{
convexEdgeB = true;
}
}
if ((convexEdgeA && convexEdgeB) || (!convexEdgeA && !convexEdgeB))
{
WarningIn
(
"Foam::conformalVoronoiMesh"
"::createSpecialisedFeaturePoint"
)
<< "Both or neither of the convex edges share the concave "
<< "edge's normal."
<< " convexEdgeA = " << convexEdgeA
<< " convexEdgeB = " << convexEdgeB
<< endl;
// Remove points that have just been added before returning
for (label i = 0; i < 2; ++i)
{
pts.remove();
nVert--;
}
return false;
}
if (convexEdgeA)
{
forAll(convexEdgeANormals, edgeAnormalI)
{
const vector& concaveNormal
= normals[concaveEdgeNormals[edgeNormalI]];
const vector& convexNormal
= normals[convexEdgeANormals[edgeAnormalI]];
if
(
!areParallel(concaveNormal, convexNormal, tolParallel)
)
{
convexEdgePlaneCNormal = convexNormal;
plane planeC(featPt, convexEdgePlaneCNormal);
externalPtD =
internalPtA
+ 2.0*planeC.distance(internalPtA)
*convexEdgePlaneCNormal;
pts.append
(
Vb(externalPtD, Vb::vtExternalFeaturePoint)
);
}
}
}
if (convexEdgeB)
{
forAll(convexEdgeBNormals, edgeBnormalI)
{
const vector& concaveNormal
= normals[concaveEdgeNormals[edgeNormalI]];
const vector& convexNormal
= normals[convexEdgeBNormals[edgeBnormalI]];
if
(
!areParallel(concaveNormal, convexNormal, tolParallel)
)
{
convexEdgePlaneDNormal = convexNormal;
plane planeD(featPt, convexEdgePlaneDNormal);
externalPtE =
internalPtB
+ 2.0*planeD.distance(internalPtB)
*convexEdgePlaneDNormal;
pts.append
(
Vb(externalPtE, Vb::vtExternalFeaturePoint)
);
}
}
}
}
pts.append
(
Vb(concaveEdgeExternalPt, Vb::vtExternalFeaturePoint)
);
const scalar totalAngle = radToDeg
(
constant::mathematical::pi
+ radAngleBetween(concaveEdgePlaneANormal, concaveEdgePlaneBNormal)
);
if (totalAngle > foamyHexMeshControls().maxQuadAngle())
{
// Add additional mitreing points
//scalar angleSign = 1.0;
vector convexEdgesPlaneNormal =
0.5*(convexEdgePlaneCNormal + convexEdgePlaneDNormal);
plane planeM(featPt, convexEdgesPlaneNormal);
// if
// (
// geometryToConformTo_.outside
// (
// featPt - convexEdgesPlaneNormal*ppDist
// )
// )
// {
// angleSign = -1.0;
// }
// scalar phi =
// angleSign*acos(concaveEdgeDir & -convexEdgesPlaneNormal);
//
// scalar guard =
// (
// 1.0 + sin(phi)*ppDist/mag
// (
// concaveEdgeLocalFeatPt - concaveEdgeExternalPt
// )
// )/cos(phi) - 1.0;
const Foam::point internalPtF =
concaveEdgeExternalPt
//+ (2.0 + guard)*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt);
+ 2.0*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt);
pts.append
(
Vb(internalPtF, Vb::vtInternalFeaturePoint)
);
const Foam::point externalPtG =
internalPtF
+ 2.0*planeM.distance(internalPtF)*convexEdgesPlaneNormal;
pts.append
(
Vb(externalPtG, Vb::vtExternalFeaturePoint)
);
}
if (debug)
{
for (label ptI = initialNumOfPoints; ptI < pts.size(); ++ptI)
{
Info<< "Point " << ptI << " : ";
meshTools::writeOBJ(Info, topoint(pts[ptI].point()));
}
}
return true;
}
else if
(
pFEdgesTypes[extendedFeatureEdgeMesh::EXTERNAL] == 1
&& pFEdgesTypes[extendedFeatureEdgeMesh::INTERNAL] == 2
&& pEds.size() == 3
)
{
Info<< "nExternal == 1 && nInternal == 2" << endl;
const Foam::point& featPt = feMesh.points()[ptI];
if (!positionOnThisProc(featPt))
{
return false;
}
label nVert = number_of_vertices();
const label initialNumOfPoints = pts.size();
const scalar ppDist = pointPairDistance(featPt);
const vectorField& normals = feMesh.normals();
const labelListList& edgeNormals = feMesh.edgeNormals();
label convexEdgeI = -1;
labelList concaveEdgesI(2, -1);
label nConcave = 0;
forAll(pEds, i)
{
const extendedFeatureEdgeMesh::edgeStatus& eS = allEdStat[i];
if (eS == extendedFeatureEdgeMesh::EXTERNAL)
{
convexEdgeI = pEds[i];
}
else if (eS == extendedFeatureEdgeMesh::INTERNAL)
{
concaveEdgesI[nConcave++] = pEds[i];
}
else if (eS == extendedFeatureEdgeMesh::FLAT)
{
WarningIn("Foam::conformalVoronoiMesh::"
"createSpecialisedFeaturePoint")
<< "Edge " << eS << " is flat"
<< endl;
}
else
{
FatalErrorIn("Foam::conformalVoronoiMesh::"
"createSpecialisedFeaturePoint")
<< "Edge " << eS << " not concave/convex"
<< exit(FatalError);
}
}
const vector& convexEdgePlaneANormal =
normals[edgeNormals[convexEdgeI][0]];
const vector& convexEdgePlaneBNormal =
normals[edgeNormals[convexEdgeI][1]];
// Intersect planes parallel to the concave edge planes offset
// by ppDist and the plane defined by featPt and the edge vector.
plane planeA
(
featPt - ppDist*convexEdgePlaneANormal,
convexEdgePlaneANormal
);
plane planeB
(
featPt - ppDist*convexEdgePlaneBNormal,
convexEdgePlaneBNormal
);
const vector& convexEdgeDir = feMesh.edgeDirection
(
convexEdgeI,
ptI
);
// Todo,needed later but want to get rid of this.
const Foam::point convexEdgeLocalFeatPt =
featPt + ppDist*convexEdgeDir;
// Finding the nearest point on the intersecting line to the edge
// point. Floating point errors often occur using planePlaneIntersect
plane planeF(convexEdgeLocalFeatPt, convexEdgeDir);
const Foam::point convexEdgeExternalPt = planeF.planePlaneIntersect
(
planeA,
planeB
);
// Redefine planes to be on the feature surfaces to project through
planeA = plane(featPt, convexEdgePlaneANormal);
planeB = plane(featPt, convexEdgePlaneBNormal);
const Foam::point internalPtA =
convexEdgeExternalPt
+ 2.0*planeA.distance(convexEdgeExternalPt)
*convexEdgePlaneANormal;
pts.append
(
Vb(internalPtA, Vb::vtExternalFeaturePoint)
);
const Foam::point internalPtB =
convexEdgeExternalPt
+ 2.0*planeB.distance(convexEdgeExternalPt)
*convexEdgePlaneBNormal;
pts.append
(
Vb(internalPtB, Vb::vtExternalFeaturePoint)
);
// Add the internal points
Foam::point externalPtD;
Foam::point externalPtE;
vector concaveEdgePlaneCNormal(0,0,0);
vector concaveEdgePlaneDNormal(0,0,0);
const labelList& convexEdgeNormals = edgeNormals[convexEdgeI];
const labelList& concaveEdgeANormals = edgeNormals[concaveEdgesI[0]];
const labelList& concaveEdgeBNormals = edgeNormals[concaveEdgesI[1]];
forAll(convexEdgeNormals, edgeNormalI)
{
bool concaveEdgeA = false;
bool concaveEdgeB = false;
forAll(concaveEdgeANormals, edgeAnormalI)
{
const vector& convexNormal
= normals[convexEdgeNormals[edgeNormalI]];
const vector& concaveNormal
= normals[concaveEdgeANormals[edgeAnormalI]];
Info<< "Angle between vectors = "
<< degAngleBetween(convexNormal, concaveNormal) << endl;
// Need a looser tolerance, because sometimes adjacent triangles
// on the same surface will be slightly out of alignment.
if (areParallel(convexNormal, concaveNormal, tolParallel))
{
concaveEdgeA = true;
}
}
forAll(concaveEdgeBNormals, edgeBnormalI)
{
const vector& convexNormal
= normals[convexEdgeNormals[edgeNormalI]];
const vector& concaveNormal
= normals[concaveEdgeBNormals[edgeBnormalI]];
Info<< "Angle between vectors = "
<< degAngleBetween(convexNormal, concaveNormal) << endl;
// Need a looser tolerance, because sometimes adjacent triangles
// on the same surface will be slightly out of alignment.
if (areParallel(convexNormal, concaveNormal, tolParallel))
{
concaveEdgeB = true;
}
}
if
(
(concaveEdgeA && concaveEdgeB)
|| (!concaveEdgeA && !concaveEdgeB)
)
{
WarningIn
(
"Foam::conformalVoronoiMesh"
"::createSpecialisedFeaturePoint"
) << "Both or neither of the concave edges share the convex "
<< "edge's normal."
<< " concaveEdgeA = " << concaveEdgeA
<< " concaveEdgeB = " << concaveEdgeB
<< endl;
// Remove points that have just been added before returning
for (label i = 0; i < 2; ++i)
{
pts.remove();
nVert--;
}
return false;
}
if (concaveEdgeA)
{
forAll(concaveEdgeANormals, edgeAnormalI)
{
const vector& convexNormal
= normals[convexEdgeNormals[edgeNormalI]];
const vector& concaveNormal
= normals[concaveEdgeANormals[edgeAnormalI]];
if
(
!areParallel(convexNormal, concaveNormal, tolParallel)
)
{
concaveEdgePlaneCNormal = concaveNormal;
plane planeC(featPt, concaveEdgePlaneCNormal);
externalPtD =
internalPtA
- 2.0*planeC.distance(internalPtA)
*concaveEdgePlaneCNormal;
pts.append
(
Vb(externalPtD, Vb::vtInternalFeaturePoint)
);
}
}
}
if (concaveEdgeB)
{
forAll(concaveEdgeBNormals, edgeBnormalI)
{
const vector& convexNormal
= normals[convexEdgeNormals[edgeNormalI]];
const vector& concaveNormal
= normals[concaveEdgeBNormals[edgeBnormalI]];
if
(
!areParallel(convexNormal, concaveNormal, tolParallel)
)
{
concaveEdgePlaneDNormal = concaveNormal;
plane planeD(featPt, concaveEdgePlaneDNormal);
externalPtE =
internalPtB
- 2.0*planeD.distance(internalPtB)
*concaveEdgePlaneDNormal;
pts.append
(
Vb(externalPtE, Vb::vtInternalFeaturePoint)
);
}
}
}
}
pts.append
(
Vb(convexEdgeExternalPt, Vb::vtInternalFeaturePoint)
);
const scalar totalAngle = radToDeg
(
constant::mathematical::pi
+ radAngleBetween(convexEdgePlaneANormal, convexEdgePlaneBNormal)
);
if (totalAngle > foamyHexMeshControls().maxQuadAngle())
{
// Add additional mitreing points
//scalar angleSign = 1.0;
vector convexEdgesPlaneNormal =
0.5*(concaveEdgePlaneCNormal + concaveEdgePlaneDNormal);
plane planeM(featPt, convexEdgesPlaneNormal);
// if
// (
// geometryToConformTo_.outside
// (
// featPt - convexEdgesPlaneNormal*ppDist
// )
// )
// {
// angleSign = -1.0;
// }
// scalar phi =
// angleSign*acos(concaveEdgeDir & -convexEdgesPlaneNormal);
//
// scalar guard =
// (
// 1.0 + sin(phi)*ppDist/mag
// (
// concaveEdgeLocalFeatPt - concaveEdgeExternalPt
// )
// )/cos(phi) - 1.0;
const Foam::point internalPtF =
convexEdgeExternalPt
//+ (2.0 + guard)*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt);
+ 2.0*(convexEdgeLocalFeatPt - convexEdgeExternalPt);
pts.append
(
Vb(internalPtF, Vb::vtExternalFeaturePoint)
);
const Foam::point externalPtG =
internalPtF
- 2.0*planeM.distance(internalPtF)*convexEdgesPlaneNormal;
pts.append
(
Vb(externalPtG, Vb::vtInternalFeaturePoint)
);
}
if (debug)
{
for (label ptI = initialNumOfPoints; ptI < pts.size(); ++ptI)
{
Info<< "Point " << ptI << " "
<< indexedVertexEnum::vertexTypeNames_[pts[ptI].type()]
<< " : ";
meshTools::writeOBJ(Info, topoint(pts[ptI].point()));
}
}
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -0,0 +1,735 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline Foam::scalar Foam::conformalVoronoiMesh::defaultCellSize() const
{
return foamyHexMeshControls().defaultCellSize();
}
inline Foam::scalar Foam::conformalVoronoiMesh::targetCellSize
(
const Foam::point& pt
) const
{
return cellShapeControls().cellSize(pt);
}
inline Foam::scalar Foam::conformalVoronoiMesh::averageCellSize
(
const Vertex_handle& vA,
const Vertex_handle& vB
) const
{
// Arithmetic mean
// return 0.5*(vA->targetCellSize() + vB->targetCellSize());
// Geometric mean
return sqrt(vA->targetCellSize()*vB->targetCellSize());
// Harmonic mean
// return
// 2.0*(vA->targetCellSize()*vB->targetCellSize())
// /(vA->targetCellSize() + vB->targetCellSize());
}
inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
(
const Vertex_handle& vA,
const Vertex_handle& vB
) const
{
if
(
(!vA->internalOrBoundaryPoint() || vA->referred())
&& (!vB->internalOrBoundaryPoint() || vB->referred())
)
{
// There are no internalOrBoundaryPoints available, determine
// size from scratch
// Geometric mean
return sqrt
(
targetCellSize(topoint(vA->point()))
*targetCellSize(topoint(vB->point()))
);
}
else if (!vB->internalOrBoundaryPoint() || vB->referred())
{
return vA->targetCellSize();
}
else if (!vA->internalOrBoundaryPoint() || vA->referred())
{
return vB->targetCellSize();
}
return averageCellSize(vA, vB);
}
inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
(
const Delaunay::Finite_facets_iterator& fit
) const
{
// Arithmetic mean
scalar sizeSum = 0;
label nProducts = 0;
const Cell_handle c(fit->first);
const int oppositeVertex = fit->second;
for (label i = 0; i < 3; i++)
{
Vertex_handle v = c->vertex(vertex_triple_index(oppositeVertex, i));
if (v->internalOrBoundaryPoint() && !v->referred())
{
sizeSum += v->targetCellSize();
nProducts++;
}
}
if (nProducts < 1)
{
// There are no internalOrBoundaryPoints available, determine
// size from scratch
for (label i = 0; i < 3; i++)
{
Vertex_handle v = c->vertex(vertex_triple_index(oppositeVertex, i));
sizeSum += targetCellSize(topoint(v->point()));
}
nProducts = 3;
}
if (sizeSum < 0)
{
WarningIn("averageAnyCellSize(const Delaunay::Finite_facets_iterator&)")
<< "sizeSum = " << sizeSum
<< endl;
return 0;
}
return pow(sizeSum, (1.0/nProducts));
}
inline Foam::scalar Foam::conformalVoronoiMesh::pointPairDistance
(
const Foam::point& pt
) const
{
return targetCellSize(pt)*foamyHexMeshControls().pointPairDistanceCoeff();
}
inline Foam::scalar Foam::conformalVoronoiMesh::mixedFeaturePointDistance
(
const Foam::point& pt
) const
{
return
pointPairDistance(pt)
*foamyHexMeshControls().mixedFeaturePointPPDistanceCoeff();
}
inline Foam::scalar Foam::conformalVoronoiMesh::featurePointExclusionDistanceSqr
(
const Foam::point& pt
) const
{
return
sqr
(
targetCellSize(pt)
*foamyHexMeshControls().featurePointExclusionDistanceCoeff()
);
}
inline Foam::scalar Foam::conformalVoronoiMesh::featureEdgeExclusionDistanceSqr
(
const Foam::point& pt
) const
{
return
sqr
(
targetCellSize(pt)
*foamyHexMeshControls().featureEdgeExclusionDistanceCoeff()
);
}
inline Foam::scalar Foam::conformalVoronoiMesh::surfacePtExclusionDistanceSqr
(
const Foam::point& pt
) const
{
return
sqr
(
targetCellSize(pt)
*foamyHexMeshControls().surfacePtExclusionDistanceCoeff()
);
}
inline Foam::scalar Foam::conformalVoronoiMesh::surfaceSearchDistanceSqr
(
const Foam::point& pt
) const
{
return
sqr
(
targetCellSize(pt)
*foamyHexMeshControls().surfaceSearchDistanceCoeff()
);
}
inline Foam::scalar Foam::conformalVoronoiMesh::maxSurfaceProtrusion
(
const Foam::point& pt
) const
{
return
targetCellSize(pt)
*foamyHexMeshControls().maxSurfaceProtrusionCoeff();
}
inline bool Foam::conformalVoronoiMesh::insertPoint
(
const Foam::point& p,
const indexedVertexEnum::vertexType type
)
{
return insertPoint(toPoint<Point>(p), type);
}
inline bool Foam::conformalVoronoiMesh::insertPoint
(
const Point& P,
const indexedVertexEnum::vertexType type
)
{
uint nVert = number_of_vertices();
Vertex_handle vh = insert(P);
bool pointInserted = true;
if (nVert == number_of_vertices())
{
Pout<< "Failed to insert point : " << topoint(P)
<< " of type " << type << endl;
pointInserted = false;
}
else
{
vh->index() = getNewVertexIndex();
vh->type() = type;
}
return pointInserted;
}
inline bool Foam::conformalVoronoiMesh::insertReferredPoint(const Vb& P)
{
return insertReferredPoint(P.point(), P.index(), P.type(), P.procIndex());
}
inline bool Foam::conformalVoronoiMesh::insertReferredPoint
(
const Foam::point& p,
const label index,
const indexedVertexEnum::vertexType type,
const label processor
)
{
return insertReferredPoint(toPoint<Point>(p), index, type, processor);
}
inline bool Foam::conformalVoronoiMesh::insertReferredPoint
(
const Point& P,
const label index,
const indexedVertexEnum::vertexType type,
const label processor
)
{
uint nVert = number_of_vertices();
Vertex_handle vh = insert(P);
bool pointInserted = true;
if (nVert == number_of_vertices())
{
Pout<< "Failed to insert point " << topoint(P)
<< " type: " << type << " index: " << index
<< " proc: " << processor << endl;
pointInserted = false;
}
else
{
vh->index() = index;
vh->type() = type;
vh->procIndex() = processor;
}
return pointInserted;
}
inline void Foam::conformalVoronoiMesh::createPointPair
(
const scalar ppDist,
const Foam::point& surfPt,
const vector& n,
DynamicList<Vb>& pts
)
{
vector ppDistn = ppDist*n;
const Foam::point internalPt = surfPt - ppDistn;
const Foam::point externalPt = surfPt + ppDistn;
if
(
geometryToConformTo_.inside(internalPt)
&& geometryToConformTo_.outside(externalPt)
)
{
pts.append
(
Vb
(
surfPt - ppDistn,
vertexCount() + pts.size(),
Vb::vtInternalSurface,
Pstream::myProcNo()
)
);
pts.append
(
Vb
(
surfPt + ppDistn,
vertexCount() + pts.size(),
Vb::vtExternalSurface,
Pstream::myProcNo()
)
);
}
else
{
Info<< "Warning: point pair not inside/outside" << nl
<< " surfPt = " << surfPt << nl
<< " internal = "
<< internalPt << " " << geometryToConformTo_.inside(internalPt)
<< nl
<< " external = "
<< externalPt << " " << geometryToConformTo_.outside(externalPt)
<< endl;
}
}
inline Foam::point Foam::conformalVoronoiMesh::perturbPoint
(
const Foam::point& pt
) const
{
Foam::point perturbedPt(pt);
// vector delta(xR/ni, yR/nj, zR/nk);
// scalar pert = randomPerturbationCoeff*cmptMin(delta);
scalar pert = 1e-12*defaultCellSize();
perturbedPt.x() += pert*(rndGen_.scalar01() - 0.5);
perturbedPt.y() += pert*(rndGen_.scalar01() - 0.5);
perturbedPt.z() += pert*(rndGen_.scalar01() - 0.5);
return perturbedPt;
}
inline void Foam::conformalVoronoiMesh::createBafflePointPair
(
const scalar ppDist,
const Foam::point& surfPt,
const vector& n,
DynamicList<Vb>& pts
)
{
vector ppDistn = ppDist*n;
pts.append
(
Vb
(
surfPt - ppDistn,
vertexCount() + 1 + pts.size(),
Vb::vtInternalSurface,
Pstream::myProcNo()
)
);
pts.append
(
Vb
(
surfPt + ppDistn,
vertexCount() + 1 + pts.size(),
Vb::vtInternalSurface,
Pstream::myProcNo()
)
);
}
inline bool Foam::conformalVoronoiMesh::isPointPair
(
const Vertex_handle& vA,
const Vertex_handle& vB
) const
{
// Want to do this topologically, but problem if vertices are redistributed
// so that one of the point pair is one processor and the other is on
// another.
const Foam::point& ptA = topoint(vA->point());
const Foam::point& ptB = topoint(vB->point());
if
(
(
vA->type() == Vb::vtInternalSurface
&& vB->type() == Vb::vtExternalSurface
)
||
(
vB->type() == Vb::vtInternalSurface
&& vA->type() == Vb::vtExternalSurface
)
||
(
vA->type() == Vb::vtInternalFeatureEdge
&& vB->type() == Vb::vtExternalFeatureEdge
)
||
(
vB->type() == Vb::vtInternalFeatureEdge
&& vA->type() == Vb::vtExternalFeatureEdge
)
||
(
vA->type() == Vb::vtInternalSurface
&& vB->type() == Vb::vtExternalFeatureEdge
)
||
(
vB->type() == Vb::vtInternalSurface
&& vA->type() == Vb::vtExternalFeatureEdge
)
||
(
vA->type() == Vb::vtExternalSurface
&& vB->type() == Vb::vtInternalFeatureEdge
)
||
(
vB->type() == Vb::vtExternalSurface
&& vA->type() == Vb::vtInternalFeatureEdge
)
)
{
const scalar distSqr = magSqr(ptA - ptB);
const scalar ppDistSqr = sqr(2*pointPairDistance(0.5*(ptA + ptB)));
if (distSqr > 1.001*ppDistSqr)
{
return false;
}
}
return true;
}
inline bool Foam::conformalVoronoiMesh::isBoundaryDualFace
(
const Delaunay::Finite_edges_iterator& eit
) const
{
Cell_handle c = eit->first;
Vertex_handle vA = c->vertex(eit->second);
Vertex_handle vB = c->vertex(eit->third);
// if (vA->internalBoundaryPoint() && vB->externalBoundaryPoint())
// {
// if (vA->index() == vB->index() - 1)
// {
// return true;
// }
// }
// else if (vA->externalBoundaryPoint() && vB->internalBoundaryPoint())
// {
// if (vA->index() == vB->index() + 1)
// {
// return true;
// }
// }
//
// return false;
// A dual face on the boundary will result from one Dv inside and
// one outside
return
(
(
(vA->internalOrBoundaryPoint() && !vA->referred())
|| (vB->internalOrBoundaryPoint() && !vB->referred())
)
&& (
!vA->internalOrBoundaryPoint()
|| !vB->internalOrBoundaryPoint()
)
);
}
inline Foam::List<bool> Foam::conformalVoronoiMesh::dualFaceBoundaryPoints
(
const Delaunay::Finite_edges_iterator& eit
) const
{
Cell_circulator ccStart = incident_cells(*eit);
Cell_circulator cc1 = ccStart;
Cell_circulator cc2 = cc1;
// Advance the second circulator so that it always stays on the next
// cell around the edge;
cc2++;
DynamicList<bool> tmpFaceBoundaryPoints;
do
{
label cc1I = cc1->cellIndex();
label cc2I = cc2->cellIndex();
if (cc1I != cc2I)
{
if (cc1->boundaryDualVertex())
{
tmpFaceBoundaryPoints.append(true);
}
else
{
tmpFaceBoundaryPoints.append(false);
}
}
cc1++;
cc2++;
} while (cc1 != ccStart);
return tmpFaceBoundaryPoints;
}
inline Foam::List<Foam::label> Foam::conformalVoronoiMesh::processorsAttached
(
const Delaunay::Finite_facets_iterator& fit
) const
{
DynamicList<label> procsAttached(8);
const Cell_handle c1(fit->first);
const int oppositeVertex = fit->second;
const Cell_handle c2(c1->neighbor(oppositeVertex));
FixedList<label, 4> c1Procs(c1->processorsAttached());
FixedList<label, 4> c2Procs(c2->processorsAttached());
forAll(c1Procs, aPI)
{
if (findIndex(procsAttached, c1Procs[aPI] == -1))
{
procsAttached.append(c1Procs[aPI]);
}
if (findIndex(procsAttached, c2Procs[aPI] == -1))
{
procsAttached.append(c2Procs[aPI]);
}
}
return List<label>(procsAttached);
}
inline bool Foam::conformalVoronoiMesh::isParallelDualEdge
(
const Delaunay::Finite_facets_iterator& fit
) const
{
const Cell_handle c1(fit->first);
const int oppositeVertex = fit->second;
return
(
c1->vertex(vertex_triple_index(oppositeVertex, 0))->referred()
|| c1->vertex(vertex_triple_index(oppositeVertex, 1))->referred()
|| c1->vertex(vertex_triple_index(oppositeVertex, 2))->referred()
);
}
inline bool Foam::conformalVoronoiMesh::isProcBoundaryEdge
(
const Delaunay::Finite_edges_iterator& eit
) const
{
bool isProcBoundaryEdge = false;
Cell_handle c = eit->first;
Vertex_handle vA = c->vertex(eit->second);
Vertex_handle vB = c->vertex(eit->third);
if
(
(
(vA->referred() && !vB->referred())
|| (vB->referred() && !vA->referred())
)
&& vA->internalOrBoundaryPoint()
&& vB->internalOrBoundaryPoint()
)
{
isProcBoundaryEdge = true;
}
return isProcBoundaryEdge;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::conformalVoronoiMesh::CGALVector
Foam::conformalVoronoiMesh::toCGALVector(const Foam::vector& v) const
{
return CGALVector(v.x(), v.y(), v.z());
}
inline const Foam::Time& Foam::conformalVoronoiMesh::time() const
{
return runTime_;
}
inline Foam::Random& Foam::conformalVoronoiMesh::rndGen() const
{
return rndGen_;
}
inline const Foam::searchableSurfaces&
Foam::conformalVoronoiMesh::allGeometry() const
{
return allGeometry_;
}
inline const Foam::conformationSurfaces&
Foam::conformalVoronoiMesh::geometryToConformTo() const
{
return geometryToConformTo_;
}
inline const Foam::backgroundMeshDecomposition&
Foam::conformalVoronoiMesh::decomposition() const
{
if (!Pstream::parRun())
{
FatalErrorIn
(
"inline const Foam::backgroundMeshDecomposition& "
"Foam::conformalVoronoiMesh::decomposition() const"
)
<< "The backgroundMeshDecomposition cannot be asked for in serial."
<< exit(FatalError) << endl;
}
return decomposition_();
}
inline const Foam::cellShapeControl&
Foam::conformalVoronoiMesh::cellShapeControls() const
{
return cellShapeControl_;
}
inline const Foam::cvControls&
Foam::conformalVoronoiMesh::foamyHexMeshControls() const
{
return foamyHexMeshControls_;
}
// ************************************************************************* //

View File

@ -0,0 +1,191 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "conformalVoronoiMesh.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Triangulation>
Foam::scalar Foam::conformalVoronoiMesh::calculateLoadUnbalance
(
const Triangulation& mesh
) const
{
label nRealVertices = 0;
for
(
typename Triangulation::Finite_vertices_iterator vit
= mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
// Only store real vertices that are not feature vertices
if (vit->real() && !vit->featurePoint())
{
nRealVertices++;
}
}
scalar globalNRealVertices = returnReduce
(
nRealVertices,
sumOp<label>()
);
scalar unbalance = returnReduce
(
mag(1.0 - nRealVertices/(globalNRealVertices/Pstream::nProcs())),
maxOp<scalar>()
);
Info<< " Processor unbalance " << unbalance << endl;
return unbalance;
}
template<class Triangulation>
bool Foam::conformalVoronoiMesh::distributeBackground(const Triangulation& mesh)
{
if (!Pstream::parRun())
{
return false;
}
Info<< nl << "Redistributing points" << endl;
timeCheck("Before distribute");
label iteration = 0;
scalar previousLoadUnbalance = 0;
while (true)
{
scalar maxLoadUnbalance = calculateLoadUnbalance(mesh);
if
(
maxLoadUnbalance <= foamyHexMeshControls().maxLoadUnbalance()
|| maxLoadUnbalance <= previousLoadUnbalance
)
{
// If this is the first iteration, return false, if it was a
// subsequent one, return true;
return iteration != 0;
}
previousLoadUnbalance = maxLoadUnbalance;
Info<< " Total number of vertices before redistribution "
<< returnReduce(label(mesh.number_of_vertices()), sumOp<label>())
<< endl;
const fvMesh& bMesh = decomposition_().mesh();
volScalarField cellWeights
(
IOobject
(
"cellWeights",
bMesh.time().timeName(),
bMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
bMesh,
dimensionedScalar("weight", dimless, 1e-2),
zeroGradientFvPatchScalarField::typeName
);
meshSearch cellSearch(bMesh, polyMesh::FACEPLANES);
labelList cellVertices(bMesh.nCells(), 0);
for
(
typename Triangulation::Finite_vertices_iterator vit
= mesh.finite_vertices_begin();
vit != mesh.finite_vertices_end();
++vit
)
{
// Only store real vertices that are not feature vertices
if (vit->real() && !vit->featurePoint())
{
pointFromPoint v = topoint(vit->point());
label cellI = cellSearch.findCell(v);
if (cellI == -1)
{
// Pout<< "findCell conformalVoronoiMesh::distribute "
// << "findCell "
// << vit->type() << " "
// << vit->index() << " "
// << v << " "
// << cellI
// << " find nearest cellI ";
cellI = cellSearch.findNearestCell(v);
}
cellVertices[cellI]++;
}
}
forAll(cellVertices, cI)
{
// Give a small but finite weight for empty cells. Some
// decomposition methods have difficulty with integer overflows in
// the sum of the normalised weight field.
cellWeights.internalField()[cI] = max
(
cellVertices[cI],
1e-2
);
}
autoPtr<mapDistributePolyMesh> mapDist = decomposition_().distribute
(
cellWeights
);
cellShapeControl_.shapeControlMesh().distribute(decomposition_);
distribute();
timeCheck("After distribute");
iteration++;
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indexedCell.H"
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
template<class Gt, class Cb>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const InfoProxy<CGAL::indexedCell<Gt, Cb> >& p
)
{
const CGAL::indexedCell<Gt, Cb>& iv = p.t_;
os << "Cell: ";
if (iv.index_ == CGAL::indexedCell<Gt, Cb>::ctFar)
{
os << "far";
}
else if (iv.index_ >= 0)
{
os << iv.index_;
}
else if (iv.index_ == CGAL::indexedCell<Gt, Cb>::ctInternal)
{
os << "internal";
}
else if (iv.index_ == CGAL::indexedCell<Gt, Cb>::ctSurface)
{
os << "surface";
}
else if (iv.index_ == CGAL::indexedCell<Gt, Cb>::ctFeatureEdge)
{
os << "featureEdge";
}
else if (iv.index_ == CGAL::indexedCell<Gt, Cb>::ctFeaturePoint)
{
os << "featurePoint";
}
else
{
os << "unassigned";
}
if (iv.parallelDualVertex())
{
os << " (processor)";
}
else
{
os << " (local)";
}
os << " filterCount: " << iv.filterCount_ << nl;
os << " " << iv.vertex(0)->info();
os << " " << iv.vertex(1)->info();
os << " " << iv.vertex(2)->info();
os << " " << iv.vertex(3)->info();
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,271 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
indexedCell
Description
An indexed form of CGAL::Triangulation_cell_base_3<K> used to keep
track of the Delaunay cells (tets) in the tessellation.
SourceFiles
indexedCellI.H
indexedCell.C
\*---------------------------------------------------------------------------*/
#ifndef indexedCell_H
#define indexedCell_H
#include <CGAL/Triangulation_3.h>
#include <CGAL/Triangulation_cell_base_with_circumcenter_3.h>
#include "indexedVertex.H"
#include "List.H"
#include "globalIndex.H"
#include "Pstream.H"
#include "Swap.H"
#include "InfoProxy.H"
#include "tetCell.H"
#include "typeInfo.H"
#include "vectorTools.H"
#include "indexedCellEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace CGAL
{
template<class Gt, class Cb> class indexedCell;
}
namespace Foam
{
class Ostream;
template<class Gt, class Cb> Ostream& operator<<
(
Ostream&,
const Foam::InfoProxy<CGAL::indexedCell<Gt, Cb> >&
);
}
namespace CGAL
{
/*---------------------------------------------------------------------------*\
Class indexedCell Declaration
\*---------------------------------------------------------------------------*/
template
<
class Gt,
class Cb=CGAL::Triangulation_cell_base_with_circumcenter_3<Gt>
>
class indexedCell
:
public Foam::indexedCellEnum,
public Cb
{
// Private data
//- The index for this Delaunay tetrahedral cell. Type information is
//- also carried:
// ctFar : the dual point of this cell does not form part of the
// internal or boundary of the dual mesh
// >=0 : the (local) index of an internal or boundary dual point,
// not on a processor face
// < 0 && > ctFar : the (global) index of a dual point on a processor
// face
int index_;
//- The number of times that this Delaunay cell has been limited
// during filtering
int filterCount_;
// Private member functions
//- Same as globallyOrderedCellVertices but without sorting
Foam::tetCell unsortedVertexGlobalIndices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const;
public:
typedef typename Cb::Triangulation_data_structure Tds;
typedef typename Cb::Vertex_handle Vertex_handle;
typedef typename Cb::Cell_handle Cell_handle;
template<typename TDS2>
struct Rebind_TDS
{
typedef typename Cb::template Rebind_TDS<TDS2>::Other Cb2;
typedef indexedCell<Gt, Cb2> Other;
};
// Constructors
inline indexedCell();
inline indexedCell
(
Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
Vertex_handle v3
);
inline indexedCell
(
Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
Vertex_handle v3,
Cell_handle n0,
Cell_handle n1,
Cell_handle n2,
Cell_handle n3
);
// Member Functions
inline int& cellIndex();
inline int cellIndex() const;
#ifdef CGAL_INEXACT
inline const Foam::point& dual();
#else
inline const Foam::point dual();
#endif
inline bool unassigned() const;
inline int& filterCount();
inline int filterCount() const;
//- Is the Delaunay cell real, i.e. any real vertex
inline bool real() const;
//- Does the Delaunay cell have a far point
inline bool hasFarPoint() const;
//- Does the Delaunay cell have a feature point
inline bool hasFeaturePoint() const;
//- Does the Delaunay cell have a seed point
inline bool hasSeedPoint() const;
inline bool hasInternalPoint() const;
inline bool hasConstrainedPoint() const;
//- Does the Dual vertex form part of a processor patch
inline bool parallelDualVertex() const;
//- Does the Dual vertex form part of a processor patch
inline Foam::label dualVertexMasterProc() const;
inline Foam::FixedList<Foam::label, 4> processorsAttached() const;
//- Using the globalIndex object, return a list of four (sorted) global
// Delaunay vertex indices that uniquely identify this tet in parallel
inline Foam::tetCell vertexGlobalIndices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const;
//- Using the globalIndex object, return a list of four vertices with
// so that the cell has a consistent orientation in parallel.
inline Foam::FixedList<Foam::label, 4> globallyOrderedCellVertices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const;
//- Is the Delaunay cell part of the final dual mesh, i.e. any vertex
// form part of the internal or boundary definition
inline bool internalOrBoundaryDualVertex() const;
//- Is the Delaunay cell real or referred (or mixed), i.e. all vertices
// form part of the real or referred internal or boundary definition
inline bool anyInternalOrBoundaryDualVertex() const;
//- A dual vertex on the boundary will result from a Delaunay cell with
// least one Delaunay vertex outside and at least one inside
inline bool boundaryDualVertex() const;
//- A dual vertex on a feature edge will result from this Delaunay cell
inline bool featureEdgeDualVertex() const;
//- A dual vertex on a feature point will result from this Delaunay cell
inline bool featurePointDualVertex() const;
inline bool nearProcBoundary() const;
inline bool potentialCoplanarCell() const;
inline bool featurePointExternalCell() const;
inline bool featurePointInternalCell() const;
// Info
//- Return info proxy.
// Used to print indexedCell information to a stream
Foam::InfoProxy<indexedCell<Gt, Cb> > info() const
{
return *this;
}
friend Foam::Ostream& Foam::operator<< <Gt, Cb>
(
Foam::Ostream&,
const Foam::InfoProxy<indexedCell<Gt, Cb> >&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace CGAL
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "indexedCellI.H"
#ifdef NoRepository
# include "indexedCell.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "plane.H"
#include "tetrahedron.H"
#include "pointConversion.H"
#include "CGALTriangulation3DKernel.H"
template<typename Cell>
Foam::scalar Foam::foamyHexMeshChecks::coplanarTet
(
Cell& c,
const scalar tol
)
{
tetPointRef tet
(
topoint(c->vertex(0)->point()),
topoint(c->vertex(1)->point()),
topoint(c->vertex(2)->point()),
topoint(c->vertex(3)->point())
);
const scalar quality = tet.quality();
if (quality < tol)
{
return quality;
}
return 0;
// plane triPlane
// (
// topoint(c->vertex(0)->point()),
// topoint(c->vertex(1)->point()),
// topoint(c->vertex(2)->point())
// );
//
// const scalar distance = triPlane.distance(topoint(c->vertex(3)->point()));
//
// // Check if the four points are roughly coplanar. If they are then we
// // cannot calculate the circumcentre. Better test might be the volume
// // of the tet.
// if (distance < tol)
// {
// return 0;
// }
//
// return distance;
}
template<typename Cell>
bool Foam::foamyHexMeshChecks::closePoints
(
Cell& c,
const scalar tol
)
{
for (label v = 0; v < 4; ++v)
{
for (label vA = v + 1; vA < 4; ++vA)
{
if
(
mag
(
topoint(c->vertex(v)->point())
- topoint(c->vertex(vA)->point())
)
< tol
)
{
return true;
}
}
}
return false;
}
template<typename Cell>
bool Foam::foamyHexMeshChecks::smallVolume
(
Cell& c,
const scalar tol
)
{
CGAL::Tetrahedron_3<baseK> tet
(
c->vertex(0)->point(),
c->vertex(1)->point(),
c->vertex(2)->point(),
c->vertex(3)->point()
);
if (tet.volume() < tol)
{
return true;
}
return false;
}

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef indexedCellChecks_H
#define indexedCellChecks_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace foamyHexMeshChecks
{
template<typename Cell>
scalar coplanarTet
(
Cell& c,
const scalar tol = 1e-12
);
template<typename Cell>
bool closePoints
(
Cell& c,
const scalar tol = 1e-12
);
template<typename Cell>
bool smallVolume
(
Cell& c,
const scalar tol = 0.0
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace foamyHexMeshChecks
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "indexedCellChecks.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indexedCellEnum.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<>
const char*
Foam::NamedEnum<Foam::indexedCellEnum::cellTypes, 6>::names[] =
{
"Unassigned",
"Internal",
"Surface",
"FeatureEdge",
"FeaturePoint",
"Far"
};
const Foam::NamedEnum<Foam::indexedCellEnum::cellTypes, 6>
cellTypesNames_;
// ************************************************************************* //

View File

@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
indexedCellEnum
Description
SourceFiles
indexedCellEnum.C
\*---------------------------------------------------------------------------*/
#ifndef indexedCellEnum_H
#define indexedCellEnum_H
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class indexedCellEnum
{
public:
enum cellTypes
{
ctUnassigned = INT_MIN,
ctFar = INT_MIN + 1,
ctInternal = INT_MIN + 2,
ctSurface = INT_MIN + 3,
ctFeatureEdge = INT_MIN + 4,
ctFeaturePoint = INT_MIN + 5
};
static const Foam::NamedEnum<cellTypes, 6> cellTypesNames_;
};
template<>
inline bool contiguous<indexedCellEnum>()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,688 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
//#include "indexedCellChecks.H"
template<class Gt, class Cb>
Foam::tetCell CGAL::indexedCell<Gt, Cb>::unsortedVertexGlobalIndices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const
{
Foam::tetCell tVGI;
for (int i = 0; i < 4; i++)
{
Vertex_handle v = this->vertex(i);
// Finding the global index of each Delaunay vertex
tVGI[i] = globalDelaunayVertexIndices.toGlobal
(
Foam::Pstream::myProcNo(),
v->index()
);
}
return tVGI;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Gt, class Cb>
CGAL::indexedCell<Gt, Cb>::indexedCell()
:
Cb(),
index_(ctUnassigned),
filterCount_(0)
{}
template<class Gt, class Cb>
CGAL::indexedCell<Gt, Cb>::indexedCell
(
Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3
)
:
Cb(v0, v1, v2, v3),
index_(ctUnassigned),
filterCount_(0)
{}
template<class Gt, class Cb>
CGAL::indexedCell<Gt, Cb>::indexedCell
(
Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
Vertex_handle v3,
Cell_handle n0,
Cell_handle n1,
Cell_handle n2,
Cell_handle n3
)
:
Cb(v0, v1, v2, v3, n0, n1, n2, n3),
index_(ctUnassigned),
filterCount_(0)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Gt, class Cb>
int& CGAL::indexedCell<Gt, Cb>::cellIndex()
{
return index_;
}
template<class Gt, class Cb>
int CGAL::indexedCell<Gt, Cb>::cellIndex() const
{
return index_;
}
#ifdef CGAL_INEXACT
template<class Gt, class Cb>
const Foam::point& CGAL::indexedCell<Gt, Cb>::dual()
{
// if (Foam::foamyHexMeshChecks::coplanarTet(*this, 1e-20) == 0)
// {
// Do exact calc
// }
return reinterpret_cast<const Foam::point&>(this->circumcenter());
}
#else
template<class Gt, class Cb>
const Foam::point CGAL::indexedCell<Gt, Cb>::dual()
{
const typename Gt::Point_3& P = this->circumcenter();
return Foam::point
(
CGAL::to_double(P.x()),
CGAL::to_double(P.y()),
CGAL::to_double(P.z())
);
}
#endif
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::unassigned() const
{
return index_ == ctUnassigned;
}
template<class Gt, class Cb>
inline int& CGAL::indexedCell<Gt, Cb>::filterCount()
{
return filterCount_;
}
template<class Gt, class Cb>
inline int CGAL::indexedCell<Gt, Cb>::filterCount() const
{
return filterCount_;
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::real() const
{
return
(
(
this->vertex(0)->real()
|| this->vertex(1)->real()
|| this->vertex(2)->real()
|| this->vertex(3)->real()
)
&&
!(
this->vertex(0)->farPoint()
|| this->vertex(1)->farPoint()
|| this->vertex(2)->farPoint()
|| this->vertex(3)->farPoint()
)
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::hasFarPoint() const
{
return
(
this->vertex(0)->farPoint()
|| this->vertex(1)->farPoint()
|| this->vertex(2)->farPoint()
|| this->vertex(3)->farPoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::hasFeaturePoint() const
{
return
(
this->vertex(0)->featurePoint()
|| this->vertex(1)->featurePoint()
|| this->vertex(2)->featurePoint()
|| this->vertex(3)->featurePoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::hasSeedPoint() const
{
return
(
this->vertex(0)->seedPoint()
|| this->vertex(1)->seedPoint()
|| this->vertex(2)->seedPoint()
|| this->vertex(3)->seedPoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::hasInternalPoint() const
{
return
(
this->vertex(0)->internalPoint()
|| this->vertex(1)->internalPoint()
|| this->vertex(2)->internalPoint()
|| this->vertex(3)->internalPoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::hasConstrainedPoint() const
{
return
(
this->vertex(0)->constrained()
|| this->vertex(1)->constrained()
|| this->vertex(2)->constrained()
|| this->vertex(3)->constrained()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::parallelDualVertex() const
{
return
(
!this->hasFarPoint()
&&
(
this->vertex(0)->referred()
|| this->vertex(1)->referred()
|| this->vertex(2)->referred()
|| this->vertex(3)->referred()
)
&&
(
this->vertex(0)->real()
|| this->vertex(1)->real()
|| this->vertex(2)->real()
|| this->vertex(3)->real()
)
);
}
template<class Gt, class Cb>
inline Foam::label CGAL::indexedCell<Gt, Cb>::dualVertexMasterProc() const
{
if (!parallelDualVertex())
{
return -1;
}
// The master processor is the lowest numbered of the four on this tet.
int masterProc = Foam::Pstream::nProcs() + 1;
for (int i = 0; i < 4; i++)
{
if (this->vertex(i)->referred())
{
masterProc = min(masterProc, this->vertex(i)->procIndex());
}
else
{
masterProc = min(masterProc, Foam::Pstream::myProcNo());
}
}
return masterProc;
}
template<class Gt, class Cb>
inline Foam::FixedList<Foam::label, 4>
CGAL::indexedCell<Gt, Cb>::processorsAttached() const
{
if (!parallelDualVertex())
{
return Foam::FixedList<Foam::label, 4>(Foam::Pstream::myProcNo());
}
Foam::FixedList<Foam::label, 4> procsAttached
(
Foam::Pstream::myProcNo()
);
for (int i = 0; i < 4; i++)
{
if (this->vertex(i)->referred())
{
procsAttached[i] = this->vertex(i)->procIndex();
}
}
return procsAttached;
}
template<class Gt, class Cb>
inline Foam::tetCell CGAL::indexedCell<Gt, Cb>::vertexGlobalIndices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const
{
// tetVertexGlobalIndices
Foam::tetCell tVGI
= unsortedVertexGlobalIndices(globalDelaunayVertexIndices);
// bubble sort
for (int i = 0; i < tVGI.size(); i++)
{
for (int j = tVGI.size() - 1 ; j > i; j--)
{
if (tVGI[j - 1] > tVGI[j])
{
Foam::Swap(tVGI[j - 1], tVGI[j]);
}
}
}
return tVGI;
}
template<class Gt, class Cb>
inline Foam::FixedList<Foam::label, 4>
CGAL::indexedCell<Gt, Cb>::globallyOrderedCellVertices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const
{
// tetVertexGlobalIndices
Foam::tetCell tVGI
= unsortedVertexGlobalIndices(globalDelaunayVertexIndices);
Foam::FixedList<Foam::label, 4> vertexMap(Foam::identity(4));
// bubble sort
for (int i = 0; i < tVGI.size(); i++)
{
for (int j = tVGI.size() - 1 ; j > i; j--)
{
if (tVGI[j - 1] > tVGI[j])
{
Foam::Swap(tVGI[j - 1], tVGI[j]);
Foam::Swap(vertexMap[j - 1], vertexMap[j]);
}
}
}
for (int i = 0; i < 4; i++)
{
tVGI[i] = vertexMap[i];
}
return tVGI;
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::internalOrBoundaryDualVertex() const
{
return
(
this->vertex(0)->internalOrBoundaryPoint()
|| this->vertex(1)->internalOrBoundaryPoint()
|| this->vertex(2)->internalOrBoundaryPoint()
|| this->vertex(3)->internalOrBoundaryPoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::anyInternalOrBoundaryDualVertex() const
{
return
(
this->vertex(0)->internalOrBoundaryPoint()
|| this->vertex(0)->externalBoundaryPoint()
|| this->vertex(1)->internalOrBoundaryPoint()
|| this->vertex(1)->externalBoundaryPoint()
|| this->vertex(2)->internalOrBoundaryPoint()
|| this->vertex(2)->externalBoundaryPoint()
|| this->vertex(3)->internalOrBoundaryPoint()
|| this->vertex(3)->externalBoundaryPoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::boundaryDualVertex() const
{
return
(
(
this->vertex(0)->internalBoundaryPoint()
|| this->vertex(1)->internalBoundaryPoint()
|| this->vertex(2)->internalBoundaryPoint()
|| this->vertex(3)->internalBoundaryPoint()
)
&& (
this->vertex(0)->externalBoundaryPoint()
|| this->vertex(1)->externalBoundaryPoint()
|| this->vertex(2)->externalBoundaryPoint()
|| this->vertex(3)->externalBoundaryPoint()
)
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::featureEdgeDualVertex() const
{
return
(
this->vertex(0)->featureEdgePoint()
&& this->vertex(1)->featureEdgePoint()
&& this->vertex(2)->featureEdgePoint()
&& this->vertex(3)->featureEdgePoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::featurePointDualVertex() const
{
return
(
this->vertex(0)->featurePoint()
&& this->vertex(1)->featurePoint()
&& this->vertex(2)->featurePoint()
&& this->vertex(3)->featurePoint()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::nearProcBoundary() const
{
return
(
this->vertex(0)->nearProcBoundary()
|| this->vertex(1)->nearProcBoundary()
|| this->vertex(2)->nearProcBoundary()
|| this->vertex(3)->nearProcBoundary()
);
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::potentialCoplanarCell() const
{
Foam::label nMasters = 0;
Foam::label nSlaves = 0;
Vertex_handle vM[2];
Vertex_handle vS[2];
for (Foam::label i = 0; i < 4; ++i)
{
Vertex_handle v = this->vertex(i);
if (v->internalBoundaryPoint())
{
vM[nMasters] = v;
nMasters++;
}
if (v->externalBoundaryPoint())
{
vS[nSlaves] = v;
nSlaves++;
}
}
Foam::label nPairs = 0;
if (nMasters == 2 && nSlaves == 2)
{
Foam::vector vp0(Foam::vector::zero);
Foam::vector vp1(Foam::vector::zero);
if
(
vM[0]->type() == vS[0]->index()
&& vM[0]->index() == vS[0]->type()
)
{
vp0 = reinterpret_cast<const Foam::point&>(vM[0]->point())
- reinterpret_cast<const Foam::point&>(vS[0]->point());
nPairs++;
}
else if
(
vM[0]->type() == vS[1]->index()
&& vM[0]->index() == vS[1]->type()
)
{
vp0 = reinterpret_cast<const Foam::point&>(vM[0]->point())
- reinterpret_cast<const Foam::point&>(vS[1]->point());
nPairs++;
}
if
(
vM[1]->type() == vS[0]->index()
&& vM[1]->index() == vS[0]->type()
)
{
vp1 = reinterpret_cast<const Foam::point&>(vM[1]->point())
- reinterpret_cast<const Foam::point&>(vS[0]->point());
nPairs++;
}
else if
(
vM[1]->type() == vS[1]->index()
&& vM[1]->index() == vS[1]->type()
)
{
vp1 = reinterpret_cast<const Foam::point&>(vM[1]->point())
- reinterpret_cast<const Foam::point&>(vS[1]->point());
nPairs++;
}
if (nPairs == 2)
{
if (Foam::vectorTools::areParallel(vp0, vp1))
{
Foam::Pout<< "PARALLEL" << Foam::endl;
return true;
}
}
}
return false;
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::featurePointExternalCell() const
{
int featureVertex = -1;
for (int i = 0; i < 4; ++i)
{
if (this->vertex(i)->constrained())
{
featureVertex = i;
}
}
// Pick cell with a face attached to an infinite cell
if (featureVertex != -1)
{
Vertex_handle v1 =
this->vertex(Tds::vertex_triple_index(featureVertex, 0));
Vertex_handle v2 =
this->vertex(Tds::vertex_triple_index(featureVertex, 1));
Vertex_handle v3 =
this->vertex(Tds::vertex_triple_index(featureVertex, 2));
if (v1->internalBoundaryPoint())
{
if
(
v2->externalBoundaryPoint()
&& v3->externalBoundaryPoint()
)
{
return true;
}
}
else if (v2->internalBoundaryPoint())
{
if
(
v1->externalBoundaryPoint()
&& v3->externalBoundaryPoint()
)
{
return true;
}
}
else if (v3->internalBoundaryPoint())
{
if
(
v1->externalBoundaryPoint()
&& v2->externalBoundaryPoint()
)
{
return true;
}
}
}
return false;
}
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::featurePointInternalCell() const
{
int featureVertex = -1;
for (int i = 0; i < 4; ++i)
{
if (this->vertex(i)->constrained())
{
featureVertex = i;
}
}
// Pick cell with a face attached to an infinite cell
if (featureVertex != -1)
{
Vertex_handle v1 =
this->vertex(Tds::vertex_triple_index(featureVertex, 0));
Vertex_handle v2 =
this->vertex(Tds::vertex_triple_index(featureVertex, 1));
Vertex_handle v3 =
this->vertex(Tds::vertex_triple_index(featureVertex, 2));
if (v1->externalBoundaryPoint())
{
if
(
v2->internalBoundaryPoint()
&& v3->internalBoundaryPoint()
)
{
return true;
}
}
else if (v2->externalBoundaryPoint())
{
if
(
v1->internalBoundaryPoint()
&& v3->internalBoundaryPoint()
)
{
return true;
}
}
else if (v3->externalBoundaryPoint())
{
if
(
v1->internalBoundaryPoint()
&& v2->internalBoundaryPoint()
)
{
return true;
}
}
}
return false;
}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //

View File

@ -0,0 +1,197 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indexedVertex.H"
#include "point.H"
#include "Istream.H"
#include "Ostream.H"
#include "OStringStream.H"
#include "IStringStream.H"
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
Foam::Istream& Foam::operator>>
(
Istream& is,
CGAL::Point_3<baseK>& p
)
{
// string data(is);
//
// std::istringstream stdIs;
//
// CGAL::set_ascii_mode(stdIs);
//
// stdIs.str(data);
//
// CGAL::Gmpz xNumer, xDenom;
// CGAL::Gmpz yNumer, yDenom;
// CGAL::Gmpz zNumer, zDenom;
//
// stdIs >> xNumer >> xDenom >> yNumer >> yDenom >> zNumer >> zDenom;
//
// CGAL::Gmpq x(xNumer, xDenom);
// CGAL::Gmpq y(yNumer, yDenom);
// CGAL::Gmpq z(zNumer, zDenom);
//
// p = CGAL::Point_3<baseK>
// (
// CGAL::to_double(x),
// CGAL::to_double(y),
// CGAL::to_double(z)
// );
Foam::point pt;
is >> pt.x() >> pt.y() >> pt.z();
p = CGAL::Point_3<baseK>
(
pt.x(),
pt.y(),
pt.z()
);
return is;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const CGAL::Point_3<baseK>& p
)
{
// CGAL::Gmpq x(CGAL::to_double(p.x()));
// CGAL::Gmpq y(CGAL::to_double(p.y()));
// CGAL::Gmpq z(CGAL::to_double(p.z()));
//
// std::ostringstream stdOs;
//
// CGAL::set_ascii_mode(stdOs);
//
// stdOs<< x.numerator() << ' ' << x.denominator() << ' '
// << y.numerator() << ' ' << y.denominator() << ' '
// << z.numerator() << ' ' << z.denominator();
//
// os << stdOs.str();
os << CGAL::to_double(p.x()) << ' '
<< CGAL::to_double(p.y()) << ' '
<< CGAL::to_double(p.z());
return os;
}
template<class Gt, class Vb>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const CGAL::indexedVertex<Gt, Vb>& p
)
{
os << p.point() << ' '
<< p.index() << ' '
<< static_cast<int>(p.type()) << ' '
<< p.procIndex() << ' '
<< p.alignment() << ' '
<< p.targetCellSize() << ' '
<< static_cast<int>(p.fixed());
return os;
}
template<class Gt, class Vb>
Foam::Istream& Foam::operator>>
(
Istream& is,
CGAL::indexedVertex<Gt, Vb>& p
)
{
is >> p.point()
>> p.index();
int type;
is >> type;
p.type() = static_cast<Foam::indexedVertexEnum::vertexType>(type);
is >> p.procIndex()
>> p.alignment()
>> p.targetCellSize();
int fixed;
is >> fixed;
p.fixed() = static_cast<bool>(fixed);
return is;
}
template<class Gt, class Vb>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const InfoProxy<CGAL::indexedVertex<Gt, Vb> >& p
)
{
const CGAL::indexedVertex<Gt, Vb>& iv = p.t_;
const Foam::point pt
(
CGAL::to_double(iv.point().x()),
CGAL::to_double(iv.point().y()),
CGAL::to_double(iv.point().z())
);
string fixed
(
iv.vertexFixed_
? string(" fixed, ")
: string(" free, ")
);
string referred
(
Pstream::myProcNo() == iv.processor_
? string(" (local)")
: string(" (from " + name(iv.processor_) + ")")
);
os << iv.index_ << " "
<< CGAL::indexedVertex<Gt, Vb>::vertexTypeNames_[iv.type_]
<< " at:" << pt
<< " size:" << iv.targetCellSize_
<< " alignment:" << iv.alignment_
<< fixed
<< referred.c_str()
<< endl;
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,367 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
indexedVertex
Description
An indexed form of CGAL::Triangulation_vertex_base_3<K> used to keep
track of the Delaunay vertices in the tessellation.
SourceFiles
indexedVertexI.H
indexedVertex.C
\*---------------------------------------------------------------------------*/
#ifndef indexedVertex_H
#define indexedVertex_H
#include <CGAL/Triangulation_3.h>
#include "CGALTriangulation3DKernel.H"
#include "tensor.H"
#include "triad.H"
#include "InfoProxy.H"
#include "point.H"
#include "indexedVertexEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace CGAL
{
template<class Gt, class Vb> class indexedVertex;
}
namespace Foam
{
class Ostream;
class Istream;
template<class Gt, class Vb> Ostream& operator<<
(
Ostream&,
const Foam::InfoProxy<CGAL::indexedVertex<Gt, Vb> >&
);
template<class Gt, class Vb> Ostream& operator<<
(
Ostream&,
const CGAL::indexedVertex<Gt, Vb>&
);
template<class Gt, class Vb> Istream& operator>>
(
Istream&,
CGAL::indexedVertex<Gt, Vb>&
);
inline Istream& operator>>
(
Istream& is,
CGAL::Point_3<baseK>& p
);
inline Ostream& operator<<
(
Ostream& os,
const CGAL::Point_3<baseK>& p
);
} // End namespace Foam
namespace CGAL
{
/*---------------------------------------------------------------------------*\
Class indexedVertex Declaration
\*---------------------------------------------------------------------------*/
template<class Gt, class Vb = CGAL::Triangulation_vertex_base_3<Gt> >
class indexedVertex
:
public Foam::indexedVertexEnum,
public Vb
{
// Private data
//- Type of pair-point
vertexType type_;
//- The index for this Delaunay vertex. For referred vertices, the
// index is negative for vertices that are the outer (slave) of point
// pairs
int index_;
//- Number of the processor that owns this vertex
int processor_;
//- Required alignment of the dual cell of this vertex
Foam::tensor alignment_;
//- Target size of the dual cell of this vertex
Foam::scalar targetCellSize_;
//- Specify whether the vertex is fixed or movable.
bool vertexFixed_;
public:
typedef typename Vb::Triangulation_data_structure Tds;
typedef typename Vb::Point Point;
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Cell_handle Cell_handle;
template<typename TDS2>
struct Rebind_TDS
{
typedef typename Vb::template Rebind_TDS<TDS2>::Other Vb2;
typedef indexedVertex<Gt,Vb2> Other;
};
// Constructors
inline indexedVertex();
inline indexedVertex(const Point& p);
inline indexedVertex(const Point& p, vertexType type);
inline indexedVertex(const Foam::point& p, vertexType type);
inline indexedVertex
(
const Point& p,
int index,
vertexType type,
int processor
);
inline indexedVertex
(
const Foam::point& p,
int index,
vertexType type,
int processor
);
inline indexedVertex(const Point& p, Cell_handle f);
inline indexedVertex(Cell_handle f);
// Member Functions
inline int& index();
inline int index() const;
inline vertexType& type();
inline vertexType type() const;
inline Foam::tensor& alignment();
inline const Foam::tensor& alignment() const;
inline Foam::scalar& targetCellSize();
inline Foam::scalar targetCellSize() const;
inline bool uninitialised() const;
//- Is point a far-point
inline bool farPoint() const;
//- Is point internal, i.e. not on boundary
inline bool internalPoint() const;
//- Is this a referred vertex
inline bool referred() const;
//- Is this a "real" point on this processor, i.e. is internal or part
// of the boundary description, and not a "far" or "referred" point
inline bool real() const;
// For referred vertices, what is the original processor index
inline int procIndex() const;
// For referred vertices, set the original processor index
inline int& procIndex();
//- Set the point to be internal
inline void setInternal();
//- Is point internal and near the boundary
inline bool nearBoundary() const;
//- Set the point to be near the boundary
inline void setNearBoundary();
//- Is point internal and near a proc boundary
inline bool nearProcBoundary() const;
//- Set the point to be near a proc boundary
inline void setNearProcBoundary();
//- Either master or slave of pointPair.
inline bool boundaryPoint() const;
//- Either original internal point or master of pointPair.
inline bool internalOrBoundaryPoint() const;
//- Is point near the boundary or part of the boundary definition
inline bool nearOrOnBoundary() const;
//- Part of a feature point
inline bool featurePoint() const;
//- Part of a feature edge
inline bool featureEdgePoint() const;
//- Part of a surface point pair
inline bool surfacePoint() const;
inline bool internalBoundaryPoint() const;
inline bool externalBoundaryPoint() const;
inline bool constrained() const;
//- Is the vertex fixed or movable
inline bool fixed() const;
//- Fix the vertex so that it can't be moved
inline bool& fixed();
inline indexedVertex& operator=(const indexedVertex& rhs)
{
Vb::operator=(rhs);
this->type_ = rhs.type();
this->index_ = rhs.index();
this->processor_ = rhs.procIndex();
this->alignment_ = rhs.alignment();
this->targetCellSize_ = rhs.targetCellSize();
this->vertexFixed_ = rhs.fixed();
return *this;
}
inline bool operator==(const indexedVertex& rhs) const
{
return
(
//this->point() == rhs.point()
this->type_ == rhs.type()
&& this->index_ == rhs.index()
&& this->processor_ == rhs.procIndex()
&& this->vertexFixed_ == rhs.fixed()
);
}
inline bool operator!=(const indexedVertex& rhs) const
{
return !(*this == rhs);
}
// Info
//- Return info proxy.
// Used to print indexedVertex information to a stream
Foam::InfoProxy<indexedVertex<Gt, Vb> > info() const
{
return *this;
}
friend Foam::Ostream& Foam::operator<< <Gt, Vb>
(
Foam::Ostream&,
const Foam::InfoProxy<indexedVertex<Gt, Vb> >&
);
friend Foam::Ostream& Foam::operator<< <Gt, Vb>
(
Foam::Ostream&,
const indexedVertex<Gt, Vb>&
);
friend Foam::Istream& Foam::operator>> <Gt, Vb>
(
Foam::Istream&,
indexedVertex<Gt, Vb>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace CGAL
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
#ifdef CGAL_INEXACT
namespace Foam
{
// For inexact representations where the storage type is a double, the data
// is contiguous. This may not be true for exact number types.
template<>
inline bool contiguous
<
CGAL::indexedVertex
<
K,
CGAL::Triangulation_vertex_base_3<K>
>
>()
{
return true;
}
template<>
inline bool contiguous<CGAL::Triangulation_vertex_base_3<K>::Point>()
{
return true;
}
} // End namespace Foam
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "indexedVertexI.H"
#ifdef NoRepository
# include "indexedVertex.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indexedVertexEnum.H"
#include "Pstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<>
const char*
Foam::NamedEnum<Foam::indexedVertexEnum::vertexType, 11>::names[] =
{
"Unassigned",
"Internal",
"InternalNearBoundary",
"InternalSurface",
"InternalFeatureEdge",
"InternalFeaturePoint",
"ExternalSurface",
"ExternalFeatureEdge",
"ExternalFeaturePoint",
"Far",
"Constrained"
};
const Foam::NamedEnum<Foam::indexedVertexEnum::vertexType, 11>
Foam::indexedVertexEnum::vertexTypeNames_;
template<>
const char*
Foam::NamedEnum<Foam::indexedVertexEnum::vertexMotion, 2>::names[] =
{
"fixed",
"movable"
};
const Foam::NamedEnum<Foam::indexedVertexEnum::vertexMotion, 2>
vertexMotionNames_;
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const Foam::indexedVertexEnum::vertexType& v
)
{
os << static_cast<int>(v);
return os;
}
Foam::Istream& Foam::operator>>
(
Istream& is,
Foam::indexedVertexEnum::vertexType& v
)
{
int type;
is >> type;
v = static_cast<Foam::indexedVertexEnum::vertexType>(type);
return is;
}
// ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ 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 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
indexedVertexEnum
Description
SourceFiles
indexedVertexEnum.C
\*---------------------------------------------------------------------------*/
#ifndef indexedVertexEnum_H
#define indexedVertexEnum_H
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class indexedVertexEnum
{
public:
enum vertexType
{
vtUnassigned = 0,
vtInternal = 1,
vtInternalNearBoundary = 2,
vtInternalSurface = 3,
vtInternalFeatureEdge = 4,
vtInternalFeaturePoint = 5,
vtExternalSurface = 6,
vtExternalFeatureEdge = 7,
vtExternalFeaturePoint = 8,
vtFar = 9,
vtConstrained = 10
};
enum vertexMotion
{
fixed = 0,
movable = 1
};
static const Foam::NamedEnum<vertexType, 11> vertexTypeNames_;
static const Foam::NamedEnum<vertexMotion, 2> vertexMotionNames_;
friend Ostream& operator<<(Foam::Ostream&, const vertexType&);
friend Istream& operator>>(Foam::Istream&, vertexType&);
};
template<>
inline bool contiguous<indexedVertexEnum>()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

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