ENH: Latest version of cvMesh. Squash of commits.

This commit is contained in:
laurence
2012-12-11 17:22:06 +00:00
parent 4cdb4a2c43
commit fd8eebab13
82 changed files with 14596 additions and 6319 deletions

View File

@ -4,7 +4,8 @@ set -x
wmake libso conformalVoronoiMesh
wmake
wmake cvMeshBackgroundMesh
#wmake cvMeshBackgroundMesh
(cd cvMeshSurfaceSimplify && ./Allwmake)
wmake cellSizeAndAlignmentGrid
# ----------------------------------------------------------------- end-of-file

View File

@ -2,7 +2,7 @@ EXE_DEBUG = -DFULLDEBUG -g -O0
EXE_FROUNDING_MATH = -frounding-math
EXE_NDEBUG = -DNDEBUG
CGAL_EXACT =
CGAL_EXACT = /*-DCGAL_DONT_USE_LAZY_KERNEL*/
CGAL_INEXACT = -DCGAL_INEXACT
include $(GENERAL_RULES)/CGAL
@ -19,7 +19,9 @@ EXE_INC = \
-I$(LIB_SRC)/edgeMesh/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-IvectorTools
EXE_LIBS = \
$(CGAL_LIBS) \
@ -32,4 +34,5 @@ EXE_LIBS = \
-ledgeMesh \
-lfileFormats \
-ltriSurface \
-ldynamicMesh
-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$(HOME)/OpenFOAM/OpenFOAM-dev/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/lnInclude \
-I$(HOME)/OpenFOAM/OpenFOAM-dev/applications/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,711 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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()] = triad
(
vit->alignment().x(),
vit->alignment().y(),
vit->alignment().z()
);
}
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;
}
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
label maxRefinementIterations = 0;
label maxSmoothingIterations = 200;
scalar minResidual = 0;
scalar defaultCellSize = 0.0004;
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()
);
}
}
else
{
CellSizeDelaunay::Vertex_handle vh = mesh.insert
(
points[pI],
defaultCellSize,
pointAlignment()
);
}
}
}
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
);
}
}
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->real())
{
const tensor& alignment = vit->alignment();
fixedAlignments[vit->index()] = triad
(
alignment.x(),
alignment.y(),
alignment.z()
);
}
}
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];
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();
// Enforce the boundary conditions
const triad& fixedAlignment = fixedAlignments[pI];
label nFixed = 0;
forAll(fixedAlignment, dirI)
{
if (fixedAlignment[dirI] != triad::unset[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];
}
}
}
if (newTriad.set(vector::X) && oldTriad.set(vector::X))
{
scalar dotProd = (oldTriad.x() & newTriad.x());
scalar diff = mag(dotProd) - 1.0;
residual += mag(diff);
}
if (newTriad.set(vector::Y) && oldTriad.set(vector::Y))
{
scalar dotProd = (oldTriad.y() & newTriad.y());
scalar diff = mag(dotProd) - 1.0;
residual += mag(diff);
}
if (newTriad.set(vector::Z) && oldTriad.set(vector::Z))
{
scalar dotProd = (oldTriad.z() & newTriad.z());
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,73 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
root "";
case "";
instance "";
local "";
class dictionary;
object meshQualityDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Maximum non-orthogonality allowed. Set to 180 to disable.
maxNonOrtho 65;
//- Max skewness allowed. Set to <0 to disable.
maxBoundarySkewness 50;
maxInternalSkewness 10;
//- Max concaveness allowed. Is angle (in degrees) below which concavity
// is allowed. 0 is straight face, <0 would be convex face.
// Set to 180 to disable.
maxConcave 80;
//- Minimum quality of the tet formed by the face-centre
// and variable base point minimum decomposition triangles and
// the cell centre. This has to be a positive number for tracking
// to work. Set to very negative number (e.g. -1E30) to
// disable.
// <0 = inside out tet,
// 0 = flat tet
// 1 = regular tet
minTetQuality 1e-30;
//- Minimum pyramid volume. Is absolute volume of cell pyramid.
// Set to a sensible fraction of the smallest cell volume expected.
// Set to very negative number (e.g. -1E30) to disable.
minVol 1e-20;
//- Minimum face area. Set to <0 to disable.
minArea -1;
//- Minimum face twist. Set to <-1 to disable. dot product of face normal
//- and face centre triangles normal
minTwist 0.001;
//- minimum normalised cell determinant
//- 1 = hex, <= 0 = folded or flattened illegal cell
minDeterminant 0.001;
//- minFaceWeight (0 -> 0.5)
minFaceWeight 0.02;
//- minVolRatio (0 -> 1)
minVolRatio 0.01;
//must be >0 for Fluent compatibility
minTriangleTwist -1;
// ************************************************************************* //

View File

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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;
this->clear();
resetVertexCount();
resetCellCount();
}
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,238 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::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,
labelList& patchSizes,
labelList& patchStarts,
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;
//- 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 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,406 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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,
labelList& patchSizes,
labelList& patchStarts,
const List<DynamicList<face> >& patchFaces,
const List<DynamicList<label> >& patchOwners
) const
{
label nPatches = patchFaces.size();
patchSizes.setSize(nPatches, -1);
patchStarts.setSize(nPatches, -1);
label nBoundaryFaces = 0;
forAll(patchFaces, p)
{
patchSizes[p] = patchFaces[p].size();
patchStarts[p] = nInternalFaces + nBoundaryFaces;
nBoundaryFaces += patchSizes[p];
}
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++;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//template<class Triangulation>
//Foam::DelaunayMesh<Triangulation>::DelaunayMesh(Istream& is)
//:
// base1(is),
// base2(is),
// member1(is),
// member2(is)
//{
// // Check state of Istream
// is.check("Foam::DelaunayMesh<Triangulation>::DelaunayMesh(Foam::Istream&)");
//}
// * * * * * * * * * * * * * * 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>
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, "cvMesh_defaultPatch");
wordList patchTypes(1, wallPolyPatch::typeName);
labelList patchSizes(1, 0);
labelList patchStarts(1, 0);
List<DynamicList<face> > patchFaces(1, DynamicList<face>());
List<DynamicList<label> > patchOwners(1, DynamicList<label>());
vertexMap.setSize(Triangulation::number_of_vertices());
cellMap.setSize(Triangulation::number_of_finite_cells());
// 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));
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);
addPatches
(
faceI,
faces,
owner,
patchSizes,
patchStarts,
patchFaces,
patchOwners
);
autoPtr<fvMesh> meshPtr
(
new fvMesh
(
IOobject
(
name,
runTime.timeName(),
runTime,
IOobject::NO_READ,
IOobject::NO_WRITE
),
xferMove(points),
xferMove(faces),
xferMove(owner),
xferMove(neighbour)
)
);
List<polyPatch*> patches(patchStarts.size());
label nValidPatches = 0;
forAll(patches, p)
{
patches[nValidPatches] = polyPatch::New
(
patchTypes[p],
patchNames[p],
patchSizes[p],
patchStarts[p],
nValidPatches,
meshPtr().boundaryMesh()
).ptr();
nValidPatches++;
}
patches.setSize(nValidPatches);
meshPtr().addFvPatches(patches);
return meshPtr;
}
// ************************************************************************* //

View File

@ -0,0 +1,932 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 scalar distFromBbSqr = bb.distanceFromBoxSqr
(
topoint(it->point())
);
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);
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();
}
uninserted.insert(labelPair(vert.procIndex(), vert.index()));
nNotInserted++;
continue;
}
// 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)
);
bool insert = false;
for (size_t i = 0; i < V.size(); ++i)
{
if (V[i]->real() || V[i]->hasFarPoint())
{
insert = true;
break;
}
}
if (insert)
{
hint = Triangulation::insert_in_hole
(
pointToInsert,
V.begin(),
V.end(),
f.first,
f.second
);
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,207 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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
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

@ -1,5 +1,8 @@
#include CGAL_FILES
conformalVoronoiMesh/indexedVertex/indexedVertexEnum.C
conformalVoronoiMesh/indexedCell/indexedCellEnum.C
conformalVoronoiMesh/conformalVoronoiMesh.C
conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
@ -13,7 +16,20 @@ conformationSurfaces/conformationSurfaces.C
backgroundMeshDecomposition/backgroundMeshDecomposition.C
cellSizeControlSurfaces/cellSizeControlSurfaces.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
/*cellSizeControlSurfaces/cellSizeControlSurfaces.C*/
cellSizeFunctions = cellSizeControlSurfaces/cellSizeFunction
$(cellSizeFunctions)/cellSizeFunction/cellSizeFunction.C

View File

@ -2,7 +2,7 @@ EXE_DEBUG = -DFULLDEBUG -g -O0
EXE_FROUNDING_MATH = -frounding-math
EXE_NDEBUG = -DNDEBUG
CGAL_EXACT =
CGAL_EXACT = /*-DCGAL_DONT_USE_LAZY_KERNEL*/
CGAL_INEXACT = -DCGAL_INEXACT
include $(GENERAL_RULES)/CGAL
@ -20,6 +20,8 @@ EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-IPrintTable \
-I../vectorTools
EXE_LIBS = \
@ -27,4 +29,5 @@ EXE_LIBS = \
-ledgeMesh \
-lfileFormats \
-ltriSurface \
-ldynamicMesh
-ldynamicMesh \
-lsampling

View File

@ -0,0 +1,241 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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<HashTable<DataType, KeyType> > procData
(
Pstream::nProcs(),
HashTable<DataType, KeyType>()
);
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 HashTable<DataType, KeyType>& procIData
= procData[procI];
for
(
typename HashTable<DataType, KeyType>
::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 #";
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,137 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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
{
// Private data
//- Hash table holding the data
HashTable<DataType, KeyType> 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 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

@ -25,6 +25,10 @@ License
#include "backgroundMeshDecomposition.H"
#include "meshSearch.H"
#include "conformationSurfaces.H"
#include "zeroGradientFvPatchFields.H"
#include "Time.H"
#include "Random.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -377,7 +381,7 @@ void Foam::backgroundMeshDecomposition::initialRefinement()
if (oldCellI == -1)
{
newVolumeStatus[newCellI] =
searchableSurface::UNKNOWN;;
searchableSurface::UNKNOWN;
}
else
{
@ -413,8 +417,10 @@ void Foam::backgroundMeshDecomposition::initialRefinement()
fvMeshDistribute distributor(mesh_, mergeDist_);
autoPtr<mapDistributePolyMesh> mapDist =
distributor.distribute(newDecomp);
autoPtr<mapDistributePolyMesh> mapDist = distributor.distribute
(
newDecomp
);
meshCutter_.distribute(mapDist);
@ -527,87 +533,87 @@ bool Foam::backgroundMeshDecomposition::refineCell
if (volType == searchableSurface::MIXED)
{
// Assess the cell size at the nearest point on the surface for the
// MIXED cells, if the cell is large with respect to the cell size,
// then refine it.
pointField samplePoints
(
volRes_*volRes_*volRes_,
vector::zero
);
// scalar sampleVol = cellBb.volume()/samplePoints.size();
vector delta = cellBb.span()/volRes_;
label pI = 0;
for (label i = 0; i < volRes_; i++)
{
for (label j = 0; j < volRes_; j++)
{
for (label k = 0; k < volRes_; k++)
{
samplePoints[pI++] =
cellBb.min()
+ vector
(
delta.x()*(i + 0.5),
delta.y()*(j + 0.5),
delta.z()*(k + 0.5)
);
}
}
}
List<pointIndexHit> hitInfo;
labelList hitSurfaces;
geometry.findSurfaceNearest
(
samplePoints,
scalarField(samplePoints.size(), sqr(GREAT)),
hitInfo,
hitSurfaces
);
// weightEstimate = 0.0;
scalar minCellSize = GREAT;
forAll(samplePoints, i)
{
scalar s = cellSizeControl_.cellSize
(
hitInfo[i].hitPoint()
);
// Info<< "cellBb.midpoint() " << cellBb.midpoint() << nl
// << samplePoints[i] << nl
// << hitInfo[i] << nl
// << "cellBb.span() " << cellBb.span() << nl
// << "cellBb.mag() " << cellBb.mag() << nl
// << s << endl;
if (s < minCellSize)
{
minCellSize = max(s, minCellSizeLimit_);
}
// Estimate the number of points in the cell by the surface size,
// this is likely to be too small, so reduce.
// weightEstimate += sampleVol/pow3(s);
}
if (sqr(spanScale_)*sqr(minCellSize) < magSqr(cellBb.span()))
{
return true;
}
// // Assess the cell size at the nearest point on the surface for the
// // MIXED cells, if the cell is large with respect to the cell size,
// // then refine it.
//
// pointField samplePoints
// (
// volRes_*volRes_*volRes_,
// vector::zero
// );
//
// // scalar sampleVol = cellBb.volume()/samplePoints.size();
//
// vector delta = cellBb.span()/volRes_;
//
// label pI = 0;
//
// for (label i = 0; i < volRes_; i++)
// {
// for (label j = 0; j < volRes_; j++)
// {
// for (label k = 0; k < volRes_; k++)
// {
// samplePoints[pI++] =
// cellBb.min()
// + vector
// (
// delta.x()*(i + 0.5),
// delta.y()*(j + 0.5),
// delta.z()*(k + 0.5)
// );
// }
// }
// }
//
// List<pointIndexHit> hitInfo;
// labelList hitSurfaces;
//
// geometry.findSurfaceNearest
// (
// samplePoints,
// scalarField(samplePoints.size(), sqr(GREAT)),
// hitInfo,
// hitSurfaces
// );
//
// // weightEstimate = 0.0;
//
// scalar minCellSize = GREAT;
//
// forAll(samplePoints, i)
// {
// scalar s = cellShapeControl_.cellSize
// (
// hitInfo[i].hitPoint()
// );
//
// // Info<< "cellBb.midpoint() " << cellBb.midpoint() << nl
// // << samplePoints[i] << nl
// // << hitInfo[i] << nl
// // << "cellBb.span() " << cellBb.span() << nl
// // << "cellBb.mag() " << cellBb.mag() << nl
// // << s << endl;
//
// if (s < minCellSize)
// {
// minCellSize = max(s, minCellSizeLimit_);
// }
//
// // Estimate the number of points in the cell by the surface size,
// // this is likely to be too small, so reduce.
// // weightEstimate += sampleVol/pow3(s);
// }
//
// if (sqr(spanScale_)*sqr(minCellSize) < magSqr(cellBb.span()))
// {
// return true;
// }
}
else if (volType == searchableSurface::INSIDE)
{
// scalar s = cvMesh_.cellSizeControl().cellSize(cellBb.midpoint());
// scalar s = cvMesh_.cellShapeControl_.cellSize(cellBb.midpoint());
// Estimate the number of points in the cell by the size at the cell
// midpoint
@ -724,9 +730,7 @@ void Foam::backgroundMeshDecomposition::buildPatchAndTree()
globalBackgroundBounds_ = treeBoundBox(bbMin, bbMax);
octreeNearestDistances_ = bFTreePtr_().calcNearestDistance();
if (cvMeshControls_.objOutput())
if (false)
{
OFstream fStr
(
@ -773,15 +777,15 @@ void Foam::backgroundMeshDecomposition::buildPatchAndTree()
Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
(
const dictionary& coeffsDict,
const conformalVoronoiMesh& cvMesh
const Time& runTime,
Random& rndGen,
const conformationSurfaces& geometryToConformTo,
const dictionary& coeffsDict
)
:
runTime_(cvMesh.time()),
geometryToConformTo_(cvMesh.geometryToConformTo()),
cellSizeControl_(cvMesh.cellSizeControl()),
rndGen_(cvMesh.rndGen()),
cvMeshControls_(cvMesh.cvMeshControls()),
runTime_(runTime),
geometryToConformTo_(geometryToConformTo),
rndGen_(rndGen),
mesh_
(
IOobject
@ -800,7 +804,6 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
),
boundaryFacesPtr_(),
bFTreePtr_(),
octreeNearestDistances_(),
allBackgroundMeshBounds_(Pstream::nProcs()),
globalBackgroundBounds_(),
decomposeDict_
@ -857,74 +860,6 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
}
Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
(
const scalar spanScale,
const scalar minCellSizeLimit,
const label minLevels,
const label volRes,
const scalar maxCellWeightCoeff,
const Time& runTime,
const conformationSurfaces& geometryToConformTo,
const cellSizeControlSurfaces& cellSizeControl,
Random& rndGen,
const cvControls& cvMeshControls
)
:
runTime_(runTime),
geometryToConformTo_(geometryToConformTo),
cellSizeControl_(cellSizeControl),
rndGen_(rndGen),
cvMeshControls_(cvMeshControls),
mesh_
(
IOobject
(
fvMesh::defaultRegion,
runTime_.timeName(),
runTime_,
IOobject::MUST_READ
)
),
meshCutter_
(
mesh_,
labelList(mesh_.nCells(), 0),
labelList(mesh_.nPoints(), 0)
),
boundaryFacesPtr_(),
bFTreePtr_(),
octreeNearestDistances_(),
allBackgroundMeshBounds_(Pstream::nProcs()),
globalBackgroundBounds_(),
decomposeDict_
(
IOobject
(
"decomposeParDict",
runTime_.system(),
runTime_,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
),
decomposerPtr_(decompositionMethod::New(decomposeDict_)),
mergeDist_(1e-6*mesh_.bounds().mag()),
spanScale_(spanScale),
minCellSizeLimit_(minCellSizeLimit),
minLevels_(minLevels),
volRes_(volRes),
maxCellWeightCoeff_(maxCellWeightCoeff)
{
// Stand-alone operation
Info<< nl << "Building initial background mesh decomposition" << endl;
initialRefinement();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::backgroundMeshDecomposition::~backgroundMeshDecomposition()
@ -936,10 +871,7 @@ Foam::backgroundMeshDecomposition::~backgroundMeshDecomposition()
Foam::autoPtr<Foam::mapDistributePolyMesh>
Foam::backgroundMeshDecomposition::distribute
(
volScalarField& cellWeights,
List<DynamicList<point> >& cellVertices,
List<DynamicList<label> >& cellVertexIndices,
List<DynamicList<label> >& cellVertexTypes
volScalarField& cellWeights
)
{
if (debug)
@ -982,10 +914,8 @@ Foam::backgroundMeshDecomposition::distribute
{
Info<< " cellWeightLimit " << cellWeightLimit << endl;
Pout<< " sum(cellWeights) "
<< sum(cellWeights.internalField())
<< " max(cellWeights) "
<< max(cellWeights.internalField())
Pout<< " sum(cellWeights) " << sum(cellWeights.internalField())
<< " max(cellWeights) " << max(cellWeights.internalField())
<< endl;
}
@ -1049,94 +979,6 @@ Foam::backgroundMeshDecomposition::distribute
// Update numbering of cells/vertices.
meshCutter_.updateMesh(map);
{
// Map cellVertices, cellVertexIndices and cellVertexTypes
meshSearch cellSearch(mesh_, polyMesh::FACEPLANES);
const labelList& reverseCellMap = map().reverseCellMap();
List<DynamicList<point> > newCellVertices(mesh_.nCells());
List<DynamicList<label> > newCellVertexIndices(mesh_.nCells());
List<DynamicList<label> > newCellVertexTypes(mesh_.nCells());
forAll(cellVertices, oldCellI)
{
DynamicList<point>& oldCellVertices =
cellVertices[oldCellI];
DynamicList<label>& oldCellVertexIndices =
cellVertexIndices[oldCellI];
DynamicList<label>& oldCellVertexTypes =
cellVertexTypes[oldCellI];
if (findIndex(newCellsToRefine, oldCellI) >= 0)
{
// This old cell was refined so the cell for the vertices
// in the new mesh needs to be searched for.
forAll(oldCellVertices, oPI)
{
const point& v = oldCellVertices[oPI];
label newCellI = cellSearch.findCell(v);
if (newCellI == -1)
{
// Pout<< "findCell backgroundMeshDecomposition "
// << v << " "
// << oldCellI
// << newCellI
// << " find nearest cellI ";
newCellI = cellSearch.findNearestCell(v);
// Pout<< newCellI << endl;
}
newCellVertices[newCellI].append(v);
newCellVertexIndices[newCellI].append
(
oldCellVertexIndices[oPI]
);
newCellVertexTypes[newCellI].append
(
oldCellVertexTypes[oPI]
);
}
}
else
{
label newCellI = reverseCellMap[oldCellI];
forAll(oldCellVertices, oPI)
{
newCellVertices[newCellI].append
(
oldCellVertices[oPI]
);
newCellVertexIndices[newCellI].append
(
oldCellVertexIndices[oPI]
);
newCellVertexTypes[newCellI].append
(
oldCellVertexTypes[oPI]
);
}
}
}
cellVertices.transfer(newCellVertices);
cellVertexIndices.transfer(newCellVertexIndices);
cellVertexTypes.transfer(newCellVertexTypes);
}
Info<< " Background mesh refined from "
<< returnReduce(map().nOldCells(), sumOp<label>())
<< " to " << mesh_.globalData().nTotalCells()
@ -1193,10 +1035,6 @@ Foam::backgroundMeshDecomposition::distribute
cellWeights.write();
}
mapDist().distributeCellData(cellVertices);
mapDist().distributeCellData(cellVertexIndices);
mapDist().distributeCellData(cellVertexTypes);
buildPatchAndTree();
return mapDist;
@ -1227,8 +1065,10 @@ bool Foam::backgroundMeshDecomposition::positionOnThisProcessor
// return bFTreePtr_().findAnyOverlap(pt, 0.0);
return
(
bFTreePtr_().getVolumeType(pt)
== indexedOctree<treeDataBPatch>::INSIDE;
== indexedOctree<treeDataBPatch>::INSIDE
);
}
@ -1247,6 +1087,7 @@ Foam::boolList Foam::backgroundMeshDecomposition::positionOnThisProcessor
return posProc;
}
bool Foam::backgroundMeshDecomposition::overlapsThisProcessor
(
const treeBoundBox& box
@ -1660,110 +1501,304 @@ Foam::backgroundMeshDecomposition::intersectsProcessors
}
Foam::labelListList Foam::backgroundMeshDecomposition::overlapsProcessors
bool Foam::backgroundMeshDecomposition::overlapsOtherProcessors
(
const List<point>& centres,
const List<scalar>& radiusSqrs,
bool includeOwnProcessor
const point& centre,
const scalar& radiusSqr
) const
{
DynamicList<label> toCandidateProc;
DynamicList<point> testCentres;
DynamicList<scalar> testRadiusSqrs;
labelList sphereBlockStart(centres.size(), -1);
labelList sphereBlockSize(centres.size(), -1);
label nTotalCandidates = 0;
forAll(centres, sI)
forAll(allBackgroundMeshBounds_, procI)
{
const point& c = centres[sI];
scalar rSqr = radiusSqrs[sI];
if (bFTreePtr_().findNearest(centre, radiusSqr).hit())
{
return true;
}
}
label nCandidates = 0;
return false;
}
Foam::labelList Foam::backgroundMeshDecomposition::overlapProcessors
(
const point& centre,
const scalar radiusSqr
) const
{
DynamicList<label> toProc(Pstream::nProcs());
forAll(allBackgroundMeshBounds_, procI)
{
// It is assumed that the sphere in question overlaps the source
// processor, so don't test it, unless includeOwnProcessor is true
// Test against the bounding box of the processor
if
(
(includeOwnProcessor || procI != Pstream::myProcNo())
&& allBackgroundMeshBounds_[procI].overlaps(c, rSqr)
procI != Pstream::myProcNo()
&& allBackgroundMeshBounds_[procI].overlaps(centre, radiusSqr)
)
{
toCandidateProc.append(procI);
testCentres.append(c);
testRadiusSqrs.append(rSqr);
nCandidates++;
}
}
sphereBlockStart[sI] = nTotalCandidates;
sphereBlockSize[sI] = nCandidates;
nTotalCandidates += nCandidates;
}
// Needed for reverseDistribute
label preDistributionToCandidateProcSize = toCandidateProc.size();
autoPtr<mapDistribute> map(buildMap(toCandidateProc));
map().distribute(testCentres);
map().distribute(testRadiusSqrs);
List<bool> sphereOverlapsCandidate(testCentres.size(), false);
// Test candidate spheres on candidate processors
forAll(testCentres, sI)
// Expensive test
// if (bFTreePtr_().findNearest(centre, radiusSqr).hit())
{
const point& c = testCentres[sI];
scalar rSqr = testRadiusSqrs[sI];
// If the sphere finds a nearest element of the patch, then it overlaps
sphereOverlapsCandidate[sI] = bFTreePtr_().findNearest(c, rSqr).hit();
//sphereOverlapsCandidate[sI] = bFTreePtr_().findAnyOverlap(c, rSqr);
toProc.append(procI);
}
map().reverseDistribute
(
preDistributionToCandidateProcSize,
sphereOverlapsCandidate
);
labelListList sphereProcs(centres.size());
// Working storage for assessing processors
DynamicList<label> tmpProcs;
forAll(centres, sI)
{
tmpProcs.clear();
// Extract the sub list of results for this point
SubList<bool> sphereProcResults
(
sphereOverlapsCandidate,
sphereBlockSize[sI],
sphereBlockStart[sI]
);
forAll(sphereProcResults, sPRI)
{
if (sphereProcResults[sPRI])
{
tmpProcs.append(toCandidateProc[sphereBlockStart[sI] + sPRI]);
}
}
sphereProcs[sI] = tmpProcs;
return toProc;
}
return sphereProcs;
}
//Foam::labelListList Foam::backgroundMeshDecomposition::overlapsProcessors
//(
// const List<point>& centres,
// const List<scalar>& radiusSqrs,
// const Delaunay& T,
// bool includeOwnProcessor
//) const
//{
// DynamicList<label> toCandidateProc;
// DynamicList<point> testCentres;
// DynamicList<scalar> testRadiusSqrs;
// labelList sphereBlockStart(centres.size(), -1);
// labelList sphereBlockSize(centres.size(), -1);
//
// label nTotalCandidates = 0;
//
// forAll(centres, sI)
// {
// const point& c = centres[sI];
// scalar rSqr = radiusSqrs[sI];
//
// label nCandidates = 0;
//
// forAll(allBackgroundMeshBounds_, procI)
// {
// // It is assumed that the sphere in question overlaps the source
// // processor, so don't test it, unless includeOwnProcessor is true
// if
// (
// (includeOwnProcessor || procI != Pstream::myProcNo())
// && allBackgroundMeshBounds_[procI].overlaps(c, rSqr)
// )
// {
// if (bFTreePtr_().findNearest(c, rSqr).hit())
// {
// toCandidateProc.append(procI);
// testCentres.append(c);
// testRadiusSqrs.append(rSqr);
//
// nCandidates++;
// }
// }
// }
//
// sphereBlockStart[sI] = nTotalCandidates;
// sphereBlockSize[sI] = nCandidates;
//
// nTotalCandidates += nCandidates;
// }
//
// // Needed for reverseDistribute
//// label preDistributionToCandidateProcSize = toCandidateProc.size();
////
//// autoPtr<mapDistribute> map(buildMap(toCandidateProc));
////
//// map().distribute(testCentres);
//// map().distribute(testRadiusSqrs);
//
// // @todo This is faster, but results in more vertices being referred
// boolList sphereOverlapsCandidate(testCentres.size(), true);
//// boolList sphereOverlapsCandidate(testCentres.size(), false);
////
//// // Test candidate spheres on candidate processors
//// forAll(testCentres, sI)
//// {
//// const point& c = testCentres[sI];
//// const scalar rSqr = testRadiusSqrs[sI];
////
//// const bool flagOverlap = bFTreePtr_().findNearest(c, rSqr).hit();
////
//// if (flagOverlap)
//// {
//// //if (vertexOctree.findAnyOverlap(c, rSqr))
////// if (vertexOctree.findNearest(c, rSqr*1.001).hit())
////// {
////// sphereOverlapsCandidate[sI] = true;
////// }
////
////// Vertex_handle nearestVertex = T.nearest_vertex
////// (
////// toPoint<Point>(c)
////// );
//////
////// const scalar distSqr = magSqr
////// (
////// topoint(nearestVertex->point()) - c
////// );
//////
////// if (distSqr <= rSqr)
////// {
////// // If the sphere finds a nearest element of the patch, then it
////// // overlaps
//// sphereOverlapsCandidate[sI] = true;
////// }
//// }
//// }
//
//// map().reverseDistribute
//// (
//// preDistributionToCandidateProcSize,
//// sphereOverlapsCandidate
//// );
//
// labelListList sphereProcs(centres.size());
//
// // Working storage for assessing processors
// DynamicList<label> tmpProcs;
//
// forAll(centres, sI)
// {
// tmpProcs.clear();
//
// // Extract the sub list of results for this point
//
// SubList<bool> sphereProcResults
// (
// sphereOverlapsCandidate,
// sphereBlockSize[sI],
// sphereBlockStart[sI]
// );
//
// forAll(sphereProcResults, sPRI)
// {
// if (sphereProcResults[sPRI])
// {
// tmpProcs.append(toCandidateProc[sphereBlockStart[sI] + sPRI]);
// }
// }
//
// sphereProcs[sI] = tmpProcs;
// }
//
// return sphereProcs;
//}
//Foam::labelListList Foam::backgroundMeshDecomposition::overlapProcessors
//(
// const point& cc,
// const scalar rSqr
//) const
//{
// DynamicList<label> toCandidateProc;
// label sphereBlockStart(-1);
// label sphereBlockSize(-1);
//
// label nCandidates = 0;
//
// forAll(allBackgroundMeshBounds_, procI)
// {
// // It is assumed that the sphere in question overlaps the source
// // processor, so don't test it, unless includeOwnProcessor is true
// if
// (
// (includeOwnProcessor || procI != Pstream::myProcNo())
// && allBackgroundMeshBounds_[procI].overlaps(cc, rSqr)
// )
// {
// toCandidateProc.append(procI);
//
// nCandidates++;
// }
// }
//
// sphereBlockSize = nCandidates;
// nTotalCandidates += nCandidates;
//
// // Needed for reverseDistribute
// label preDistributionToCandidateProcSize = toCandidateProc.size();
//
// autoPtr<mapDistribute> map(buildMap(toCandidateProc));
//
// map().distribute(testCentres);
// map().distribute(testRadiusSqrs);
//
// // @todo This is faster, but results in more vertices being referred
//// boolList sphereOverlapsCandidate(testCentres.size(), true);
// boolList sphereOverlapsCandidate(testCentres.size(), false);
//
// // Test candidate spheres on candidate processors
// forAll(testCentres, sI)
// {
// const point& c = testCentres[sI];
// const scalar rSqr = testRadiusSqrs[sI];
//
// const bool flagOverlap = bFTreePtr_().findNearest(c, rSqr).hit();
//
// if (flagOverlap)
// {
// //if (vertexOctree.findAnyOverlap(c, rSqr))
//// if (vertexOctree.findNearest(c, rSqr*1.001).hit())
//// {
//// sphereOverlapsCandidate[sI] = true;
//// }
//
//// Vertex_handle nearestVertex = T.nearest_vertex
//// (
//// toPoint<Point>(c)
//// );
////
//// const scalar distSqr = magSqr
//// (
//// topoint(nearestVertex->point()) - c
//// );
////
//// if (distSqr <= rSqr)
//// {
//// // If the sphere finds a nearest element of the patch, then it
//// // overlaps
// sphereOverlapsCandidate[sI] = true;
//// }
// }
// }
//
// map().reverseDistribute
// (
// preDistributionToCandidateProcSize,
// sphereOverlapsCandidate
// );
//
// labelListList sphereProcs(centres.size());
//
// // Working storage for assessing processors
// DynamicList<label> tmpProcs;
//
// forAll(centres, sI)
// {
// tmpProcs.clear();
//
// // Extract the sub list of results for this point
//
// SubList<bool> sphereProcResults
// (
// sphereOverlapsCandidate,
// sphereBlockSize[sI],
// sphereBlockStart[sI]
// );
//
// forAll(sphereProcResults, sPRI)
// {
// if (sphereProcResults[sPRI])
// {
// tmpProcs.append(toCandidateProc[sphereBlockStart[sI] + sPRI]);
// }
// }
//
// sphereProcs[sI] = tmpProcs;
// }
//
// return sphereProcs;
//}
// ************************************************************************* //

View File

@ -53,7 +53,6 @@ SourceFiles
#ifndef backgroundMeshDecomposition_H
#define backgroundMeshDecomposition_H
#include "conformalVoronoiMesh.H"
#include "fvMesh.H"
#include "hexRef8.H"
#include "cellSet.H"
@ -81,6 +80,10 @@ namespace Foam
typedef PrimitivePatch<face, List, const pointField, point> bPatch;
typedef treeDataPrimitivePatch<bPatch> treeDataBPatch;
class Time;
class Random;
class conformationSurfaces;
/*---------------------------------------------------------------------------*\
Class backgroundMeshDecomposition Declaration
\*---------------------------------------------------------------------------*/
@ -98,15 +101,9 @@ class backgroundMeshDecomposition
//- Reference to surface
const conformationSurfaces& geometryToConformTo_;
//- The cell size control object
const cellSizeControlSurfaces& cellSizeControl_;
//- Random number generator
Random& rndGen_;
//- Controls
const cvControls& cvMeshControls_;
//- Mesh stored on for this processor, specifiying the domain that it
// is responsible for.
fvMesh mesh_;
@ -121,8 +118,6 @@ class backgroundMeshDecomposition
//- Search tree for the boundaryFaces_ patch
autoPtr<indexedOctree<treeDataBPatch> > bFTreePtr_;
List<scalar> octreeNearestDistances_;
//- The bounds of all background meshes on all processors
treeBoundBoxList allBackgroundMeshBounds_;
@ -204,24 +199,10 @@ public:
//- Construct from components in cvMesh operation
backgroundMeshDecomposition
(
const dictionary& coeffsDict,
const conformalVoronoiMesh& cvMesh
);
//- Construct from components for standalone operation
backgroundMeshDecomposition
(
const scalar spanScale,
const scalar minCellSizeLimit,
const label minLevels,
const label volRes,
const scalar maxCellWeightCoeff,
const Time& runTime,
const conformationSurfaces& geometryToConformTo,
const cellSizeControlSurfaces& cellSizeControl,
Random& rndGen,
const cvControls& cvMeshControls
const conformationSurfaces& geometryToConformTo,
const dictionary& coeffsDict
);
@ -238,10 +219,7 @@ public:
// returning a map to use to redistribute vertices.
autoPtr<mapDistributePolyMesh> distribute
(
volScalarField& cellWeights,
List<DynamicList<point> >& cellVertices,
List<DynamicList<label> >& cellVertexIndices,
List<DynamicList<label> >& cellVertexTypes
volScalarField& cellWeights
);
//- Distribute supplied the points to the appropriate processor
@ -300,18 +278,31 @@ public:
bool includeOwnProcessor = false
) 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
bool overlapsOtherProcessors
(
const List<point>& centres,
const List<scalar>& radiusSqrs,
bool includeOwnProcessor = false
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
@ -320,9 +311,6 @@ public:
//- Return access to the underlying tree
inline const indexedOctree<treeDataBPatch>& tree() const;
//- Return access to the nearest distance of the octree nodes
inline const List<scalar>& octreeNearestDistances() const;
//- Return the boundBox of this processor
inline const treeBoundBox& procBounds() const;

View File

@ -30,18 +30,13 @@ const Foam::fvMesh& Foam::backgroundMeshDecomposition::mesh() const
return mesh_;
}
const Foam::indexedOctree<Foam::treeDataBPatch>&
Foam::backgroundMeshDecomposition::tree() const
{
return bFTreePtr_();
}
const Foam::List<Foam::scalar>&
Foam::backgroundMeshDecomposition::octreeNearestDistances() const
{
return octreeNearestDistances_;
}
const Foam::treeBoundBox&
Foam::backgroundMeshDecomposition::procBounds() const

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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_ << nl << 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 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,920 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "cellSizeAndAlignmentControl.H"
#include "searchableSurfaceControl.H"
#include "cellSizeFunction.H"
#include "triad.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template <class Triangulation, class Type>
Foam::tmp<Foam::Field<Type> > Foam::cellShapeControl::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::cellShapeControl::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::cellShapeControl::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::cellShapeControl::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()] = triad
(
vit->alignment().x(),
vit->alignment().y(),
vit->alignment().z()
);
}
return tAlignments;
}
template <class Triangulation>
Foam::tmp<Foam::pointField> Foam::cellShapeControl::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;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellShapeControl::cellShapeControl
(
const Time& runTime,
const dictionary& motionDict,
const searchableSurfaces& allGeometry,
const conformationSurfaces& geometryToConformTo
)
:
dictionary(motionDict),
runTime_(runTime),
allGeometry_(allGeometry),
geometryToConformTo_(geometryToConformTo),
defaultCellSize_(readScalar(lookup("defaultCellSize"))),
shapeControlMesh_(runTime),
aspectRatio_(motionDict),
sizeAndAlignment_
(
runTime,
motionDict.subDict("shapeControlFunctions"),
geometryToConformTo
)
{}
// * * * * * * * * * * * * * * * * 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;
label nFarPoints = 0;
for (label pI = 0; pI < 4; ++pI)
{
if (ch->vertex(pI)->farPoint())
{
nFarPoints++;
}
}
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;
// }
// }
// }
// Look up nearest point
cellShapeControlMesh::Vertex_handle nearV =
shapeControlMesh_.nearest_vertex
(
toPoint<cellShapeControlMesh::Point>(pt)
);
size = nearV->targetCellSize();
}
else
{
if (nFarPoints != 0)
{
for (label pI = 0; pI < 4; ++pI)
{
if (!ch->vertex(pI)->farPoint())
{
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;
label nFarPoints = 0;
for (label pI = 0; pI < 4; ++pI)
{
if (ch->vertex(pI)->farPoint())
{
nFarPoints++;
}
}
if (shapeControlMesh_.is_infinite(ch) || nFarPoints == 4)
{
Pout<< "At Infinite vertex" << endl;
if (nFarPoints != 0)
{
for (label pI = 0; pI < 4; ++pI)
{
if (!ch->vertex(pI)->farPoint())
{
alignment = ch->vertex(pI)->alignment();
return alignment;
}
}
}
// cellShapeControlMesh::Vertex_handle nearV =
// shapeControlMesh_.nearest_vertex
// (
// toPoint<cellShapeControlMesh::Point>(pt)
// );
//
// alignment = nearV->alignment();
}
else
{
// forAll(bary, pI)
// {
// alignment += bary[pI]*ch->vertex(pI)->alignment();
// }
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;
label nFarPoints = 0;
for (label pI = 0; pI < 4; ++pI)
{
if (ch->vertex(pI)->farPoint())
{
nFarPoints++;
}
}
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();
alignment = ch->vertex(pI)->alignment();
return;
}
}
}
// cellShapeControlMesh::Vertex_handle nearV =
// shapeControlMesh_.nearest_vertex
// (
// toPoint<cellShapeControlMesh::Point>(pt)
// );
//
// size = nearV->targetCellSize();
// alignment = nearV->alignment();
}
else
{
if (nFarPoints != 0)
{
for (label pI = 0; pI < 4; ++pI)
{
if (!ch->vertex(pI)->farPoint())
{
size = ch->vertex(pI)->targetCellSize();
alignment = ch->vertex(pI)->alignment();
return;
}
}
}
else
{
triad tri;
forAll(bary, pI)
{
size += bary[pI]*ch->vertex(pI)->targetCellSize();
triad triTmp2
(
ch->vertex(pI)->alignment().x(),
ch->vertex(pI)->alignment().y(),
ch->vertex(pI)->alignment().z()
);
tri += triTmp2*bary[pI];
}
tri.normalize();
tri.orthogonalize();
tri = tri.sortxyz();
alignment = tensor
(
tri.x(), tri.y(), tri.z()
);
}
}
}
void Foam::cellShapeControl::initialMeshPopulation
(
const autoPtr<backgroundMeshDecomposition>& decomposition
)
{
// Need to pass in the background mesh decomposition so that can test if
// a point to insert is on the processor.
if (Pstream::parRun())
{
shapeControlMesh_.insertBoundingPoints(decomposition().procBounds());
}
else
{
shapeControlMesh_.insertBoundingPoints(allGeometry_.bounds());
}
const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
sizeAndAlignment_.controlFunctions();
forAll(controlFunctions, fI)
{
const cellSizeAndAlignmentControl& controlFunction =
controlFunctions[fI];
Info<< "Inserting points from " << controlFunction.name()
<< " (" << controlFunction.type() << ")" << endl;
pointField pts(1);
scalarField sizes(1);
Field<triad> alignments(1);
controlFunction.initialVertices(pts, sizes, alignments);
label nRejected = 0;
forAll(pts, pI)
{
if (Pstream::parRun())
{
if (!decomposition().positionOnThisProcessor(pts[pI]))
{
nRejected++;
continue;
}
}
shapeControlMesh_.insert
(
pts[pI],
sizes[pI],
alignments[pI]
);
}
Info<< " Inserted " << (pts.size() - nRejected) << "/" << pts.size()
<< endl;
}
}
Foam::label Foam::cellShapeControl::refineMesh
(
const autoPtr<backgroundMeshDecomposition>& decomposition
)
{
const pointField cellCentres = shapeControlMesh_.cellCentres();
Info<< " Created cell centres" << endl;
const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
sizeAndAlignment_.controlFunctions();
DynamicList<Vb> verts(shapeControlMesh_.number_of_vertices());
forAll(cellCentres, cellI)
{
const Foam::point& pt = cellCentres[cellI];
if (!geometryToConformTo_.inside(pt))
{
continue;
}
scalarList bary;
cellShapeControlMesh::Cell_handle ch;
shapeControlMesh_.barycentricCoords(pt, bary, ch);
if (shapeControlMesh_.is_infinite(ch))
{
continue;
}
scalar interpolatedSize = 0;
forAll(bary, pI)
{
interpolatedSize += bary[pI]*ch->vertex(pI)->targetCellSize();
}
label lastPriority = labelMax;
scalar lastCellSize = GREAT;
forAll(controlFunctions, fI)
{
const cellSizeAndAlignmentControl& controlFunction =
controlFunctions[fI];
if (controlFunction.priority() > lastPriority)
{
continue;
}
if (isA<searchableSurfaceControl>(controlFunction))
{
const cellSizeFunction& sizeFunction =
dynamicCast<const searchableSurfaceControl>
(
controlFunction
).sizeFunction();
scalar cellSize = 0;
if (sizeFunction.cellSize(pt, cellSize))
{
if (controlFunction.priority() == lastPriority)
{
if (cellSize < lastCellSize)
{
lastCellSize = cellSize;
}
}
else
{
lastCellSize = cellSize;
}
lastPriority = controlFunction.priority();
}
}
}
if
(
lastCellSize < GREAT
&& mag(interpolatedSize - lastCellSize)/lastCellSize > 0.2
)
{
if (Pstream::parRun())
{
if (!decomposition().positionOnThisProcessor(pt))
{
continue;
}
}
verts.append
(
Vb
(
toPoint<cellShapeControlMesh::Point>(pt),
Vb::vtInternal
)
);
verts.last().targetCellSize() = lastCellSize;
verts.last().alignment() = tensor::I;
}
}
shapeControlMesh_.insertPoints(verts);
return verts.size();
}
void Foam::cellShapeControl::smoothMesh()
{
label maxSmoothingIterations = 200;
scalar minResidual = 0;
labelListList pointPoints;
autoPtr<mapDistribute> meshDistributor = buildMap
(
shapeControlMesh_,
pointPoints
);
triadField alignments = buildAlignmentField(shapeControlMesh_);
pointField points = buildPointField(shapeControlMesh_);
// Setup the sizes and alignments on each point
triadField fixedAlignments(shapeControlMesh_.vertexCount(), triad::unset);
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
shapeControlMesh_.finite_vertices_begin();
vit != shapeControlMesh_.finite_vertices_end();
++vit
)
{
if (vit->real())
{
const tensor& alignment = vit->alignment();
fixedAlignments[vit->index()] = triad
(
alignment.x(),
alignment.y(),
alignment.z()
);
}
}
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;
}
triad& newTriad = triadAv[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();
// Enforce the boundary conditions
const triad& fixedAlignment = fixedAlignments[pI];
label nFixed = 0;
forAll(fixedAlignment, dirI)
{
if (fixedAlignment[dirI] != triad::unset[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];
}
}
}
const triad& oldTriad = alignments[pI];
if (newTriad.set(vector::X) && oldTriad.set(vector::X))
{
scalar dotProd = (oldTriad.x() & newTriad.x());
scalar diff = mag(dotProd) - 1.0;
residual += mag(diff);
}
if (newTriad.set(vector::Y) && oldTriad.set(vector::Y))
{
scalar dotProd = (oldTriad.y() & newTriad.y());
scalar diff = mag(dotProd) - 1.0;
residual += mag(diff);
}
if (newTriad.set(vector::Z) && oldTriad.set(vector::Z))
{
scalar dotProd = (oldTriad.z() & newTriad.z());
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;
}
}
meshDistributor().distribute(alignments);
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
shapeControlMesh_.finite_vertices_begin();
vit != shapeControlMesh_.finite_vertices_end();
++vit
)
{
if (vit->real())
{
vit->alignment() = tensor
(
alignments[vit->index()].x(),
alignments[vit->index()].y(),
alignments[vit->index()].z()
);
}
}
labelList referredPoints;
autoPtr<mapDistribute> referredDistributor = buildReferredMap
(
shapeControlMesh_,
referredPoints
);
alignments.setSize(shapeControlMesh_.vertexCount());
referredDistributor().distribute(alignments);
label referredI = 0;
for
(
CellSizeDelaunay::Finite_vertices_iterator vit =
shapeControlMesh_.finite_vertices_begin();
vit != shapeControlMesh_.finite_vertices_end();
++vit
)
{
if (vit->referred())
{
const triad& t = alignments[referredPoints[referredI++]];
vit->alignment() = tensor(t.x(), t.y(), t.z());
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,212 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "triadField.H"
#include "Time.H"
#include "searchableSurfaces.H"
#include "conformationSurfaces.H"
#include "cellAspectRatioControl.H"
#include "cellSizeAndAlignmentControls.H"
#include "cellShapeControlMesh.H"
#include "backgroundMeshDecomposition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellShapeControl Declaration
\*---------------------------------------------------------------------------*/
class cellShapeControl
:
public dictionary
{
// Private data
const Time& runTime_;
const searchableSurfaces& allGeometry_;
const conformationSurfaces& geometryToConformTo_;
const scalar defaultCellSize_;
cellShapeControlMesh shapeControlMesh_;
cellAspectRatioControl aspectRatio_;
cellSizeAndAlignmentControls sizeAndAlignment_;
// 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);
//- 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 dictionary& cellShapeControlDict,
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;
// 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;
// Edit
void initialMeshPopulation
(
const autoPtr<backgroundMeshDecomposition>& decomposition
);
label refineMesh
(
const autoPtr<backgroundMeshDecomposition>& decomposition
);
void smoothMesh();
//- Add a control point with a specified size and alignment
// virtual void addControlPoint
// (
// const point& pt,
// const scalar& size,
// const tensor& alignment
// );
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "cellShapeControlI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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_;
}
// ************************************************************************* //

View File

@ -0,0 +1,760 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "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;//cvMeshControls().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
ch = locate
(
Point(pt.x(), pt.y(), pt.z())
);
if (!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());
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());
}
}
mapDist().distribute(points);
mapDist().distribute(sizes);
mapDist().distribute(alignments);
// Reset the entire tessellation
DelaunayMesh<CellSizeDelaunay>::reset();
Info<< nl << " Inserting distributed tessellation" << endl;
insertBoundingPoints(decomposition.procBounds());
// Internal points have to be inserted first
DynamicList<Vb> verticesToInsert(points.size());
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];
}
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)
{
boundBox bbInflate = bb;
bbInflate.inflate(10);
pointField pts = bbInflate.points();
forAll(pts, pI)
{
insertFar(pts[pI]);
}
}
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)
);
for
(
Finite_vertices_iterator vit = finite_vertices_begin();
vit != finite_vertices_end();
++vit
)
{
if (!vit->farPoint())
{
sizes[vertexMap[vit->index()]] = vit->targetCellSize();
}
}
mesh.write();
}
// ************************************************************************* //

View File

@ -0,0 +1,168 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 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
//- 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);
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 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,121 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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& allGeometry
)
:
runTime_(runTime),
name_(name),
priority_(readLabel(controlFunctionDict.lookup("priority")))
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cellSizeAndAlignmentControl>
Foam::cellSizeAndAlignmentControl::New
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& allGeometry
)
{
word cellSizeAndAlignmentControlTypeName
(
controlFunctionDict.lookup("type")
);
Info<< nl << "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,
allGeometry
)
);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControl::~cellSizeAndAlignmentControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "triad.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSizeAndAlignmentControl Declaration
\*---------------------------------------------------------------------------*/
class cellSizeAndAlignmentControl
{
protected:
const Time& runTime_;
private:
// Private data
const word name_;
//- Priority of this cellSizeFunction
label priority_;
// 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& allGeometry
),
(runTime, name, controlFunctionDict, allGeometry)
);
// Constructors
//- Construct from dictionary and references to conformalVoronoiMesh and
// searchableSurfaces
cellSizeAndAlignmentControl
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& allGeometry
);
// Selectors
//- Return a reference to the selected cellShapeControl
static autoPtr<cellSizeAndAlignmentControl> New
(
const Time& runTime,
const word& name,
const dictionary& controlFunctionDict,
const conformationSurfaces& allGeometry
);
//- Destructor
virtual ~cellSizeAndAlignmentControl();
// Member Functions
// Access
const word& name() const
{
return name_;
}
inline label priority() const
{
return priority_;
}
// Query
virtual void initialVertices
(
pointField& pts,
scalarField& sizes,
Field<triad>& alignments
) 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 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"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControls::cellSizeAndAlignmentControls
(
const Time& runTime,
const dictionary& shapeControlDict,
const conformationSurfaces& allGeometry
)
:
shapeControlDict_(shapeControlDict),
allGeometry_(allGeometry),
controlFunctions_(shapeControlDict_.size())
{
label functionI = 0;
forAllConstIter(dictionary, shapeControlDict_, iter)
{
word shapeControlEntryName = iter().keyword();
const dictionary& controlFunctionDict
(
shapeControlDict_.subDict(shapeControlEntryName)
);
controlFunctions_.set
(
functionI,
cellSizeAndAlignmentControl::New
(
runTime,
shapeControlEntryName,
controlFunctionDict,
allGeometry
)
);
functionI++;
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellSizeAndAlignmentControls::~cellSizeAndAlignmentControls()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "cellShapeControlMesh.H"
#include "cellSizeAndAlignmentControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSizeAndAlignmentControls Declaration
\*---------------------------------------------------------------------------*/
class cellSizeAndAlignmentControls
{
// Private data
const dictionary& shapeControlDict_;
const conformationSurfaces& allGeometry_;
PtrList<cellSizeAndAlignmentControl> controlFunctions_;
// Private Member Functions
//- Disallow default bitwise copy construct
cellSizeAndAlignmentControls(const cellSizeAndAlignmentControls&);
//- Disallow default bitwise assignment
void operator=(const cellSizeAndAlignmentControls&);
public:
// Constructors
//- Construct from dictionary
cellSizeAndAlignmentControls
(
const Time& runTime,
const dictionary& shapeControlDict,
const conformationSurfaces& allGeometry
);
//- Destructor
virtual ~cellSizeAndAlignmentControls();
// Member Functions
// Access
const PtrList<cellSizeAndAlignmentControl>& controlFunctions() const
{
return controlFunctions_;
}
// Query
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,236 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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& allGeometry
)
:
cellSizeAndAlignmentControl(runTime, name, controlFunctionDict, allGeometry),
pointsFile_(controlFunctionDict.lookup("pointsFile")),
sizesFile_(controlFunctionDict.lookup("sizesFile")),
alignmentsFile_(controlFunctionDict.lookup("alignmentsFile"))
{
Info<< indent << "Loading from file... " << 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::initialVertices
(
pointField& pts,
scalarField& sizes,
Field<triad>& 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,134 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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_;
// 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& allGeometry
);
//- 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;
// Edit
virtual void initialVertices
(
pointField& pts,
scalarField& sizes,
Field<triad>& alignments
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,640 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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& allGeometry
)
:
cellSizeAndAlignmentControl(runTime, name, controlFunctionDict, allGeometry),
searchableSurface_(allGeometry.geometry()[name]),
allGeometry_(allGeometry),
cellSizeFunction_
(
cellSizeFunction::New(controlFunctionDict, searchableSurface_)
)
// geometryToConformTo_(geometryToConformTo),
// surfaces_(),
// cellSizeFunctions_(),
// triangulatedMesh_()
{
// const dictionary& surfacesDict = coeffDict();
//
// Info<< nl << "Reading cellSizeControlGeometry" << endl;
//
// surfaces_.setSize(surfacesDict.size());
//
// cellSizeFunctions_.setSize(surfacesDict.size());
//
// label surfI = 0;
//
// DynamicList<point> pointsToInsert;
// DynamicList<scalar> sizesToInsert;
// DynamicList<tensor> alignmentsToInsert;
//
// forAllConstIter(dictionary, surfacesDict, iter)
// {
// const dictionary& surfaceSubDict
// (
// surfacesDict.subDict(iter().keyword())
// );
//
// // If the "surface" keyword is not found in the dictionary, assume that
// // the name of the dictionary is the surface. Distinction required to
// // allow the same surface to be used multiple times to supply multiple
// // cellSizeFunctions
//
// word surfaceName = surfaceSubDict.lookupOrDefault<word>
// (
// "surface",
// iter().keyword()
// );
//
// surfaces_[surfI] = allGeometry_.findSurfaceID(surfaceName);
//
// if (surfaces_[surfI] < 0)
// {
// FatalErrorIn
// (
// "Foam::surfaceControl::surfaceControl"
// ) << "No surface " << surfaceName << " found. "
// << "Valid geometry is " << nl << allGeometry_.names()
// << exit(FatalError);
// }
//
// const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
//
// Info<< nl << " " << iter().keyword() << nl
// << " surface: " << surfaceName << nl
// << " size : " << surface.size() << endl;
//
// cellSizeFunctions_.set
// (
// surfI,
// cellSizeFunction::New
// (
// surfaceSubDict,
// surface
// )
// );
//
// surfI++;
//
// if (isA<triSurfaceMesh>(surface))
// {
// const triSurfaceMesh& tsm
// = refCast<const triSurfaceMesh>(surface);
//
// const pointField& points = tsm.points();
// const vectorField& faceNormals = tsm.faceNormals();
// const labelListList& pointFaces = tsm.pointFaces();
//
// Info<< " Number of points: " << tsm.nPoints() << endl;
//
// forAll(points, pI)
// {
// const Foam::point& pt = points[pI];
// const labelList& ptFaces = pointFaces[pI];
//
// vectorField pointNormals(ptFaces.size());
//
// forAll(pointNormals, pnI)
// {
// pointNormals[pnI] = faceNormals[ptFaces[pnI]];
// }
//
// pointsToInsert.append(pt);
//
// // Get the value of the point from surfaceCellSizeFunction. If
// // adding points internally then will need to interpolate.
// scalar newSize = 0;
//
// cellSizeFunctions_[surfI - 1].cellSize(pt, newSize);
// sizesToInsert.append(newSize);
//
// tensor newAlignment = requiredAlignment(pt, pointNormals);
//
// alignmentsToInsert.append(newAlignment);
// }
// }
// }
//
// // Add the global bound box to ensure that all internal point queries
// // will return sizes and alignments
//// boundBox bb = allGeometry_.bounds();
////
//// pointField bbPoints = bb.points();
////
//// forAll(bbPoints, pI)
//// {
//// pointsToInsert.append(bbPoints[pI]);
//// sizesToInsert.append(defaultCellSize());
//// alignmentsToInsert.append(tensor(1,0,0,0,1,0,0,0,1));
//// }
//
// triangulatedMesh_.set
// (
// new triangulatedMesh
// (
// runTime,
// pointsToInsert,
// sizesToInsert,
// alignmentsToInsert,
// defaultCellSize()
// )
// );
//
// scalar factor = 1.0;
// label maxIteration = cellShapeControlDict.lookupOrDefault<label>
// (
// "maxRefinementIterations", 1
// );
//
//
// for (label iteration = 0; iteration < maxIteration; ++iteration)
// {
// Info<< "Iteration : " << iteration << endl;
//
// label nRefined = triangulatedMesh_().refineTriangulation
// (
// factor,
// allGeometry_,
// geometryToConformTo_
// );
//
// Info<< " Number of cells refined in refinement iteration : "
// << nRefined << nl << endl;
//
// if (nRefined <= 0 && iteration != 0)
// {
// break;
// }
//
// factor *= 1.5;
// }
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::searchableSurfaceControl::~searchableSurfaceControl()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
//Foam::scalar Foam::surfaceControl::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::surfaceControl::cellAlignment(const point& pt) const
//{
// scalarList bary;
// Cell_handle ch;
//
// triangulatedMesh_().barycentricCoords(pt, bary, ch);
//
//// vectorField cartesianDirections(3);
////
//// cartesianDirections[0] = vector(0,0,1);
//// cartesianDirections[1] = vector(0,1,0);
//// cartesianDirections[2] = vector(1,0,0);
////
//// // Rearrange each alignment tensor so that the x/y/z components are
//// // in order of whichever makes the smallest angle with the global coordinate
//// // system
//// FixedList<tensor, 4> alignments;
////
//// forAll(alignments, aI)
//// {
//// tensor a = ch->vertex(aI)->alignment();
////
//// tensor tmpA = a;
////
////// Info<< nl << indent<< a << endl;
////
//// scalar minAngle = 0;
////
//// scalar axx = vectorTools::cosPhi(a.x(), cartesianDirections[0]);
//// scalar axy = vectorTools::cosPhi(a.y(), cartesianDirections[0]);
//// scalar axz = vectorTools::cosPhi(a.z(), cartesianDirections[0]);
////
//// scalar ayx = vectorTools::cosPhi(a.x(), cartesianDirections[1]);
//// scalar ayy = vectorTools::cosPhi(a.y(), cartesianDirections[1]);
//// scalar ayz = vectorTools::cosPhi(a.z(), cartesianDirections[1]);
////
//// scalar azx = vectorTools::cosPhi(a.x(), cartesianDirections[2]);
//// scalar azy = vectorTools::cosPhi(a.y(), cartesianDirections[2]);
//// scalar azz = vectorTools::cosPhi(a.z(), cartesianDirections[2]);
////
////// Info<< indent << axx << " " << axy << " " << axz << nl
////// << indent << ayx << " " << ayy << " " << ayz << nl
////// << indent << azx << " " << azy << " " << azz << endl;
////
//// if (mag(axx) >= minAngle)
//// {
//// tmpA.xx() = mag(a.xx()); tmpA.xy() = mag(a.xy()); tmpA.xz() = mag(a.xz());
//// minAngle = mag(axx);
//// }
//// if (mag(axy) >= minAngle)
//// {
//// tmpA.xx() = mag(a.yx()); tmpA.xy() = mag(a.yy()); tmpA.xz() = mag(a.yz());
//// minAngle = mag(axy);
//// }
//// if (mag(axz) >= minAngle)
//// {
//// tmpA.xx() = mag(a.zx()); tmpA.xy() = mag(a.zy()); tmpA.xz() = mag(a.zz());
//// }
////
//// minAngle = 0;
////
//// if (mag(ayx) >= minAngle)
//// {
//// tmpA.yx() = mag(a.xx()); tmpA.yy() = mag(a.xy()); tmpA.yz() = mag(a.xz());
//// minAngle = mag(ayx);
//// }
//// if (mag(ayy) >= minAngle)
//// {
//// tmpA.yx() = mag(a.yx()); tmpA.yy() = mag(a.yy()); tmpA.yz() = mag(a.yz());
//// minAngle = mag(ayy);
//// }
//// if (mag(ayz) >= minAngle)
//// {
//// tmpA.yx() = mag(a.zx()); tmpA.yy() = mag(a.zy()); tmpA.yz() = mag(a.zz());
//// }
////
//// minAngle = 0;
////
//// if (mag(azx) >= minAngle)
//// {
//// tmpA.zx() = mag(a.xx()); tmpA.zy() = mag(a.xy()); tmpA.zz() = mag(a.xz());
//// minAngle = mag(azx);
//// }
//// if (mag(azy) >= minAngle)
//// {
//// tmpA.zx() = mag(a.yx()); tmpA.zy() = mag(a.yy()); tmpA.zz() = mag(a.yz());
//// minAngle = mag(azy);
//// }
//// if (mag(azz) >= minAngle)
//// {
//// tmpA.zx() = mag(a.zx()); tmpA.zy() = mag(a.zy()); tmpA.zz() = mag(a.zz());
//// }
////
//// alignments[aI] = tmpA;
//// }
//
// scalar nearest = 0;
//
//// Info<< nl << "Point " << pt << endl;
////
//// FixedList<quaternion, 4> qAlignments;
//// forAll(qAlignments, aI)
//// {
////// Info<< " Direction " << aI << endl;
////// Info<< " Rot tensor" << alignments[aI] << endl;
//// qAlignments[aI] = quaternion(alignments[aI]);
//// qAlignments[aI].normalize();
////// Info<< " Quaternion: " << qAlignments[aI] << endl;
////// Info<< " Rot tensor from quat: " << qAlignments[aI].R() << endl;
//// }
//
// tensor alignment = Foam::tensor::zero;
// forAll(bary, pI)
// {
//// alignment += bary[pI]*ch->vertex(pI)->alignment();
//
//// alignment += bary[pI]*alignments[pI];
//
// // Try slerp with quaternions
//
// // Find nearest point
// if (bary[pI] > nearest)
// {
// alignment = ch->vertex(pI)->alignment();
// nearest = bary[pI];
// }
// }
//
//// quaternion alignment;
//
//// alignment = qAlignments[0]*bary[0]
//// + qAlignments[1]*bary[1]
//// + qAlignments[2]*bary[2]
//// + qAlignments[3]*bary[3];
//
//// alignment = slerp(qAlignments[0], qAlignments[1], bary[0]+bary[1]+bary[2]);
//// alignment = slerp(alignment, qAlignments[2], bary[0]+bary[1]+bary[2]);
//// alignment = slerp(alignment, qAlignments[3], bary[0]+bary[1]+bary[2]);
//// alignment = slerp(alignment, qAlignments[0], bary[0]/(bary[0]+bary[1]+bary[2]));
//
//// Info<< " Interp alignment : " << alignment << endl;
//// Info<< " Interp rot tensor: " << alignment.R() << endl;
//
// return alignment;
//}
//
//
//void Foam::surfaceControl::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::searchableSurfaceControl::initialVertices
(
pointField& pts,
scalarField& sizes,
Field<triad>& alignments
) const
{
pts = searchableSurface_.points();
const scalar nearFeatDistSqrCoeff = 1e-8;
sizes.setSize(pts.size());
alignments.setSize(pts.size());
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;
allGeometry_.findFeaturePointNearest
(
pts[pI],
nearFeatDistSqrCoeff,
info,
infoFeature
);
autoPtr<triad> pointAlignment;
if (info.hit())
{
const extendedFeatureEdgeMesh& features =
allGeometry_.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
{
allGeometry_.findEdgeNearest
(
pts[pI],
nearFeatDistSqrCoeff,
info,
infoFeature
);
if (info.hit())
{
const extendedFeatureEdgeMesh& features =
allGeometry_.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]));
}
}
if (!cellSizeFunction_().cellSize(pts[pI], sizes[pI]))
{
FatalErrorIn
(
"Foam::searchableSurfaceControl::initialVertices"
"(pointField&, scalarField&, tensorField&)"
) << "Could not calculate cell size"
<< abort(FatalError);
}
alignments[pI] = pointAlignment();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "cellShapeControl.H"
#include "cellSizeFunction.H"
#include "triad.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class surfaceControl Declaration
\*---------------------------------------------------------------------------*/
class searchableSurfaceControl
:
public cellSizeAndAlignmentControl
{
// Private data
// //- Reference to the searchableSurfaces object holding all geometry data
const searchableSurface& searchableSurface_;
const conformationSurfaces& allGeometry_;
autoPtr<cellSizeFunction> cellSizeFunction_;
// 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& allGeometry
);
//- 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 initialVertices
(
pointField& pts,
scalarField& sizes,
Field<triad>& alignments
) const;
const cellSizeFunction& sizeFunction() const
{
return cellSizeFunction_();
}
// Edit
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -26,6 +26,9 @@ License
#include "cellSizeControlSurfaces.H"
#include "conformalVoronoiMesh.H"
#include "cellSizeFunction.H"
#include "triSurfaceMesh.H"
#include "tetrahedron.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -149,15 +152,358 @@ bool Foam::cellSizeControlSurfaces::evalCellSizeFunctions
}
bool Foam::cellSizeControlSurfaces::checkCoplanarTet
(
Cell_handle c,
const scalar tol
) const
{
plane triPlane
(
topoint(c->vertex(0)->point()),
topoint(c->vertex(1)->point()),
topoint(c->vertex(2)->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 (triPlane.distance(topoint(c->vertex(3)->point())) < tol)
{
return true;
}
return false;
}
bool Foam::cellSizeControlSurfaces::checkClosePoints
(
Cell_handle c,
const scalar tol
) const
{
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;
}
Foam::label Foam::cellSizeControlSurfaces::refineTriangulation
(
const scalar factor
)
{
// Check the tets and insert new points if necessary
List<Foam::point> corners(4);
List<scalar> values(4);
DynamicList<Foam::point> pointsToInsert(T_.number_of_vertices());
DynamicList<scalar> valuesToInsert(T_.number_of_vertices());
for
(
Delaunay::Finite_cells_iterator c = T_.finite_cells_begin();
c != T_.finite_cells_end();
++c
)
{
//const point& newPoint = tet.centre();
//Cell_handle ch = c;
// Info<< count++ << endl;
// Info<< " " << topoint(c->vertex(0)->point()) << nl
// << " " << topoint(c->vertex(1)->point()) << nl
// << " " << topoint(c->vertex(2)->point()) << nl
// << " " << topoint(c->vertex(3)->point()) << endl;
scalar minDist = 1e-6*defaultCellSize_;
if (checkClosePoints(c, minDist) || checkCoplanarTet(c, minDist))
{
continue;
}
const Point circumcenter = CGAL::circumcenter
(
c->vertex(0)->point(),
c->vertex(1)->point(),
c->vertex(2)->point(),
c->vertex(3)->point()
);
pointFromPoint newPoint = topoint(circumcenter);
if (geometryToConformTo_.outside(newPoint))
{
continue;
}
Cell_handle ch = T_.locate
(
Point(newPoint.x(), newPoint.y(), newPoint.z())
);
forAll(corners, pI)
{
corners[pI] = topoint(ch->vertex(pI)->point());
values[pI] = ch->vertex(pI)->value();
}
tetPointRef tet(corners[0], corners[1], corners[2], corners[3]);
scalarList bary;
tet.barycentric(newPoint, bary);
scalar interpolatedSize = 0;
forAll(bary, pI)
{
interpolatedSize += bary[pI]*ch->vertex(pI)->value();
}
// Find largest gradient
label maxGradCorner = -1;
scalar maxGradient = 0.0;
forAll(corners, pI)
{
const scalar distance = mag(newPoint - corners[pI]);
const scalar diffSize = interpolatedSize - values[pI];
const scalar gradient = diffSize/distance;
if (gradient > maxGradient)
{
maxGradient = gradient;
maxGradCorner = pI;
}
}
// if (wallSize < 0.5*defaultCellSize_)
// {
// Info<< "Centre : " << centre
// << " (Default Size: " << defaultCellSize_ << ")" << nl
// << "Interpolated Size : " << interpolatedSize << nl
// << "Distance from wall : " << distanceSize << nl
// << "Wall size : " << wallSize << nl
// << "distanceGradient : " << distanceGradient << nl
// << "interpGradient : " << interpolatedGradient << nl << endl;
// }
scalar minCellSize = 1e-6;
scalar initialMaxGradient = 0;//0.2*factor;
scalar initialMinGradient = 0;//0.01*(1.0/factor);
scalar idealGradient = 0.2;
// Reduce strong gradients
if (maxGradient > initialMaxGradient)
{
const scalar distance2 = mag(newPoint - corners[maxGradCorner]);
scalar newSize
= values[maxGradCorner] + idealGradient*distance2;
pointsToInsert.append(newPoint);
valuesToInsert.append
(
max(min(newSize, defaultCellSize_), minCellSize)
);
}
else if (maxGradient < -initialMaxGradient)
{
const scalar distance2 = mag(newPoint - corners[maxGradCorner]);
scalar newSize
= values[maxGradCorner] - idealGradient*distance2;
pointsToInsert.append(newPoint);
valuesToInsert.append
(
max(min(newSize, defaultCellSize_), minCellSize)
);
}
// Increase small gradients
if
(
maxGradient < initialMinGradient
&& maxGradient > 0
&& interpolatedSize < 0.5*defaultCellSize_
)
{
const scalar distance2 = mag(newPoint - corners[maxGradCorner]);
scalar newSize
= values[maxGradCorner] + idealGradient*distance2;
pointsToInsert.append(newPoint);
valuesToInsert.append
(
max(min(newSize, defaultCellSize_), minCellSize)
);
}
else if
(
maxGradient > -initialMinGradient
&& maxGradient < 0
&& interpolatedSize > 0.5*defaultCellSize_
)
{
const scalar distance2 = mag(newPoint - corners[maxGradCorner]);
scalar newSize
= values[maxGradCorner] - idealGradient*distance2;
pointsToInsert.append(newPoint);
valuesToInsert.append
(
max(min(newSize, defaultCellSize_), minCellSize)
);
}
}
if (!pointsToInsert.empty())
{
Info<< " Minimum Cell Size : " << min(valuesToInsert) << nl
<< " Average Cell Size : " << average(valuesToInsert) << nl
<< " Maximum Cell Size : " << max(valuesToInsert) << endl;
forAll(pointsToInsert, pI)
{
Foam::point p = pointsToInsert[pI];
Vertex_handle v = T_.insert(Point(p.x(), p.y(), p.z()));
v->value(valuesToInsert[pI]);
}
}
return pointsToInsert.size();
}
void Foam::cellSizeControlSurfaces::writeRefinementTriangulation()
{
OFstream str("refinementTriangulation.obj");
label count = 0;
Info<< "Write refinementTriangulation" << endl;
for
(
Delaunay::Finite_edges_iterator e = T_.finite_edges_begin();
e != T_.finite_edges_end();
++e
)
{
Cell_handle c = e->first;
Vertex_handle vA = c->vertex(e->second);
Vertex_handle vB = c->vertex(e->third);
pointFromPoint p1 = topoint(vA->point());
pointFromPoint p2 = topoint(vB->point());
meshTools::writeOBJ(str, p1, p2, count);
}
OFstream strPoints("refinementObject.obj");
Info<< "Write refinementObject" << endl;
for
(
Delaunay::Finite_vertices_iterator v = T_.finite_vertices_begin();
v != T_.finite_vertices_end();
++v
)
{
pointFromPoint p = topoint(v->point());
meshTools::writeOBJ
(
strPoints,
p,
point(p.x() + v->value(), p.y(), p.z())
);
}
// OFstream strDual("refinementDualPoints.obj");
//
// Info<< "Write refinementDualPoints" << endl;
//
// for
// (
// Delaunay::Finite_cells_iterator c = T_.finite_cells_begin();
// c != T_.finite_cells_end();
// ++c
// )
// {
// Point circumcenter = CGAL::circumcenter
// (
// c->vertex(0)->point(),
// c->vertex(1)->point(),
// c->vertex(2)->point(),
// c->vertex(3)->point()
// );
//
// pointFromPoint p = topoint(circumcenter);
//
// if (geometryToConformTo_.inside(p))
// {
// meshTools::writeOBJ
// (
// strDual,
// p
// );
// }
// }
if (T_.is_valid())
{
Info<< " Triangulation is valid" << endl;
}
else
{
FatalErrorIn
(
"Foam::cellSizeControlSurfaces::writeRefinementTriangulation()"
) << "Triangulation is not valid"
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellSizeControlSurfaces::cellSizeControlSurfaces
(
const searchableSurfaces& allGeometry,
const conformationSurfaces& geometryToConformTo,
const dictionary& motionControlDict
)
:
allGeometry_(allGeometry),
geometryToConformTo_(geometryToConformTo),
surfaces_(),
cellSizeFunctions_(),
defaultCellSize_(readScalar(motionControlDict.lookup("defaultCellSize"))),
@ -214,7 +560,8 @@ Foam::cellSizeControlSurfaces::cellSizeControlSurfaces
const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
Info<< nl << " " << iter().keyword() << nl
<< " surface: " << surfaceName << endl;
<< " surface: " << surfaceName << nl
<< " size : " << surface.size() << endl;
cellSizeFunctions_.set
(
@ -229,11 +576,78 @@ Foam::cellSizeControlSurfaces::cellSizeControlSurfaces
priorities[surfI] = cellSizeFunctions_[surfI].priority();
surfI++;
if (isA<triSurfaceMesh>(surface))
{
const triSurfaceMesh& tsm
= refCast<const triSurfaceMesh>(surface);
const pointField& points = tsm.points();
Info<< " number of points: " << tsm.nPoints() << endl;
std::vector<std::pair<Point, scalar> > pointsToInsert;
forAll(points, pI)
{
size_t nVert = T_.number_of_vertices();
Vertex_handle v = T_.insert
(
Point(points[pI].x(), points[pI].y(), points[pI].z())
);
if (T_.number_of_vertices() == nVert)
{
Info<< "Failed to insert point : " << points[pI] << endl;
}
// Get the value of the point from surfaceCellSizeFunction. If
// adding points internally then will need to interpolate.
scalar newSize = 0;
cellSizeFunctions_[surfI-1].cellSize(points[pI], newSize);
v->value(newSize);
}
}
}
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();
Info<< nl << "Refinement triangulation information: " << endl;
Info<< " Number of vertices: " << label(T_.number_of_vertices()) << endl;
Info<< " Number of cells : "
<< label(T_.number_of_finite_cells()) << endl;
Info<< " Number of faces : "
<< label(T_.number_of_finite_facets()) << endl;
Info<< " Number of edges : "
<< label(T_.number_of_finite_edges()) << endl;
Info<< " Dimensionality : " << label(T_.dimension()) << nl << endl;
// Sort cellSizeFunctions_ and surfaces_ by priority. Cut off any surfaces
// where priority < defaultPriority_
labelList sortedIndices;
sortedOrder(priorities, sortedIndices);
@ -282,8 +696,40 @@ Foam::scalar Foam::cellSizeControlSurfaces::cellSize
{
scalar size = defaultCellSize_;
// bool anyFunctionFound = evalCellSizeFunctions(pt, size);
bool refinementTriangulationSwitch = true;
if (!refinementTriangulationSwitch)
{
evalCellSizeFunctions(pt, size);
}
else
{
Cell_handle ch = T_.locate
(
Point(pt.x(), pt.y(), pt.z()),
oldCellHandle_
);
oldCellHandle_ = ch;
pointFromPoint pA = topoint(ch->vertex(0)->point());
pointFromPoint pB = topoint(ch->vertex(1)->point());
pointFromPoint pC = topoint(ch->vertex(2)->point());
pointFromPoint pD = topoint(ch->vertex(3)->point());
tetPointRef tet(pA, pB, pC, pD);
scalarList bary;
tet.barycentric(pt, bary);
scalar value = 0;
forAll(bary, pI)
{
value += bary[pI]*ch->vertex(pI)->value();
}
size = value;
}
//if (!anyFunctionFound)
//{

View File

@ -37,9 +37,92 @@ SourceFiles
#include "searchableSurfaces.H"
#include "searchableSurfacesQueries.H"
#include "conformationSurfaces.H"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Triangulation_vertex_base_with_info_3.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template < class GT, class Vb = CGAL::Triangulation_vertex_base_3<GT> >
class vertexWithInfo
:
public Vb
{
public:
Foam::scalar value_;
Foam::tensor alignment_;
typedef typename Vb::Vertex_handle Vertex_handle;
typedef typename Vb::Cell_handle Cell_handle;
typedef typename Vb::Point Point;
template < class TDS2 >
struct Rebind_TDS
{
typedef typename Vb::template Rebind_TDS<TDS2>::Other Vb2;
typedef vertexWithInfo<GT, Vb2> Other;
};
vertexWithInfo()
:
Vb(),
value_(0.0),
alignment_(Foam::tensor::zero)
{}
explicit vertexWithInfo(const Point& p)
:
Vb(p),
value_(0.0),
alignment_(Foam::tensor::zero)
{}
vertexWithInfo(const Point& p, const Foam::scalar& value)
:
Vb(p),
value_(value),
alignment_(Foam::tensor::zero)
{}
vertexWithInfo
(
const Point& p,
const Foam::scalar& value,
const Foam::tensor& alignment
)
:
Vb(p),
value_(value),
alignment_(alignment)
{}
const Foam::scalar& value() const
{
return value_;
}
void value(const Foam::scalar& value)
{
value_ = value;
}
const Foam::tensor& alignment() const
{
return alignment_;
}
void alignment(const Foam::tensor& alignment)
{
alignment_ = alignment;
}
};
namespace Foam
{
@ -55,11 +138,29 @@ class cellSizeFunction;
class cellSizeControlSurfaces
{
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_data_structure_3<vertexWithInfo<K> > Tds;
typedef CGAL::Delaunay_triangulation_3<K, Tds, CGAL::Fast_location>
Delaunay;
typedef Delaunay::Cell_handle Cell_handle;
typedef Delaunay::Vertex_handle Vertex_handle;
typedef Delaunay::Locate_type Locate_type;
typedef Delaunay::Point Point;
Delaunay T_;
mutable Cell_handle oldCellHandle_;
// Private data
//- Reference to the searchableSurfaces object holding all geometry data
const searchableSurfaces& allGeometry_;
const conformationSurfaces& geometryToConformTo_;
//- Indices of surfaces in allGeometry that are to be conformed to
labelList surfaces_;
@ -84,6 +185,14 @@ class cellSizeControlSurfaces
scalar& minSize
) const;
bool checkCoplanarTet(Cell_handle c, const scalar tol) const;
bool checkClosePoints(Cell_handle c, const scalar tol) const;
label refineTriangulation(const scalar factor);
void writeRefinementTriangulation();
//- Disallow default bitwise copy construct
cellSizeControlSurfaces(const cellSizeControlSurfaces&);
@ -104,6 +213,7 @@ public:
cellSizeControlSurfaces
(
const searchableSurfaces& allGeometry,
const conformationSurfaces& geometryToConformTo,
const dictionary& motionControlDict
);

View File

@ -56,8 +56,7 @@ Foam::cellSizeFunction::cellSizeFunction
)
),
coeffsDict_(subDict(type + "Coeffs")),
sideMode_(),
priority_(readLabel(cellSizeFunctionDict.lookup("priority")))
sideMode_()
{
word mode = cellSizeFunctionDict.lookup("mode");
@ -77,7 +76,7 @@ Foam::cellSizeFunction::cellSizeFunction
}
else
{
FatalErrorIn("cellSizeFunction::cellSizeFunction")
FatalErrorIn("searchableSurfaceControl::searchableSurfaceControl")
<< "Unknown mode, expected: inside, outside or bothSides" << nl
<< exit(FatalError);
}
@ -86,7 +85,7 @@ Foam::cellSizeFunction::cellSizeFunction
{
if (mode != "bothSides")
{
WarningIn("cellSizeFunction::cellSizeFunction")
WarningIn("searchableSurfaceControl::searchableSurfaceControl")
<< "surface does not support volumeType, defaulting mode to "
<< "bothSides."
<< endl;

View File

@ -59,9 +59,6 @@ class cellSizeFunction
public:
//- Runtime type information
TypeName("cellSizeFunction");
//- Surface side mode
enum sideMode
{
@ -70,6 +67,9 @@ public:
rmBothsides // Control on both sides of a surface
};
//- Runtime type information
TypeName("cellSizeFunction");
protected:
@ -97,9 +97,6 @@ protected:
//- Mode of size specification, i.e. inside, outside or bothSides
sideMode sideMode_;
//- Priority of this cellSizeFunction
label priority_;
private:
@ -162,11 +159,6 @@ public:
return coeffsDict_;
}
inline label priority() const
{
return priority_;
}
//- 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

View File

@ -26,6 +26,7 @@ License
#include "automatic.H"
#include "addToRunTimeSelectionTable.H"
#include "triSurfaceMesh.H"
#include "vtkSurfaceWriter.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -36,6 +37,59 @@ namespace Foam
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;
totalDist += 1.0/distance;
if (value < faceValue)
{
nFaces++;
}
}
// Do not smooth out the peak values
if (nFaces == faceFaces.size())
{
//continue;
}
surf[sI] = newValue/totalDist;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::automatic::automatic
@ -90,7 +144,8 @@ Foam::triSurfaceScalarField Foam::automatic::load()
if (readCurvature_)
{
Info<< indent << "Reading curvature: " << curvatureFile_ << endl;
Info<< indent << "Reading curvature : "
<< curvatureFile_ << endl;
triSurfacePointScalarField curvature
(
@ -204,8 +259,34 @@ Foam::triSurfaceScalarField Foam::automatic::load()
}
}
smoothField(surfaceCellSize);
surfaceCellSize.write();
debug = 1;
if (debug)
{
faceList faces(surface_.size());
forAll(surface_, fI)
{
faces[fI] = surface_.triSurface::operator[](fI).triFaceFace();
}
vtkSurfaceWriter().write
(
surface_.searchableSurface::time().constant()/"triSurface",
surfaceName_,
surface_.points(),
faces,
"cellSize",
surfaceCellSize,
false,
true
);
}
return surfaceCellSize;
}

View File

@ -85,6 +85,11 @@ private:
const scalar maximumCellSize_;
// Private Member Functions
void smoothField(triSurfaceScalarField& surf);
public:
//- Runtime type information

View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
Typedefs
CGALTriangulation3Ddefs
@ -43,76 +38,20 @@ Description
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "CGAL/Delaunay_triangulation_3.h"
#include "CGALTriangulation3DKernel.H"
#include "indexedVertex.H"
#include "indexedCell.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"
#include <CGAL/Robust_circumcenter_traits_3.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel inexactK;
typedef CGAL::Robust_circumcenter_traits_3<inexactK> K;
#else
// Very robust but expensive kernel
#include "CGAL/Exact_predicates_exact_constructions_kernel.h"
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
#endif
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, CGAL::Fast_location> Delaunay;
typedef Delaunay::Vertex_handle Vertex_handle;
typedef Delaunay::Cell_handle Cell_handle;
typedef Delaunay::Point Point;
//- Spatial sort traits to use with a pair of point pointers and an integer.
// Taken from a post on the CGAL lists: 2010-01/msg00004.html by
// Sebastien Loriot (Geometry Factory).
template<class Triangulation>
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
{
return typename Gt::Less_x_3()(*(p.first), *(q.first));
}
};
struct Less_y_3
{
bool operator()(const Point_3& p, const Point_3& q) const
{
return typename Gt::Less_y_3()(*(p.first), *(q.first));
}
};
struct Less_z_3
{
bool operator()(const Point_3& p, const Point_3& q) const
{
return typename Gt::Less_z_3()(*(p.first), *(q.first));
}
};
Less_x_3 less_x_3_object () const {return Less_x_3();}
Less_y_3 less_y_3_object () const {return Less_y_3();}
Less_z_3 less_z_3_object () const {return Less_z_3();}
};
typedef CGAL::Delaunay_triangulation_3<K, Tds, CompactLocator> Delaunay;
typedef CGAL::Delaunay_triangulation_3<K, Tds, FastLocator> CellSizeDelaunay;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
Class
Foam::conformalVoronoiMesh
@ -50,7 +45,7 @@ SourceFiles
#include "ulong.H"
#include "searchableSurfaces.H"
#include "conformationSurfaces.H"
#include "cellSizeControlSurfaces.H"
#include "cellShapeControl.H"
#include "cvControls.H"
#include "DynamicList.H"
#include "PackedBoolList.H"
@ -77,6 +72,11 @@ SourceFiles
#include "zeroGradientFvPatchFields.H"
#include "globalIndex.H"
#include "pointFeatureEdgesTypes.H"
#include "pointConversion.H"
#include "Tuple2.H"
#include "DistributedDelaunayMesh.H"
#include "tensorIOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -98,24 +98,25 @@ class backgroundMeshDecomposition;
class conformalVoronoiMesh
:
public Delaunay
public DistributedDelaunayMesh<Delaunay>
{
public:
enum reconformationMode
{
rmNone, // Do not rebuild the surface conformation
rmCoarse, // Rebuild the conformation with coarse tolerances (faster)
rmFine // Rebuild the conformation with fine tolerances (slower)
rmOff, // Do not rebuild the surface conformation
rmOn
};
enum faceCollapseMode
{
fcmNone, // Do not collapse face
fcmEdge, // Collapse face to a single edge
fcmPoint, // Collapse face to a point
fcmDeferredMultiEdge // Collapse face to several edges
};
typedef Delaunay::Vertex_handle Vertex_handle;
typedef Delaunay::Cell_handle Cell_handle;
typedef Delaunay::Point Point;
typedef List<DynamicList<Pair<labelPair> > > labelPairPairDynListList;
typedef Tuple2<pointIndexHit, label> pointIndexHitAndFeature;
typedef List<pointIndexHitAndFeature> pointIndexHitAndFeatureList;
typedef DynamicList<pointIndexHitAndFeature> pointIndexHitAndFeatureDynList;
private:
@ -147,12 +148,8 @@ private:
//- The surfaces to conform to
conformationSurfaces geometryToConformTo_;
//- The cell size control object
cellSizeControlSurfaces cellSizeControl_;
//- Keep track of the start index of the internal points. Needs
// careful bookkeeping within several functions.
label startOfInternalPoints_;
//- The cell shape control object
cellShapeControl cellShapeControl_;
//- Limiting bound box before infinity begins
treeBoundBox limitBounds_;
@ -169,10 +166,14 @@ private:
mutable autoPtr<dynamicIndexedOctree<dynamicTreeDataPoint> >
edgeLocationTreePtr_;
mutable DynamicList<Foam::point> existingEdgeLocations_;
//- Search tree for surface point locations
mutable autoPtr<dynamicIndexedOctree<dynamicTreeDataPoint> >
surfacePtLocationTreePtr_;
mutable DynamicList<Foam::point> existingSurfacePtLocations_;
//- Store locations where the cell size and alignments will be
// pre-calculated and looked up
pointField sizeAndAlignmentLocations_;
@ -205,6 +206,8 @@ private:
// Private Member Functions
inline scalar defaultCellSize() const;
//- Return the local target cell size at the given location. Takes
// boolean argument to allow speed-up of queries if the point is going
// to be on a surface.
@ -271,64 +274,55 @@ private:
//- Return the required alignment directions at the given location
tensor requiredAlignment(const Foam::point& pt) const;
//- Insert Foam::point and return its auto-generated index
inline label insertPoint
(
const Foam::point& p,
const label type
);
//- Insert Point and return its auto-generated index
inline label insertPoint
inline bool insertPoint
(
const Point& P,
const label type
const indexedVertexEnum::vertexType type
);
//- Insert Foam::point with specified index and type
inline void insertPoint
inline bool insertPoint
(
const Foam::point& p,
const label index,
const label type
const indexedVertexEnum::vertexType type
);
//- Insert Point with specified index and type
inline void insertPoint
//- Insert Point with specified index, type and original processor
inline bool insertReferredPoint
(
const Point& P,
const label index,
const label type
const indexedVertexEnum::vertexType type,
const label processor
);
inline bool insertReferredPoint(const Vb& P);
//- Insert Foam::point with specified index, type and original processor
inline bool insertReferredPoint
(
const Foam::point& p,
const label index,
const indexedVertexEnum::vertexType type,
const label processor
);
//- Insert Delaunay vertices using the CGAL range insertion method,
// optionally check processor occupancy and distribute to other
// processors
void insertPoints
void insertInternalPoints
(
List<Point>& points,
bool distribute = true
const bool distribute = false
);
//- Insert indexed and typed Delaunay vertices, optionally check
// processor occupancy and distribute to other processors
void insertPoints
(
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types,
List<Vb>& vertices,
bool distribute = true
);
//- Insert a point-pair at a ppDist distance either side of
// surface point surfPt, in the direction n
inline void insertPointPair
(
const scalar ppDist,
const Foam::point& surfPt,
const vector& n
);
//- Create a point-pair at a ppDist distance either side of
// surface point surfPt, in the direction n
inline void createPointPair
@ -336,17 +330,26 @@ private:
const scalar ppDist,
const Foam::point& surfPt,
const vector& n,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
inline Foam::point perturbPoint(const Foam::point& pt) const;
//- Create a point-pair at a ppDist distance either side of
// surface point surfPt, in the direction n
inline void createBafflePointPair
(
const scalar ppDist,
const Foam::point& surfPt,
const vector& n,
DynamicList<Vb>& pts
);
//- Insert pairs of points on the surface with the given normals, at the
// specified spacing
void insertSurfacePointPairs
(
const List<pointIndexHit>& surfaceHits,
const List<label>& hitSurfaces,
const pointIndexHitAndFeatureList& surfaceHits,
const fileName fName = fileName::null
);
@ -355,8 +358,7 @@ private:
// to be conformed to on the corresponding entry in featureHit
void insertEdgePointGroups
(
const List<pointIndexHit>& edgeHits,
const labelList& featuresHit,
const pointIndexHitAndFeatureList& edgeHits,
const fileName fName = fileName::null
);
@ -365,9 +367,7 @@ private:
(
const extendedFeatureEdgeMesh& feMesh,
const pointIndexHit& edHit,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Create points to conform to an external edge
@ -375,9 +375,7 @@ private:
(
const extendedFeatureEdgeMesh& feMesh,
const pointIndexHit& edHit,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Create points to conform to an internal edge
@ -385,9 +383,7 @@ private:
(
const extendedFeatureEdgeMesh& feMesh,
const pointIndexHit& edHit,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Create points to conform to a flat edge
@ -395,9 +391,7 @@ private:
(
const extendedFeatureEdgeMesh& feMesh,
const pointIndexHit& edHit,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Create points to conform to an open edge
@ -405,9 +399,7 @@ private:
(
const extendedFeatureEdgeMesh& feMesh,
const pointIndexHit& edHit,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Create points to conform to multiply connected edge
@ -415,39 +407,54 @@ private:
(
const extendedFeatureEdgeMesh& feMesh,
const pointIndexHit& edHit,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Determine and insert point groups at the feature points
void insertFeaturePoints();
bool edgesShareNormal(const label e1, const label e2) const;
//- Create point groups at convex feature points
void createConvexFeaturePoints
(
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
);
//- Create point groups at concave feature points
void createConcaveFeaturePoints
(
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
);
//- Create point groups at mixed feature points
void createMixedFeaturePoints
void createMixedFeaturePoints(DynamicList<Vb>& pts);
void addMasterAndSlavePoints
(
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
);
const DynamicList<Foam::point>& masterPoints,
const DynamicList<indexedVertexEnum::vertexType>&masterPointsTypes,
const Map<DynamicList<autoPtr<plane> > >& masterPointReflections,
DynamicList<Vb>& pts,
const label ptI
) const;
label getSign(const extendedFeatureEdgeMesh::edgeStatus eStatus) const;
void createMasterAndSlavePoints
(
const extendedFeatureEdgeMesh& feMesh,
const label ptI,
DynamicList<Vb>& pts
) const;
void createFeaturePoints(DynamicList<Vb>& pts);
vector sharedFaceNormal
(
const extendedFeatureEdgeMesh& feMesh,
const label edgeI,
const label nextEdgeI
) const;
List<Foam::point> reflectPointInPlanes
(
const Foam::point p,
const DynamicList<autoPtr<plane> >& planes
) const;
Foam::point reflectPointInPlane
(
const Foam::point p,
const plane& planeN
) const;
//- Fill the pointFeatureEdgesType struct with the types of feature
// edges that are attached to the point.
@ -467,9 +474,7 @@ private:
const pointFeatureEdgesTypes& pFEdgeTypes,
const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat,
const label ptI,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
);
//- Store the locations of all of the features to be conformed to
@ -486,28 +491,24 @@ private:
//- Check if a location is in exclusion range around a feature point
bool nearFeaturePt(const Foam::point& pt) const;
//- Clear the entire tesselation
// Reinsert bounding points, feature points and recalculate
// startOfInternalPoints_
void reset(const bool distribute = false);
//- Insert far points in a large bounding box to avoid dual edges
// spanning huge distances
void insertBoundingPoints();
//- Reinsert the bounding points
void reinsertBoundingPoints();
//- Insert the initial points into the triangulation, based on the
// initialPointsMethod
void insertInitialPoints();
//- Calculate the worst load balance
scalar calculateLoadUnbalance() const;
//- In parallel redistribute the backgroundMeshDecomposition and
// vertices to balance the number of vertices on each processor.
// Returns true if the background mesh changes as this removes all
// referred vertices, so the parallel interface may need rebuilt.
bool distributeBackground();
//-
void distribute();
void buildCellSizeAndAlignmentMesh();
//- Store data for sizeAndAlignmentLocations_, storedSizes_ and
// storedAlignments_ and initialise the sizeAndAlignmentTreePtr_,
// determining the appropriate sizeAndAlignmentLocations_
@ -568,9 +569,28 @@ private:
// conformation
reconformationMode reconformationControl() const;
//- Determines geometrically whether a vertex is close to a surface
// This is an optimisation
label findVerticesNearBoundaries();
//- Create and insert the necessary point pairs to conform to the
// surface, then store the result
void buildSurfaceConformation(reconformationMode reconfMode);
void buildSurfaceConformation();
label synchroniseEdgeTrees
(
pointIndexHitAndFeatureList& featureEdgeHits
);
label synchroniseSurfaceTrees
(
pointIndexHitAndFeatureList& surfaceHits
);
bool locationConformsToInside
(
const pointIndexHitAndFeature& info
) const;
//- Check to see if dual cell specified by given vertex iterator
// intersects the boundary and hence reqires a point-pair
@ -583,8 +603,7 @@ private:
bool dualCellSurfaceAllIntersections
(
const Delaunay::Finite_vertices_iterator& vit,
DynamicList<pointIndexHit>& info,
DynamicList<label>& hitSurface
pointIndexHitAndFeatureDynList& info
) const;
//- Return false if the line is entirely outside the current processor
@ -599,64 +618,6 @@ private:
Foam::point& b
) const;
label removeProcessorBoundarySeeds(bool reinsertBoundPts);
void seedProcessorBoundarySurfaces(bool seedProcessors);
label numberOfUnusedReferredPoints() const;
//- Build the parallelInterfaces of the mesh
void buildParallelInterface
(
const word& outputName
);
//- Build the parallelInterfaces of the mesh, supply hash sets
// externally to allow updates
void buildParallelInterface
(
List<labelHashSet>& referralVertices,
List<labelHashSet>& receivedVertices,
bool initialEdgeReferral,
const word& outputName
);
//- Refer all vertices to all processors
void buildParallelInterfaceAll
(
List<labelHashSet>& referralVertices,
List<labelHashSet>& receivedVertices,
const word& outputName
);
//- Refer vertices where there dual edge pierces other processors
void buildParallelInterfaceIntersection
(
List<labelHashSet>& referralVertices,
List<labelHashSet>& receivedVertices,
const word& outputName
);
//- Refer vertices that are attached to Delaunay tets whose
// circumspheres touch other processors
void buildParallelInterfaceInfluence
(
List<labelHashSet>& referralVertices,
List<labelHashSet>& receivedVertices,
const word& outputName
);
//- Refer vertices to their required processors
void referVertices
(
const DynamicList<label>& targetProcessor,
DynamicList<Foam::point>& parallelPoints,
DynamicList<label>& parallelIndices,
List<labelHashSet>& receivedVertices,
const word& stageName,
const word& outputName
);
//- Find the "worst" protrusion of a dual cell through the surface,
// subject to the maxSurfaceProtrusion tolerance
void dualCellLargestSurfaceProtrusion
@ -681,7 +642,7 @@ private:
//- Write out debugging information about the surface conformation
// quality
void reportSurfaceConformationQuality();
// void reportSurfaceConformationQuality();
//- Limit the displacement of a point so that it doesn't penetrate the
// surface to be meshed or come too close to it
@ -698,23 +659,19 @@ private:
//- Check if a surface point is near another.
bool nearSurfacePoint
(
pointIndexHit& pHit,
label& surfaceHit,
DynamicList<Foam::point>& existingSurfacePtLocations
pointIndexHitAndFeature& pHit
) const;
//- Append a point to the surface point tree and the existing list
bool appendToSurfacePtTree
(
const Foam::point& pt,
DynamicList<Foam::point>& existingSurfacePtLocations
const Foam::point& pt
) const;
//- Append a point to the edge location tree and the existing list
bool appendToEdgeLocationTree
(
const Foam::point& pt,
DynamicList<Foam::point>& existingEdgeLocations
const Foam::point& pt
) const;
//- Return a list of the nearest feature edge locations
@ -745,8 +702,7 @@ private:
//- edge conformation location
bool nearFeatureEdgeLocation
(
pointIndexHit& pHit,
DynamicList<Foam::point>& existingEdgeLocations
pointIndexHit& pHit
) const;
//- Build or rebuild the edge location tree
@ -769,18 +725,11 @@ private:
void addSurfaceAndEdgeHits
(
const Delaunay::Finite_vertices_iterator& vit,
const Foam::point& vert,
const DynamicList<pointIndexHit>& surfHit,
const DynamicList<label>& hitSurface,
const pointIndexHitAndFeatureDynList& surfaceIntersections,
scalar surfacePtReplaceDistCoeffSqr,
scalar edgeSearchDistCoeffSqr,
DynamicList<pointIndexHit>& surfaceHits,
DynamicList<label>& hitSurfaces,
DynamicList<pointIndexHit>& featureEdgeHits,
DynamicList<label>& featureEdgeFeaturesHit,
DynamicList<Foam::point>& newEdgeLocations,
DynamicList<Foam::point>& existingEdgeLocations,
DynamicList<Foam::point>& existingSurfacePtLocations
pointIndexHitAndFeatureDynList& surfaceHits,
pointIndexHitAndFeatureDynList& featureEdgeHits
) const;
//- Store the surface conformation with the indices offset to be
@ -791,10 +740,19 @@ private:
// relative to new number of internal vertices
void reinsertSurfaceConformation();
void checkCells();
void checkDuals();
void checkVertices();
void checkCoPlanarCells() const;
//- Dual calculation
void calcDualMesh
(
pointField& points,
labelList& boundaryPts,
faceList& faces,
labelList& owner,
labelList& neighbour,
@ -806,7 +764,7 @@ private:
pointField& cellCentres,
labelList& cellToDelaunayVertex,
labelListList& patchToDelaunayVertex,
bool filterFaces
PackedBoolList& boundaryFacesToRemove
);
//- Tet mesh calculation
@ -844,77 +802,27 @@ private:
const Delaunay::Finite_facets_iterator& fit
) const;
//- Merge adjacent edges that are not attached to other faces
label mergeNearlyParallelEdges
//- Determines if the dual face constructed by the Delaunay
// edge is a processor boundary face
inline bool isProcBoundaryEdge
(
const Delaunay::Finite_edges_iterator& eit
) const;
//- Merge vertices that are identical
void mergeIdenticalDualVertices
(
const pointField& pts,
const scalar maxCosAngle
const labelList& boundaryPts
);
//- Merge vertices that are very close together
void mergeCloseDualVertices
label mergeIdenticalDualVertices
(
const pointField& pts,
const PackedBoolList& boundaryPts
);
label mergeCloseDualVertices
(
const pointField& pts,
const PackedBoolList& boundaryPts,
const labelList& boundaryPts,
Map<label>& dualPtIndexMap
) const;
//- Smooth the dual vertices of the dual faces on the boundary
// so that they conform to the surface and remove any
// small, normal oriented faces
void smoothSurface
(
pointField& pts,
const PackedBoolList& boundaryPts
);
label smoothSurfaceDualFaces
(
pointField& pts,
const PackedBoolList& boundaryPts,
Map<label>& dualPtIndexMap
) const;
//- Collapse a face to a point or an edge, modifying and
// mapping the points, returns the true if the face was
// collapsed in this operation
void collapseFaces
(
pointField& pts,
const PackedBoolList& boundaryPts,
HashSet<labelPair, labelPair::Hash<> >& deferredCollapseFaces
);
label collapseFaces
(
pointField& pts,
const PackedBoolList& boundaryPts,
Map<label>& dualPtIndexMap,
HashSet<labelPair, labelPair::Hash<> >& deferredCollapseFaces
) const;
//- Collapse a face to an edge, updating the point and point
// map. Returns the collapse mode that was applied.
faceCollapseMode collapseFace
(
const face& f,
pointField& pts,
const PackedBoolList& boundaryPts,
Map<label>& dualPtIndexMap,
scalar targetFaceSize,
scalar collapseSizeLimitCoeff,
label maxFC
) const;
//- Identify the index of the longest edge on the face
label longestEdge(const face& f, const pointField& pts) const;
//- Identify the face labels of the deferred collapse faces
void deferredCollapseFaceSet
(
@ -943,12 +851,19 @@ private:
void indexDualVertices
(
pointField& pts,
PackedBoolList& boundaryPts
labelList& boundaryPts
);
//- Re-index all of the the Delaunay cells
//- Re-index all of the Delaunay cells
void reindexDualVertices(const Map<label>& dualPtIndexMap);
label createPatchInfo
(
wordList& patchNames,
wordList& patchTypes,
labelList& procNeighbours
) const;
//- Create all of the internal and boundary faces
void createFacesOwnerNeighbourAndPatches
(
@ -961,6 +876,7 @@ private:
labelList& patchStarts,
labelList& procNeighbours,
labelListList& patchPointPairSlaves,
PackedBoolList& boundaryFacesToRemove,
bool includeEmptyPatches = false
) const;
@ -987,7 +903,7 @@ private:
List<DynamicList<face> >& patchFaces,
List<DynamicList<label> >& patchOwners,
List<DynamicList<label> >& patchPointPairSlaves,
List<Pair<DynamicList<label> > >& patchSortingIndices
labelPairPairDynListList& patchSortingIndices
) const;
//- Add the faces and owner information for the patches
@ -998,15 +914,18 @@ private:
labelList& owner,
labelList& patchSizes,
labelList& patchStarts,
PackedBoolList& boundaryFacesToRemove,
const List<DynamicList<face> >& patchFaces,
const List<DynamicList<label> >& patchOwners
const List<DynamicList<label> >& patchOwners,
const List<DynamicList<bool> >& indirectPatchFace
) const;
//- Remove points that are no longer used by any faces
void removeUnusedPoints
(
faceList& faces,
pointField& pts
pointField& pts,
labelList& boundaryPts
) const;
//- Remove dual cells that are not used by any faces. Return compaction
@ -1031,6 +950,21 @@ private:
//- Create a polyMesh from points.
autoPtr<polyMesh> createPolyMeshFromPoints(const pointField& pts) const;
void checkProcessorPatchesMatch
(
const wordList& patchTypes,
const labelList& patchSizes,
const labelList& procNeighbours
) const;
void reorderPoints
(
pointField& points,
labelList& boundaryPts,
faceList& faces,
const label nInternalFaces
) const;
//- Rotate the faces on processor patches if necessary
void reorderProcessorPatches
(
@ -1078,6 +1012,8 @@ public:
// surface as required
void move();
void printVertexInfo() const;
//- Check if the point is in the domain handled by this processor
bool positionOnThisProc(const Foam::point& pt) const;
@ -1094,30 +1030,18 @@ public:
const List<Foam::point>& ends
) const;
//- Which other processors does each sphere overlap
labelListList overlapsProc
(
const List<Foam::point>& centres,
const List<scalar>& radiusSqrs
) const;
//- Conversion functions between point (FOAM::) and Point (CGAL)
# ifdef CGAL_INEXACT
typedef const Foam::point& pointFromPoint;
typedef const Point& PointFrompoint;
# else
typedef Foam::point pointFromPoint;
typedef Point PointFrompoint;
# endif
inline pointFromPoint topoint(const Point&) const;
inline PointFrompoint toPoint(const Foam::point&) const;
// //- Which other processors does each sphere overlap
// labelListList overlapsProc
// (
// const List<Foam::point>& centres,
// const List<scalar>& radiusSqrs
// ) const;
typedef K::Vector_3 CGALVector;
inline CGALVector toCGALVector(const Foam::vector& v) const;
// Access
//- Return the Time object
@ -1135,8 +1059,8 @@ public:
//- Return the backgroundMeshDecomposition
inline const backgroundMeshDecomposition& decomposition() const;
//- Return the cellSizeControlSurfaces object
inline const cellSizeControlSurfaces& cellSizeControl() const;
//- Return the cellShapeControl object
inline const cellShapeControl& cellShapeControls() const;
//- Return the cvMeshControls object
inline const cvControls& cvMeshControls() const;
@ -1159,8 +1083,21 @@ public:
label offset = 0
) const;
//- Write Delaunay points to .obj file
void writePoints(const fileName& fName, bool internalOnly) const;
//- Write Delaunay points in the range between (and including)
// type startPointType and endPointType to .obj file
void writePoints
(
const fileName& fName,
const Foam::indexedVertexEnum::vertexType startPointType,
const Foam::indexedVertexEnum::vertexType endPointType
) const;
//- Write Delaunay points of type pointType to .obj file
void writePoints
(
const fileName& fName,
const Foam::indexedVertexEnum::vertexType pointType
) const;
//- Write the boundary Delaunay points to .obj file
void writeBoundaryPoints(const fileName& fName) const;
@ -1172,17 +1109,20 @@ public:
const List<Foam::point>& points
) const;
//- Write list of points to file
void writePoints
(
const fileName& fName,
const List<Vb>& points
) const;
//- Write the internal Delaunay vertices of the tessellation as a
// pointField that may be used to restart the meshing process
void writeInternalDelaunayVertices(const fileName& instance) const;
//- Prepare data and call writeMesh for polyMesh and
// tetDualMesh
void writeMesh
(
const fileName& instance,
bool filterFaces = true
);
void writeMesh(const fileName& instance);
//- Write mesh to disk
void writeMesh
@ -1190,6 +1130,7 @@ public:
const word& meshName,
const fileName& instance,
pointField& points,
labelList& boundaryPts,
faceList& faces,
labelList& owner,
labelList& neighbour,
@ -1198,7 +1139,8 @@ public:
const labelList& patchSizes,
const labelList& patchStarts,
const labelList& procNeighbours,
const pointField& cellCentres
const pointField& cellCentres,
const PackedBoolList& boundaryFacesToRemove
) const;
//- Write points and faces as .obj file
@ -1214,6 +1156,8 @@ public:
// actual cell size (cbrt(actual cell volume)).
void writeCellSizes(const fvMesh& mesh) const;
void writeCellAlignments(const fvMesh& mesh) const;
//- Calculate and write the cell centres.
void writeCellCentres(const fvMesh& mesh) const;
@ -1226,90 +1170,6 @@ public:
const fileName& fName,
const faceList& faces
) const;
//- 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).
//
// @todo problems putting declaration in the .C file. Function
// prototype is not recognised.
template<class Triangulation, class Point_iterator>
void rangeInsertWithInfo
(
Point_iterator begin,
Point_iterator end,
Triangulation& T,
DynamicList<label>& indices,
DynamicList<label>& types
)
{
typedef std::vector
<
std::pair<const typename Triangulation::Point*, label>
> vectorPairPointIndex;
vectorPairPointIndex points;
label index = 0;
for (Point_iterator it = begin; it != end; ++it)
{
points.push_back
(
std::make_pair(&(toPoint(*it)), index++)
);
}
std::random_shuffle(points.begin(), points.end());
spatial_sort
(
points.begin(),
points.end(),
Traits_for_spatial_sort<Triangulation>()
);
typename Triangulation::Vertex_handle hint;
for
(
typename vectorPairPointIndex::const_iterator
p = points.begin();
p != points.end();
++p
)
{
const size_t checkInsertion = T.number_of_vertices();
hint = T.insert(*(p->first), hint);
if (checkInsertion != T.number_of_vertices() - 1)
{
Pout<< "Failed to insert point "
<< topoint(*(p->first)) << endl;
}
else
{
label oldIndex = p->second;
label type = types[oldIndex];
if (type > Vb::vtFar)
{
// This is a member of a point pair, don't use the
// type directly (note that this routine never gets
// called for referredPoints so type will never be
// -procI
type += checkInsertion;
}
hint->index() = indices[oldIndex] + checkInsertion;
hint->type() = type;
}
}
}
};
@ -1321,10 +1181,6 @@ public:
#include "conformalVoronoiMeshI.H"
//#ifdef NoRepository
//# include "conformalVoronoiMeshTemplates.C"
//#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -48,39 +48,7 @@ Foam::conformalVoronoiMesh::calcPointFeatureEdgesTypes
eS = feMesh.getEdgeStatus(edgeI);
switch (eS)
{
case extendedFeatureEdgeMesh::EXTERNAL:
{
pFEdgeTypes.nExternal++;
break;
}
case extendedFeatureEdgeMesh::INTERNAL:
{
pFEdgeTypes.nInternal++;
break;
}
case extendedFeatureEdgeMesh::FLAT:
{
pFEdgeTypes.nFlat++;
break;
}
case extendedFeatureEdgeMesh::OPEN:
{
pFEdgeTypes.nOpen++;
break;
}
case extendedFeatureEdgeMesh::MULTIPLE:
{
pFEdgeTypes.nMultiple++;
break;
}
case extendedFeatureEdgeMesh::NONE:
{
pFEdgeTypes.nNonFeature++;
break;
}
}
pFEdgeTypes(eS)++;
}
if (debug)
@ -99,15 +67,22 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
const pointFeatureEdgesTypes& pFEdgesTypes,
const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat,
const label ptI,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
)
{
if
(
pFEdgesTypes.nExternal == 2
&& pFEdgesTypes.nInternal == 1
!pFEdgesTypes.found(extendedFeatureEdgeMesh::EXTERNAL)
|| !pFEdgesTypes.found(extendedFeatureEdgeMesh::INTERNAL)
)
{
return false;
}
if
(
pFEdgesTypes[extendedFeatureEdgeMesh::EXTERNAL] == 2
&& pFEdgesTypes[extendedFeatureEdgeMesh::INTERNAL] == 1
&& pEds.size() == 3
)
{
@ -120,6 +95,8 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
return false;
}
label nVert = number_of_vertices();
const label initialNumOfPoints = pts.size();
const scalar ppDist = pointPairDistance(featPt);
@ -212,18 +189,20 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
- 2.0*planeA.distance(concaveEdgeExternalPt)
*concaveEdgePlaneANormal;
pts.append(internalPtA);
indices.append(0);
types.append(4);
pts.append
(
Vb(internalPtA, Vb::vtInternalFeaturePoint)
);
const Foam::point internalPtB =
concaveEdgeExternalPt
- 2.0*planeB.distance(concaveEdgeExternalPt)
*concaveEdgePlaneBNormal;
pts.append(internalPtB);
indices.append(0);
types.append(3);
pts.append
(
Vb(internalPtB, Vb::vtInternalFeaturePoint)
);
// Add the external points
@ -295,8 +274,7 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
for (label i = 0; i < 2; ++i)
{
pts.remove();
indices.remove();
types.remove();
nVert--;
}
return false;
@ -325,9 +303,10 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
+ 2.0*planeC.distance(internalPtA)
*convexEdgePlaneCNormal;
pts.append(externalPtD);
indices.append(0);
types.append(-2);
pts.append
(
Vb(externalPtD, Vb::vtExternalFeaturePoint)
);
}
}
}
@ -355,17 +334,19 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
+ 2.0*planeD.distance(internalPtB)
*convexEdgePlaneDNormal;
pts.append(externalPtE);
indices.append(0);
types.append(-2);
pts.append
(
Vb(externalPtE, Vb::vtExternalFeaturePoint)
);
}
}
}
}
pts.append(concaveEdgeExternalPt);
indices.append(0);
types.append(-4);
pts.append
(
Vb(concaveEdgeExternalPt, Vb::vtExternalFeaturePoint)
);
const scalar totalAngle = radToDeg
(
@ -375,12 +356,13 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
if (totalAngle > cvMeshControls().maxQuadAngle())
{
// Add additional mitering points
// Add additional mitreing points
//scalar angleSign = 1.0;
vector convexEdgesPlaneNormal =
0.5*(convexEdgePlaneCNormal + convexEdgePlaneDNormal);
plane planeM(featPt, convexEdgesPlaneNormal);
// if
@ -410,17 +392,19 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
//+ (2.0 + guard)*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt);
+ 2.0*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt);
pts.append(internalPtF);
indices.append(0);
types.append(1);
pts.append
(
Vb(internalPtF, Vb::vtInternalFeaturePoint)
);
const Foam::point externalPtG =
internalPtF
+ 2.0*planeM.distance(internalPtF)*convexEdgesPlaneNormal;
pts.append(externalPtG);
indices.append(0);
types.append(-1);
pts.append
(
Vb(externalPtG, Vb::vtExternalFeaturePoint)
);
}
if (debug)
@ -428,13 +412,17 @@ bool Foam::conformalVoronoiMesh::createSpecialisedFeaturePoint
for (label ptI = initialNumOfPoints; ptI < pts.size(); ++ptI)
{
Info<< "Point " << ptI << " : ";
meshTools::writeOBJ(Info, pts[ptI]);
meshTools::writeOBJ(Info, topoint(pts[ptI].point()));
}
}
return true;
}
else if (pFEdgesTypes.nExternal == 1 && pFEdgesTypes.nInternal == 2)
else if
(
pFEdgesTypes[extendedFeatureEdgeMesh::EXTERNAL] == 1
&& pFEdgesTypes[extendedFeatureEdgeMesh::INTERNAL] == 2
)
{
// Info<< "nExternal == 1 && nInternal == 2" << endl;

View File

@ -21,21 +21,28 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline Foam::scalar Foam::conformalVoronoiMesh::defaultCellSize() const
{
return readScalar
(
cvMeshControls().cvMeshDict().subDict("motionControl").lookup
(
"defaultCellSize"
)
);
}
inline Foam::scalar Foam::conformalVoronoiMesh::targetCellSize
(
const Foam::point& pt
) const
{
return cellSizeControl().cellSize(pt);
return cellShapeControls().cellSize(pt);
}
@ -66,8 +73,8 @@ inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
{
if
(
!vA->internalOrBoundaryPoint()
&& !vB->internalOrBoundaryPoint()
(!vA->internalOrBoundaryPoint() || vA->referred())
&& (!vB->internalOrBoundaryPoint() || vB->referred())
)
{
// There are no internalOrBoundaryPoints available, determine
@ -80,11 +87,11 @@ inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
*targetCellSize(topoint(vB->point()))
);
}
else if (!vB->internalOrBoundaryPoint())
else if (!vB->internalOrBoundaryPoint() || vB->referred())
{
return vA->targetCellSize();
}
else if (!vA->internalOrBoundaryPoint())
else if (!vA->internalOrBoundaryPoint() || vA->referred())
{
return vB->targetCellSize();
}
@ -98,9 +105,10 @@ inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
const Delaunay::Finite_facets_iterator& fit
) const
{
// Geometric mean
// Arithmetic mean
scalar sizeSum = 0;
scalar sizeProduct = 1;
label nProducts = 0;
const Cell_handle c(fit->first);
@ -110,10 +118,10 @@ inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
{
Vertex_handle v = c->vertex(vertex_triple_index(oppositeVertex, i));
if (v->internalOrBoundaryPoint())
if (v->internalOrBoundaryPoint() && !v->referred())
{
sizeProduct *= v->targetCellSize();
sizeSum += v->targetCellSize();
nProducts++;
}
@ -128,13 +136,22 @@ inline Foam::scalar Foam::conformalVoronoiMesh::averageAnyCellSize
{
Vertex_handle v = c->vertex(vertex_triple_index(oppositeVertex, i));
sizeProduct *= targetCellSize(topoint(v->point()));
sizeSum += targetCellSize(topoint(v->point()));
}
nProducts = 3;
}
return pow(sizeProduct, (1.0/nProducts));
if (sizeSum < 0)
{
WarningIn("averageAnyCellSize(const Delaunay::Finite_facets_iterator&)")
<< "sizeSum = " << sizeSum
<< endl;
return 0;
}
return pow(sizeSum, (1.0/nProducts));
}
@ -219,93 +236,91 @@ inline Foam::scalar Foam::conformalVoronoiMesh::maxSurfaceProtrusion
}
inline Foam::label Foam::conformalVoronoiMesh::insertPoint
inline bool Foam::conformalVoronoiMesh::insertPoint
(
const Foam::point& p,
const label type
const indexedVertexEnum::vertexType type
)
{
return insertPoint(toPoint(p), type);
return insertPoint(toPoint<Point>(p), type);
}
inline Foam::label Foam::conformalVoronoiMesh::insertPoint
inline bool Foam::conformalVoronoiMesh::insertPoint
(
const Point& P,
const label type
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) << endl;
Pout<< "Failed to insert point : " << topoint(P)
<< " of type " << type << endl;
pointInserted = false;
}
else
{
vh->index() = nVert;
vh->index() = getNewVertexIndex();
vh->type() = type;
}
return vh->index();
return pointInserted;
}
inline void Foam::conformalVoronoiMesh::insertPoint
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 label type
const indexedVertexEnum::vertexType type,
const label processor
)
{
insertPoint(toPoint(p), index, type);
return insertReferredPoint(toPoint<Point>(p), index, type, processor);
}
inline void Foam::conformalVoronoiMesh::insertPoint
inline bool Foam::conformalVoronoiMesh::insertReferredPoint
(
const Point& P,
const label index,
const label type
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) << endl;
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;
}
inline void Foam::conformalVoronoiMesh::insertPointPair
(
const scalar ppDist,
const Foam::point& surfPt,
const vector& n
)
{
Pout<< "insertPointPair is depricated, "
<< " it does not check parallel insertion." << endl;
vector ppDistn = ppDist*n;
label master = insertPoint
(
surfPt - ppDistn,
number_of_vertices() + 1
);
insertPoint(surfPt + ppDistn, master);
return pointInserted;
}
@ -314,30 +329,62 @@ inline void Foam::conformalVoronoiMesh::createPointPair
const scalar ppDist,
const Foam::point& surfPt,
const vector& n,
DynamicList<Foam::point>& pts,
DynamicList<label>& indices,
DynamicList<label>& types
DynamicList<Vb>& pts
)
{
vector ppDistn = ppDist*n;
// Result when the points are eventually inserted.
// Add number_of_vertices() at insertion of first vertex to all numbers:
// pt index type
// surfPt - ppDistn 0 1
// surfPt + ppDistn 1 0
pts.append
(
Vb(surfPt - ppDistn, Vb::vtInternalSurface)
);
// Master, index = number_of_vertices(), type = number_of_vertices() + 1
pts.append(surfPt - ppDistn);
indices.append(0);
types.append(1);
pts.append
(
Vb(surfPt + ppDistn, Vb::vtExternalSurface)
);
}
// Slave, index = number_of_vertices()(new) + 1, type = index of master.
// This will be inserted after the master, so number_of_vertices() will
// have increased
pts.append(surfPt + ppDistn);
indices.append(0);
types.append(-1);
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, Vb::vtInternalSurface)
);
pts.append
(
Vb(surfPt + ppDistn, Vb::vtInternalSurface)
);
}
@ -350,13 +397,30 @@ inline bool Foam::conformalVoronoiMesh::isBoundaryDualFace
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()
|| vB->internalOrBoundaryPoint()
(vA->internalOrBoundaryPoint() && !vA->referred())
|| (vB->internalOrBoundaryPoint() && !vB->referred())
)
&& (
!vA->internalOrBoundaryPoint()
@ -458,59 +522,36 @@ inline bool Foam::conformalVoronoiMesh::isParallelDualEdge
}
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 * * * * * * * * * * * * * //
#ifdef CGAL_INEXACT
inline Foam::conformalVoronoiMesh::pointFromPoint
Foam::conformalVoronoiMesh::topoint
(
const Point& P
) const
{
return reinterpret_cast<pointFromPoint>(P);
}
inline Foam::conformalVoronoiMesh::PointFrompoint
Foam::conformalVoronoiMesh::toPoint
(
const Foam::point& p
) const
{
return reinterpret_cast<PointFrompoint>(p);
}
#else
inline Foam::conformalVoronoiMesh::pointFromPoint
Foam::conformalVoronoiMesh::topoint
(
const Point& P
) const
{
return Foam::point
(
CGAL::to_double(P.x()),
CGAL::to_double(P.y()),
CGAL::to_double(P.z())
);
}
inline Foam::conformalVoronoiMesh::PointFrompoint
Foam::conformalVoronoiMesh::toPoint
(
const Foam::point& p
) const
{
return Point(p.x(), p.y(), p.z());
}
#endif
inline Foam::conformalVoronoiMesh::CGALVector
Foam::conformalVoronoiMesh::toCGALVector(const Foam::vector& v) const
{
@ -562,10 +603,10 @@ Foam::conformalVoronoiMesh::decomposition() const
}
inline const Foam::cellSizeControlSurfaces&
Foam::conformalVoronoiMesh::cellSizeControl() const
inline const Foam::cellShapeControl&
Foam::conformalVoronoiMesh::cellShapeControls() const
{
return cellSizeControl_;
return cellShapeControl_;
}

View File

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
\*---------------------------------------------------------------------------*/
#include "indexedCell.H"
@ -41,8 +36,47 @@ Foam::Ostream& Foam::operator<<
{
const CGAL::indexedCell<Gt, Cb>& iv = p.t_;
os << "Cell : index:" << iv.index_ << " filterCount:" << iv.filterCount_
<< nl;
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();

View File

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
Class
indexedCell
@ -52,6 +47,8 @@ SourceFiles
#include "InfoProxy.H"
#include "tetCell.H"
#include "typeInfo.H"
#include "vectorTools.H"
#include "indexedCellEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -85,6 +82,7 @@ template
>
class indexedCell
:
public Foam::indexedCellEnum,
public Cb
{
// Private data
@ -98,6 +96,7 @@ class indexedCell
// 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
@ -105,14 +104,17 @@ class indexedCell
int filterCount_;
// Private member functions
//- Same as globallyOrderedCellVertices but without sorting
Foam::tetCell unsortedVertexGlobalIndices
(
const Foam::globalIndex& globalDelaunayVertexIndices
) const;
public:
enum cellTypes
{
ctFar = INT_MIN
};
typedef typename Cb::Vertex_handle Vertex_handle;
typedef typename Cb::Cell_handle Cell_handle;
@ -155,9 +157,13 @@ public:
inline int cellIndex() const;
#ifdef CGAL_INEXACT
inline const Foam::point& dual();
#else
inline const Foam::point dual();
#endif
inline bool farCell() const;
inline bool unassigned() const;
inline int& filterCount();
@ -169,6 +175,12 @@ public:
//- 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;
//- Does the Dual vertex form part of a processor patch
@ -186,6 +198,13 @@ public:
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;
@ -198,8 +217,13 @@ public:
// 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;
inline bool nearProcBoundary() const;
inline bool potentialCoplanarCell() const;
// Info

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::cvMeshChecks::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::cvMeshChecks::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::cvMeshChecks::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 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 cvMeshChecks
{
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 cvMeshChecks
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // 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 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 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

@ -21,20 +21,41 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
\*---------------------------------------------------------------------------*/
//#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_(ctFar),
index_(ctUnassigned),
filterCount_(0)
{}
@ -46,7 +67,7 @@ CGAL::indexedCell<Gt, Cb>::indexedCell
)
:
Cb(v0, v1, v2, v3),
index_(ctFar),
index_(ctUnassigned),
filterCount_(0)
{}
@ -65,7 +86,7 @@ CGAL::indexedCell<Gt, Cb>::indexedCell
)
:
Cb(v0, v1, v2, v3, n0, n1, n2, n3),
index_(ctFar),
index_(ctUnassigned),
filterCount_(0)
{}
@ -86,28 +107,37 @@ int CGAL::indexedCell<Gt, Cb>::cellIndex() const
}
#ifdef CGAL_INEXACT
template<class Gt, class Cb>
const Foam::point& CGAL::indexedCell<Gt, Cb>::dual()
{
#ifdef CGAL_INEXACT
// if (Foam::cvMeshChecks::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
return Foam::point
(
CGAL::to_double(P.x()),
CGAL::to_double(P.y()),
CGAL::to_double(P.z())
);
#endif
}
#endif
template<class Gt, class Cb>
inline bool CGAL::indexedCell<Gt, Cb>::farCell() const
inline bool CGAL::indexedCell<Gt, Cb>::unassigned() const
{
return index_ == ctFar;
return index_ == ctUnassigned;
}
@ -160,6 +190,32 @@ inline bool CGAL::indexedCell<Gt, Cb>::hasFarPoint() const
}
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
{
@ -177,11 +233,22 @@ 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()
)
);
}
@ -247,33 +314,8 @@ inline Foam::tetCell CGAL::indexedCell<Gt, Cb>::vertexGlobalIndices
) const
{
// tetVertexGlobalIndices
Foam::tetCell tVGI;
for (int i = 0; i < 4; i++)
{
Vertex_handle v = this->vertex(i);
// Finding the global index of each Delaunay vertex
if (v->referred())
{
// Referred vertices may have negative indices
tVGI[i] = globalDelaunayVertexIndices.toGlobal
(
v->procIndex(),
Foam::mag(v->index())
);
}
else
{
tVGI[i] = globalDelaunayVertexIndices.toGlobal
(
Foam::Pstream::myProcNo(),
v->index()
);
}
}
Foam::tetCell tVGI
= unsortedVertexGlobalIndices(globalDelaunayVertexIndices);
// bubble sort
for (int i = 0; i < tVGI.size(); i++)
@ -291,6 +333,41 @@ inline Foam::tetCell CGAL::indexedCell<Gt, Cb>::vertexGlobalIndices
}
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
{
@ -309,10 +386,14 @@ inline bool CGAL::indexedCell<Gt, Cb>::anyInternalOrBoundaryDualVertex() const
{
return
(
this->vertex(0)->anyInternalOrBoundaryPoint()
|| this->vertex(1)->anyInternalOrBoundaryPoint()
|| this->vertex(2)->anyInternalOrBoundaryPoint()
|| this->vertex(3)->anyInternalOrBoundaryPoint()
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()
);
}
@ -323,21 +404,34 @@ inline bool CGAL::indexedCell<Gt, Cb>::boundaryDualVertex() const
return
(
(
this->vertex(0)->internalOrBoundaryPoint()
|| this->vertex(1)->internalOrBoundaryPoint()
|| this->vertex(2)->internalOrBoundaryPoint()
|| this->vertex(3)->internalOrBoundaryPoint()
this->vertex(0)->internalBoundaryPoint()
|| this->vertex(1)->internalBoundaryPoint()
|| this->vertex(2)->internalBoundaryPoint()
|| this->vertex(3)->internalBoundaryPoint()
)
&& (
!this->vertex(0)->internalOrBoundaryPoint()
|| !this->vertex(1)->internalOrBoundaryPoint()
|| !this->vertex(2)->internalOrBoundaryPoint()
|| !this->vertex(3)->internalOrBoundaryPoint()
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>::nearProcBoundary() const
{
@ -351,4 +445,94 @@ inline bool CGAL::indexedCell<Gt, Cb>::nearProcBoundary() const
}
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;
}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //

View File

@ -1,115 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
\*---------------------------------------------------------------------------*/
#include "indexedVertex.H"
#include "point.H"
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
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_;
if (iv.type_ == CGAL::indexedVertex<Gt, Vb>::vtNearBoundary)
{
os << "internal near boundary point" << nl;
}
else if (iv.type_ == CGAL::indexedVertex<Gt, Vb>::vtInternal)
{
os << "internal point" << nl;
}
else if (iv.type_ == CGAL::indexedVertex<Gt, Vb>::vtFar)
{
os << "far point" << nl;
}
else if (iv.type_ > CGAL::indexedVertex<Gt, Vb>::vtFar && iv.type_ < 0)
{
if (iv.index_ >= 0)
{
os << "referred (master) point from processor " << iv.procIndex()
<< nl;
}
else
{
os << "referred (slave) point from processor " << iv.procIndex()
<< nl;
}
}
else if (iv.type_ >= 0)
{
if (iv.ppMaster())
{
os << "master of point pair. paired up with point " << iv.index_
<< nl;
}
else if (iv.ppSlave())
{
os << "slave of point pair. paired up with point " << iv.index_
<< nl;
}
else
{
FatalErrorIn
(
"operator<<"
"(Ostream&, const InfoProxy<CGAL::indexedVertex<Gt, Vb> >&)"
) << "unhandled type " << iv.type_ << " index " << iv.index_
<< abort(FatalError);
}
}
else
{
FatalErrorIn
(
"operator<<"
"(Ostream&, const InfoProxy<CGAL::indexedVertex<Gt, Vb> >&)"
) << "unhandled type " << iv.type_ << " index " << iv.index_
<< abort(FatalError);
}
const Foam::point pos
(
CGAL::to_double(iv.point().x()),
CGAL::to_double(iv.point().y()),
CGAL::to_double(iv.point().z())
);
os << " type:" << iv.type_ << " index:" << iv.index_
<< " at:" << pos << nl;
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,185 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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();
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();
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 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_
<< referred.c_str()
<< endl;
return os;
}
// ************************************************************************* //

View File

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
Class
indexedVertex
@ -43,9 +38,11 @@ SourceFiles
#define indexedVertex_H
#include <CGAL/Triangulation_3.h>
#include "CGALTriangulation3DKernel.H"
#include "tensor.H"
#include "InfoProxy.H"
#include "point.H"
#include "indexedVertexEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,13 +53,41 @@ 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
@ -75,23 +100,21 @@ namespace CGAL
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_;
//- type of pair-point :
// vtNearBoundary : internal near boundary point.
// vtInternal : internal point.
// vtFar : far-point.
// > vtFar, < 0 : referred point from processor -(type_ + 1)
// >= 0 : part of point-pair. Index of other point.
// Lowest numbered is inside one (master).
int type_;
//- Number of the processor that owns this vertex
int processor_;
//- Required alignment of the dual cell of this vertex
Foam::tensor alignment_;
@ -100,29 +123,15 @@ class indexedVertex
Foam::scalar targetCellSize_;
//- Specify whether the vertex is fixed or movable.
bool vertexFixed_;
bool nearProcBoundary_;
// bool vertexFixed_;
public:
enum vertexTypes
{
vtNearBoundary = INT_MIN,
vtInternal = INT_MIN + 1,
vtFar = INT_MIN + 2
};
enum vertexMotion
{
fixed = 0,
movable = 1
};
typedef typename Vb::Vertex_handle Vertex_handle;
typedef typename Vb::Cell_handle Cell_handle;
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
@ -131,14 +140,23 @@ public:
typedef indexedVertex<Gt,Vb2> Other;
};
// Constructors
inline indexedVertex();
inline indexedVertex(const Point& p);
inline indexedVertex(const Point& p, int index, int type);
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 Point& p, Cell_handle f);
@ -151,9 +169,9 @@ public:
inline int index() const;
inline int& type();
inline vertexType& type();
inline int type() const;
inline vertexType type() const;
inline Foam::tensor& alignment();
@ -171,26 +189,18 @@ public:
//- Is point internal, i.e. not on boundary
inline bool internalPoint() const;
//- Is point internal, i.e. not on boundary, external query.
inline static bool internalPoint(int type);
// is this a referred vertex
//- Is this a referred vertex
inline bool referred() const;
// is this a referred internal or boundary vertex
inline bool referredInternalOrBoundaryPoint() const;
// is this a referred external (pair slave) vertex
inline bool referredExternal() const;
// Is this a "real" point on this processor, i.e. is it internal or part
//- 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;
inline static int encodeProcIndex(int procI);
// For referred vertices, set the original processor index
inline int& procIndex();
//- Set the point to be internal
inline void setInternal();
@ -208,45 +218,61 @@ public:
inline void setNearProcBoundary();
//- Either master or slave of pointPair.
inline bool pairPoint() const;
//- Master of a pointPair is the lowest numbered one.
inline bool ppMaster() const;
//- Master of a pointPair is the lowest numbered one, external query.
inline static bool ppMaster(int index, int type);
//- Slave of a pointPair is the highest numbered one.
inline bool ppSlave() const;
inline bool boundaryPoint() const;
//- Either original internal point or master of pointPair.
inline bool internalOrBoundaryPoint() const;
//- Either original internal point or master of pointPair.
// External query.
inline static bool internalOrBoundaryPoint(int index, int type);
//- Is point near the boundary or part of the boundary definition
inline bool nearOrOnBoundary() const;
//- Either a real or referred internal or boundary point
inline bool anyInternalOrBoundaryPoint() const;
//- Part of a feature point
inline bool featurePoint() const;
//- Is the vertex fixed or movable
inline bool isVertexFixed() const;
//- Part of a feature edge
inline bool featureEdgePoint() const;
//- Fix the vertex so that it can't be moved
inline void setVertexFixed();
//- Part of a surface point pair
inline bool surfacePoint() const;
// inline void operator=(const Delaunay::Finite_vertices_iterator vit)
// {
// Vb::operator=indexedVertex(vit->point());
inline bool internalBoundaryPoint() const;
// this->index_ = vit->index();
inline bool externalBoundaryPoint() const;
// this->type_ = vit->type();
// }
// //- Is the vertex fixed or movable
// inline bool isVertexFixed() const;
//
// //- Fix the vertex so that it can't be moved
// inline void setVertexFixed();
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();
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()
);
}
inline bool operator!=(const indexedVertex& rhs) const
{
return !(*this == rhs);
}
// Info
@ -264,6 +290,17 @@ public:
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>&
);
};
@ -271,6 +308,37 @@ public:
} // 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"

View File

@ -0,0 +1,88 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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, 10>::names[] =
{
"Unassigned",
"Internal",
"InternalNearBoundary",
"InternalSurface",
"InternalFeatureEdge",
"InternalFeaturePoint",
"ExternalSurface",
"ExternalFeatureEdge",
"ExternalFeaturePoint",
"Far"
};
const Foam::NamedEnum<Foam::indexedVertexEnum::vertexType, 10>
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,95 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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
};
enum vertexMotion
{
fixed = 0,
movable = 1
};
static const Foam::NamedEnum<vertexType, 10> 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
// ************************************************************************* //

View File

@ -21,25 +21,21 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
\*---------------------------------------------------------------------------*/
#include "Pstream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Gt, class Vb>
inline CGAL::indexedVertex<Gt, Vb>::indexedVertex()
:
Vb(),
index_(vtInternal),
type_(vtInternal),
alignment_(),
targetCellSize_(0.0),
vertexFixed_(false),
nearProcBoundary_(false)
type_(vtUnassigned),
index_(vtUnassigned),
processor_(Foam::Pstream::myProcNo()),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
@ -47,12 +43,43 @@ template<class Gt, class Vb>
inline CGAL::indexedVertex<Gt, Vb>::indexedVertex(const Point& p)
:
Vb(p),
index_(vtInternal),
type_(vtInternal),
alignment_(),
targetCellSize_(0.0),
vertexFixed_(false),
nearProcBoundary_(false)
type_(vtUnassigned),
index_(vtUnassigned),
processor_(Foam::Pstream::myProcNo()),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
template<class Gt, class Vb>
inline CGAL::indexedVertex<Gt, Vb>::indexedVertex
(
const Point& p,
vertexType type
)
:
Vb(p),
type_(type),
index_(-1),
processor_(Foam::Pstream::myProcNo()),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
template<class Gt, class Vb>
inline CGAL::indexedVertex<Gt, Vb>::indexedVertex
(
const Foam::point& p,
vertexType type
)
:
Vb(Point(p.x(), p.y(), p.z())),
type_(type),
index_(-1),
processor_(Foam::Pstream::myProcNo()),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
@ -61,16 +88,16 @@ inline CGAL::indexedVertex<Gt, Vb>::indexedVertex
(
const Point& p,
int index,
int type
vertexType type,
int processor
)
:
Vb(p),
index_(index),
type_(type),
alignment_(),
targetCellSize_(0.0),
vertexFixed_(false),
nearProcBoundary_(false)
index_(index),
processor_(processor),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
@ -78,12 +105,11 @@ template<class Gt, class Vb>
inline CGAL::indexedVertex<Gt, Vb>::indexedVertex(const Point& p, Cell_handle f)
:
Vb(f, p),
index_(vtInternal),
type_(vtInternal),
alignment_(),
targetCellSize_(0.0),
vertexFixed_(false),
nearProcBoundary_(false)
type_(vtUnassigned),
index_(vtUnassigned),
processor_(Foam::Pstream::myProcNo()),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
@ -91,12 +117,11 @@ template<class Gt, class Vb>
inline CGAL::indexedVertex<Gt, Vb>::indexedVertex(Cell_handle f)
:
Vb(f),
index_(vtInternal),
type_(vtInternal),
alignment_(),
targetCellSize_(0.0),
vertexFixed_(false),
nearProcBoundary_(false)
type_(vtUnassigned),
index_(vtUnassigned),
processor_(Foam::Pstream::myProcNo()),
alignment_(Foam::tensor::zero),
targetCellSize_(0.0)
{}
@ -117,14 +142,16 @@ inline int CGAL::indexedVertex<Gt, Vb>::index() const
template<class Gt, class Vb>
inline int& CGAL::indexedVertex<Gt, Vb>::type()
inline typename CGAL::indexedVertex<Gt, Vb>::vertexType&
CGAL::indexedVertex<Gt, Vb>::type()
{
return type_;
}
template<class Gt, class Vb>
inline int CGAL::indexedVertex<Gt, Vb>::type() const
inline typename CGAL::indexedVertex<Gt, Vb>::vertexType
CGAL::indexedVertex<Gt, Vb>::type() const
{
return type_;
}
@ -161,7 +188,7 @@ inline Foam::scalar CGAL::indexedVertex<Gt, Vb>::targetCellSize() const
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::uninitialised() const
{
return type_ == vtInternal && index_ == vtInternal;
return type_ == vtUnassigned;
}
@ -175,63 +202,41 @@ inline bool CGAL::indexedVertex<Gt, Vb>::farPoint() const
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::internalPoint() const
{
return internalPoint(type_);
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::internalPoint(int type)
{
return type <= vtInternal;
return type_ == vtInternal || type_ == vtInternalNearBoundary;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::referred() const
{
return (type_ < 0 && type_ > vtFar);
}
// Can't be zero as the first few points are far points which won't be
// referred
//return index_ < 0;
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::referredInternalOrBoundaryPoint() const
{
return referred() && index_ >= 0;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::referredExternal() const
{
return referred() && index_ < 0;
// processor_ will be take the value of the processor that this vertex is
// from, so it cannot be on this processor.
return processor_ != Foam::Pstream::myProcNo();
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::real() const
{
return internalPoint() || pairPoint();
return (internalPoint() || boundaryPoint()) && !referred();
}
template<class Gt, class Vb>
inline int CGAL::indexedVertex<Gt, Vb>::procIndex() const
{
if (referred())
{
return -(type_ + 1);
}
else
{
return -1;
}
return processor_;
}
template<class Gt, class Vb>
inline int CGAL::indexedVertex<Gt, Vb>::encodeProcIndex(int procI)
inline int& CGAL::indexedVertex<Gt, Vb>::procIndex()
{
return -(procI + 1);
return processor_;
}
@ -245,115 +250,85 @@ inline void CGAL::indexedVertex<Gt, Vb>::setInternal()
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::nearBoundary() const
{
return type_ == vtNearBoundary;
return type_ == vtInternalNearBoundary;
}
template<class Gt, class Vb>
inline void CGAL::indexedVertex<Gt, Vb>::setNearBoundary()
{
type_ = vtNearBoundary;
type_ = vtInternalNearBoundary;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::nearProcBoundary() const
inline bool CGAL::indexedVertex<Gt, Vb>::boundaryPoint() const
{
return nearProcBoundary_;
}
template<class Gt, class Vb>
inline void CGAL::indexedVertex<Gt, Vb>::setNearProcBoundary()
{
nearProcBoundary_ = true;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::pairPoint() const
{
return type_ >= 0;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::ppMaster() const
{
return ppMaster(index_, type_);
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::ppMaster(int index, int type)
{
if (index >= 0 && type > index)
{
return true;
}
return false;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::ppSlave() const
{
if (type_ >= 0 && type_ < index_)
{
return true;
}
else
{
return false;
}
return type_ >= vtInternalSurface && !farPoint();
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::internalOrBoundaryPoint() const
{
return internalOrBoundaryPoint(index_, type_);
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::internalOrBoundaryPoint
(
int index,
int type
)
{
return internalPoint(type) || ppMaster(index, type);
return internalPoint() || internalBoundaryPoint();
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::nearOrOnBoundary() const
{
return pairPoint() || nearBoundary();
return boundaryPoint() || nearBoundary();
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::anyInternalOrBoundaryPoint() const
inline bool CGAL::indexedVertex<Gt, Vb>::internalBoundaryPoint() const
{
return internalOrBoundaryPoint() || referredInternalOrBoundaryPoint();
return type_ >= vtInternalSurface && type_ <= vtInternalFeaturePoint;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::isVertexFixed() const
inline bool CGAL::indexedVertex<Gt, Vb>::externalBoundaryPoint() const
{
return vertexFixed_;
return type_ >= vtExternalSurface && type_ <= vtExternalFeaturePoint;
}
template<class Gt, class Vb>
inline void CGAL::indexedVertex<Gt, Vb>::setVertexFixed()
inline bool CGAL::indexedVertex<Gt, Vb>::featurePoint() const
{
vertexFixed_ = true;
return type_ == vtInternalFeaturePoint || type_ == vtExternalFeaturePoint;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::featureEdgePoint() const
{
return type_ == vtInternalFeatureEdge || type_ == vtExternalFeatureEdge;
}
template<class Gt, class Vb>
inline bool CGAL::indexedVertex<Gt, Vb>::surfacePoint() const
{
return type_ == vtInternalSurface || type_ == vtExternalSurface;
}
//template<class Gt, class Vb>
//inline bool CGAL::indexedVertex<Gt, Vb>::isVertexFixed() const
//{
// return vertexFixed_;
//}
//
//
//template<class Gt, class Vb>
//inline void CGAL::indexedVertex<Gt, Vb>::setVertexFixed()
//{
// vertexFixed_ = true;
//}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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
pointConversion
Description
Conversion functions between point (FOAM::) and Point (CGAL)
\*---------------------------------------------------------------------------*/
#ifndef pointConversion_H
#define pointConversion_H
#include "point.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef CGAL_INEXACT
// Define Point to be contiguous for inexact (double storage) kernel
typedef const Foam::point& pointFromPoint;
typedef const CGAL::Triangulation_vertex_base_3<K>::Point& PointFrompoint;
#else
typedef Foam::point pointFromPoint;
typedef CGAL::Triangulation_vertex_base_3<K>::Point PointFrompoint;
#endif
namespace Foam
{
#ifdef CGAL_INEXACT
template<typename Point>
inline pointFromPoint topoint(const Point& P)
{
return reinterpret_cast<pointFromPoint>(P);
}
template<typename Point>
inline PointFrompoint toPoint(const Foam::point& p)
{
return reinterpret_cast<PointFrompoint>(p);
}
#else
template<typename Point>
inline pointFromPoint topoint(const Point& P)
{
return Foam::point
(
CGAL::to_double(P.x()),
CGAL::to_double(P.y()),
CGAL::to_double(P.z())
);
}
template<typename Point>
inline Point toPoint(const Foam::point& p)
{
return Point(p.x(), p.y(), p.z());
}
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
Class
pointFeatureEdgesTypes
@ -48,28 +43,39 @@ namespace Foam
\*---------------------------------------------------------------------------*/
//- Hold the types of feature edges attached to the point.
struct pointFeatureEdgesTypes
class pointFeatureEdgesTypes
:
public HashTable<label, extendedFeatureEdgeMesh::edgeStatus>
{
label ptI;
label nExternal, nInternal;
label nFlat, nOpen, nMultiple, nNonFeature;
label pointLabel_;
public:
pointFeatureEdgesTypes(const label pointLabel)
{
ptI = pointLabel;
nExternal = nInternal = 0;
nFlat = nOpen = nMultiple = nNonFeature = 0;
}
:
HashTable<label, extendedFeatureEdgeMesh::edgeStatus>(),
pointLabel_(pointLabel)
{}
friend Ostream& operator<<(Ostream& os, const pointFeatureEdgesTypes& p)
{
os << "E " << "I " << "F " << "O " << "M " << "N "
<< "Pt" << nl
<< p.nExternal << " " << p.nInternal << " "
<< p.nFlat << " " << p.nOpen << " "
<< p.nMultiple << " " << p.nNonFeature << " "
<< p.ptI
os << "Point = " << p.pointLabel_ << endl;
for
(
HashTable<label, extendedFeatureEdgeMesh::edgeStatus>
::const_iterator iter = p.cbegin();
iter != p.cend();
++iter
)
{
os << " "
<< extendedFeatureEdgeMesh::edgeStatusNames_[iter.key()]
<< " = "
<< iter()
<< endl;
}
return os;
}

View File

@ -117,7 +117,6 @@ Foam::conformationSurfaces::conformationSurfaces
}
}
word featureMethod = surfaceSubDict.lookup("featureMethod");
if (featureMethod == "extendedFeatureEdgeMesh")
@ -230,7 +229,12 @@ Foam::conformationSurfaces::conformationSurfaces
// Extend the global bounds to stop the bound box sitting on the surfaces
// to be conformed to
globalBounds_ = globalBounds_.extend(rndGen_, 1e-4);
//globalBounds_ = globalBounds_.extend(rndGen_, 1e-4);
vector newSpan = 1e-4*globalBounds_.span();
globalBounds_.min() -= newSpan;
globalBounds_.max() += newSpan;
// Look at all surfaces at determine whether the locationInMesh point is
// inside or outside each, to establish a signature for the domain to be

View File

@ -45,9 +45,6 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
class conformalVoronoiMesh;
/*---------------------------------------------------------------------------*\
Class conformationSurfaces Declaration
\*---------------------------------------------------------------------------*/

View File

@ -84,126 +84,42 @@ Foam::cvControls::cvControls
// Controls for coarse surface conformation
const dictionary& coarseDict
const dictionary& conformationControlsDict
(
surfDict.subDict("coarseConformationControls")
);
const dictionary& coarseInitialDict
(
coarseDict.subDict("initial")
);
const dictionary& coarseIterationDict
(
coarseDict.subDict("iteration")
surfDict.subDict("conformationControls")
);
surfacePtExclusionDistanceCoeff_ = readScalar
(
coarseInitialDict.lookup("surfacePtExclusionDistanceCoeff")
conformationControlsDict.lookup("surfacePtExclusionDistanceCoeff")
);
edgeSearchDistCoeffSqr_coarse_initial_ = sqr
edgeSearchDistCoeffSqr_ = sqr
(
readScalar
(
coarseInitialDict.lookup("edgeSearchDistCoeff")
conformationControlsDict.lookup("edgeSearchDistCoeff")
)
);
edgeSearchDistCoeffSqr_coarse_iteration_ = sqr
surfacePtReplaceDistCoeffSqr_ = sqr
(
readScalar
(
coarseIterationDict.lookup("edgeSearchDistCoeff")
conformationControlsDict.lookup("surfacePtReplaceDistCoeff")
)
);
surfacePtReplaceDistCoeffSqr_coarse_initial_ = sqr
maxConformationIterations_ = readLabel
(
readScalar
(
coarseInitialDict.lookup("surfacePtReplaceDistCoeff")
)
conformationControlsDict.lookup("maxIterations")
);
surfacePtReplaceDistCoeffSqr_coarse_iteration_ = sqr
iterationToInitialHitRatioLimit_ = readScalar
(
readScalar
(
coarseIterationDict.lookup("surfacePtReplaceDistCoeff")
)
conformationControlsDict.lookup("iterationToInitialHitRatioLimit")
);
maxConformationIterations_coarse_ = readLabel
(
coarseDict.lookup("maxIterations")
);
iterationToInitialHitRatioLimit_coarse_ = readScalar
(
coarseDict.lookup("iterationToInitialHitRatioLimit")
);
// Controls for fine surface conformation
const dictionary& fineDict
(
surfDict.subDict("fineConformationControls")
);
const dictionary& fineInitialDict
(
fineDict.subDict("initial")
);
const dictionary& fineIterationDict
(
fineDict.subDict("iteration")
);
edgeSearchDistCoeffSqr_fine_initial_ = sqr
(
readScalar
(
fineInitialDict.lookup("edgeSearchDistCoeff")
)
);
edgeSearchDistCoeffSqr_fine_iteration_ = sqr
(
readScalar
(
fineIterationDict.lookup("edgeSearchDistCoeff")
)
);
surfacePtReplaceDistCoeffSqr_fine_initial_ = sqr
(
readScalar
(
fineInitialDict.lookup("surfacePtReplaceDistCoeff")
)
);
surfacePtReplaceDistCoeffSqr_fine_iteration_ = sqr
(
readScalar
(
fineIterationDict.lookup("surfacePtReplaceDistCoeff")
)
);
maxConformationIterations_fine_ = readLabel
(
fineDict.lookup("maxIterations")
);
iterationToInitialHitRatioLimit_fine_ = readScalar
(
fineDict.lookup("iterationToInitialHitRatioLimit")
);
// Motion control controls
@ -279,248 +195,22 @@ Foam::cvControls::cvControls
const dictionary& filteringDict(cvMeshDict_.subDict("polyMeshFiltering"));
filterEdges_ = Switch
(
filteringDict.lookupOrDefault<Switch>("filterEdges", true)
);
filterFaces_ = Switch
(
filteringDict.lookupOrDefault<Switch>("filterFaces", false)
);
if (filterFaces_)
{
filterEdges_ = Switch::ON;
}
writeTetDualMesh_ = Switch(filteringDict.lookup("writeTetDualMesh"));
filterSizeCoeff_ = readScalar
(
filteringDict.lookup("filterSizeCoeff")
);
mergeClosenessCoeff_ = readScalar
(
filteringDict.lookup("mergeClosenessCoeff")
);
edgeMergeAngle_ = readScalar
(
filteringDict.lookup("edgeMergeAngle")
);
continueFilteringOnBadInitialPolyMesh_ = Switch
(
filteringDict.lookupOrDefault<Switch>
(
"continueFilteringOnBadInitialPolyMesh",
false
)
);
filterErrorReductionCoeff_ = readScalar
(
filteringDict.lookup("filterErrorReductionCoeff")
);
filterCountSkipThreshold_ = readLabel
(
filteringDict.lookup("filterCountSkipThreshold")
);
maxCollapseIterations_ = readLabel
(
filteringDict.lookup("maxCollapseIterations")
);
maxConsecutiveEqualFaceSets_ = readLabel
(
filteringDict.lookup("maxConsecutiveEqualFaceSets")
);
surfaceStepFaceAngle_ = readScalar
(
filteringDict.lookup("surfaceStepFaceAngle")
);
edgeCollapseGuardFraction_ = readScalar
(
filteringDict.lookup("edgeCollapseGuardFraction")
);
maxCollapseFaceToPointSideLengthCoeff_ = readScalar
(
filteringDict.lookup("maxCollapseFaceToPointSideLengthCoeff")
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::cvControls::edgeSearchDistCoeffSqrInitial
(
int reconfMode
) const
{
if (reconfMode == conformalVoronoiMesh::rmCoarse)
{
return edgeSearchDistCoeffSqr_coarse_initial_;
}
else if (reconfMode == conformalVoronoiMesh::rmFine)
{
return edgeSearchDistCoeffSqr_fine_initial_;
}
else
{
FatalErrorIn
(
"Foam::cvControls::edgeSearchDistCoeffSqrInitial"
"("
"int reconfMode"
") const"
) << "Unknown reconformationMode " << reconfMode
<< exit(FatalError);
}
return 0;
}
Foam::scalar Foam::cvControls::edgeSearchDistCoeffSqrIteration
(
int reconfMode
) const
{
if (reconfMode == conformalVoronoiMesh::rmCoarse)
{
return edgeSearchDistCoeffSqr_coarse_iteration_;
}
else if (reconfMode == conformalVoronoiMesh::rmFine)
{
return edgeSearchDistCoeffSqr_fine_iteration_;
}
else
{
FatalErrorIn
(
"Foam::cvControls::edgeSearchDistCoeffSqrIteration"
"("
"int reconfMode"
") const"
) << "Unknown reconformationMode " << reconfMode
<< exit(FatalError);
}
return 0;
}
Foam::scalar Foam::cvControls::surfacePtReplaceDistCoeffSqrInitial
(
int reconfMode
) const
{
if (reconfMode == conformalVoronoiMesh::rmCoarse)
{
return surfacePtReplaceDistCoeffSqr_coarse_initial_;
}
else if (reconfMode == conformalVoronoiMesh::rmFine)
{
return surfacePtReplaceDistCoeffSqr_fine_initial_;
}
else
{
FatalErrorIn
(
"Foam::cvControls::surfacePtReplaceDistCoeffSqrInitial"
"("
"int reconfMode"
") const"
) << "Unknown reconformationMode " << reconfMode
<< exit(FatalError);
}
return 0;
}
Foam::scalar Foam::cvControls::surfacePtReplaceDistCoeffSqrIteration
(
int reconfMode
) const
{
if (reconfMode == conformalVoronoiMesh::rmCoarse)
{
return surfacePtReplaceDistCoeffSqr_coarse_iteration_;
}
else if (reconfMode == conformalVoronoiMesh::rmFine)
{
return surfacePtReplaceDistCoeffSqr_fine_iteration_;
}
else
{
FatalErrorIn
(
"Foam::cvControls::surfacePtReplaceDistCoeffSqrIteration"
"("
"int reconfMode"
") const"
) << "Unknown reconformationMode " << reconfMode
<< exit(FatalError);
}
return 0;
}
Foam::label Foam::cvControls::maxConformationIterations
(
int reconfMode
) const
{
if (reconfMode == conformalVoronoiMesh::rmCoarse)
{
return maxConformationIterations_coarse_;
}
else if (reconfMode == conformalVoronoiMesh::rmFine)
{
return maxConformationIterations_fine_;
}
else
{
FatalErrorIn
(
"Foam::cvControls::maxConformationIterations"
"("
"int reconfMode"
") const"
) << "Unknown reconformationMode " << reconfMode
<< exit(FatalError);
}
return 0;
}
Foam::scalar Foam::cvControls::iterationToInitialHitRatioLimit
(
int reconfMode
) const
{
if (reconfMode == conformalVoronoiMesh::rmCoarse)
{
return iterationToInitialHitRatioLimit_coarse_;
}
else if (reconfMode == conformalVoronoiMesh::rmFine)
{
return iterationToInitialHitRatioLimit_fine_;
}
else
{
FatalErrorIn
(
"Foam::cvControls::iterationToInitialHitRatioLimit"
"("
"int reconfMode"
") const"
) << "Unknown reconformationMode " << reconfMode
<< exit(FatalError);
}
return 0;
}

View File

@ -37,6 +37,7 @@ SourceFiles
#include "dictionary.H"
#include "Switch.H"
#include "vector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -106,74 +107,21 @@ class cvControls
//- Distance to search for feature edges near to
// surface protrusions - fraction of the local target
// cell size. Coarse conformation, initial protrusion
// tests.
scalar edgeSearchDistCoeffSqr_coarse_initial_;
//- Distance to search for feature edges near to
// surface protrusions - fraction of the local target
// cell size. Coarse conformation, iteration
// protrusion tests.
scalar edgeSearchDistCoeffSqr_coarse_iteration_;
// cell size.
scalar edgeSearchDistCoeffSqr_;
//- Proximity to a feature edge where a surface hit is
// not created, only the edge conformation is created
// - fraction of the local target cell size. Coarse
// conformation, initial protrusion tests.
scalar surfacePtReplaceDistCoeffSqr_coarse_initial_;
// - fraction of the local target cell size.
scalar surfacePtReplaceDistCoeffSqr_;
//- Proximity to a feature edge where a surface hit is
// not created, only the edge conformation is created
// - fraction of the local target cell size. Coarse
// conformation, iteration protrusion tests.
scalar surfacePtReplaceDistCoeffSqr_coarse_iteration_;
//- Maximum allowed number surface conformation iterations.
label maxConformationIterations_;
//- Maximum allowed number coarse surface conformation
// iterations.
label maxConformationIterations_coarse_;
//- Termination criterion for coarse surface
// conformation iterations. When the number of
// surface protrusions drops below this ratio of the
// initial number of protrusions.
scalar iterationToInitialHitRatioLimit_coarse_;
// Controls for fine surface conformation
//- Distance to search for feature edges near to
// surface protrusions - fraction of the local target
// cell size. Fine conformation, initial protrusion
// tests.
scalar edgeSearchDistCoeffSqr_fine_initial_;
//- Distance to search for feature edges near to
// surface protrusions - fraction of the local target
// cell size. Fine conformation, iteration protrusion
// tests.
scalar edgeSearchDistCoeffSqr_fine_iteration_;
//- Proximity to a feature edge where a surface hit is
// not created, only the edge conformation is created
// - fraction of the local target cell size. Fine
// conformation, initial protrusion tests.
scalar surfacePtReplaceDistCoeffSqr_fine_initial_;
//- Proximity to a feature edge where a surface hit is
// not created, only the edge conformation is created
// - fraction of the local target cell size. Fine
// conformation, iteration protrusion tests.
scalar surfacePtReplaceDistCoeffSqr_fine_iteration_;
//- Maximum allowed number fine surface conformation
// iterations.
label maxConformationIterations_fine_;
//- Termination criterion for fine surface conformation
// iterations. When the number of surface protrusions
// drops below this ratio of the initial number of
// protrusions.
scalar iterationToInitialHitRatioLimit_fine_;
//- Termination criterion for conformation iterations.
// When the number of surface protrusions drops below this
// ratio of the initial number of protrusions.
scalar iterationToInitialHitRatioLimit_;
// Motion control controls
@ -198,6 +146,7 @@ class cvControls
//- Now often to re-store the size and alignment data
label sizeAndAlignmentRebuildFrequency_;
// Point insertion criteria
//- Length between Delaunay vertices above which a new Dv should be
@ -223,67 +172,15 @@ class cvControls
// polyMesh filtering controls
//- Activates the mesh edge filtering. On by default.
Switch filterEdges_;
//- Activates the mesh face filtering. Off by default.
Switch filterFaces_;
//- Write tet mesh at output time (it always writes the Voronoi)
Switch writeTetDualMesh_;
//- Upper limit on the size of faces to be filtered from,
// fraction of the local target cell size
scalar filterSizeCoeff_;
//- Upper limit on how close two dual vertices can be before
// being merged, fraction of the local target cell size
scalar mergeClosenessCoeff_;
//- If the angle between two dual edges that are connected by a single
// point is less than this angle, then the edges will be merged into a
// single edge.
scalar edgeMergeAngle_;
//- If the mesh quality criteria cannot be satisfied, continue
// with filtering anyway?
Switch continueFilteringOnBadInitialPolyMesh_;
//- When a face is "bad", what fraction should the filterSizeCoeff_ be
// reduced by. Recursive, so for a filterCount value of fC, the
// filterSizeCoeff is reduced by pow(filterErrorReductionCoeff_, fC)
scalar filterErrorReductionCoeff_;
//- Maximum number of filterCount applications before a face
// is not attempted to be filtered
label filterCountSkipThreshold_;
//- Maximum number of permissible iterations of the face collapse
// algorithm. The value to choose will be related the maximum number
// of points on a face that is to be collapsed and how many faces
// around it need to be collapsed.
label maxCollapseIterations_;
//- Maximum number of times an to allow an equal faceSet to be
// returned from the face quality assessment before stopping iterations
// to break an infinitie loop.
label maxConsecutiveEqualFaceSets_;
//- The maximum allowed angle between a boundary face normal and the
// local surface normal before face will be aggressively collapsed
scalar surfaceStepFaceAngle_;
//- Defining how close to the midpoint (M) of the projected
// vertices line a projected vertex (X) can be before making
// an edge collapse invalid
//
// X---X-g----------------M----X-----------g----X--X
//
// Only allow a collapse if all projected vertices are
// outwith edgeCollapseGuardFraction (g) of the distance form
// the face centre to the furthest vertex in the considered
// direction
scalar edgeCollapseGuardFraction_;
//- The maximum allowed length of the longest edge of a face
// to enable a face to be collapsed to a point, fraction of
// the local target cell size
scalar maxCollapseFaceToPointSideLengthCoeff_;
// Private Member Functions
@ -346,30 +243,17 @@ public:
//- Return the surfaceConformationRebuildFrequency
inline label surfaceConformationRebuildFrequency() const;
//- Return the edgeSearchDistCoeffSqr for initial
// conformation for the given reconformationMode.
scalar edgeSearchDistCoeffSqrInitial(int reconfMode) const;
//- Return the edgeSearchDistCoeffSqr for conformation.
scalar edgeSearchDistCoeffSqr() const;
//- Return the edgeSearchDistCoeffSqr for conformation
// iterations for the given reconformationMode.
scalar edgeSearchDistCoeffSqrIteration(int reconfMode) const;
//- Return the surfacePtReplaceDistCoeffSqr for conformation.
scalar surfacePtReplaceDistCoeffSqr() const;
//- Return the surfacePtReplaceDistCoeffSqr for initial
// conformation for the given reconformationMode.
scalar surfacePtReplaceDistCoeffSqrInitial(int reconfMode) const;
//- Return the maxConformationIterations
label maxConformationIterations() const;
//- Return the surfacePtReplaceDistCoeffSqr for
// conformation iterations for the given
// reconformationMode.
scalar surfacePtReplaceDistCoeffSqrIteration(int reconfMode) const;
//- Return the maxConformationIterations for the given
// reconformationMode.
label maxConformationIterations(int reconfMode) const;
//- Return the iterationToInitialHitRatioLimit for the
// given reconformationMode.
scalar iterationToInitialHitRatioLimit(int reconfMode) const;
//- Return the iterationToInitialHitRatioLimit
scalar iterationToInitialHitRatioLimit() const;
//- Return the objOutput Switch
inline Switch objOutput() const;
@ -389,6 +273,12 @@ public:
//- Return the sizeAndAlignmentRebuildFrequency
inline label sizeAndAlignmentRebuildFrequency() const;
//- Return the aspectRatio
inline scalar aspectRatio() const;
//- Return the aspectRatioDirection
inline const vector& aspectRatioDirection() const;
//- Return the insertionDistCoeff
inline scalar insertionDistCoeff() const;
@ -401,44 +291,14 @@ public:
//- Return removalDistCoeff
inline scalar removalDistCoeff() const;
//- Filter edges at output time
inline Switch filterEdges() const;
//- Filter faces at output time
inline Switch filterFaces() const;
//- Write tetMesh at output time
inline Switch writeTetDualMesh() const;
//- Return the filterSizeCoeff
inline scalar filterSizeCoeff() const;
//- Return the mergeClosenessCoeff
inline scalar mergeClosenessCoeff() const;
//- Return the edgeMergeAngle
inline scalar edgeMergeAngle() const;
//- Return the continueFilteringOnBadInitialPolyMesh Switch
inline Switch continueFilteringOnBadInitialPolyMesh() const;
//- Return the filterErrorReductionCoeff
inline scalar filterErrorReductionCoeff() const;
//- Return the maxCollapseIterations
inline label maxCollapseIterations() const;
//- Return the maxConsecutiveEqualFaceSets
inline label maxConsecutiveEqualFaceSets() const;
//- Return the filterCountSkipThreshold
inline label filterCountSkipThreshold() const;
//- Return the maxCollapseIterations
inline label minCollapseFaces() const;
//- Return the surfaceStepFaceAngle
inline scalar surfaceStepFaceAngle() const;
//- Return the edgeCollapseGuardFraction
inline scalar edgeCollapseGuardFraction() const;
//- Return the maxCollapseFaceToPointSideLengthCoeff
inline scalar maxCollapseFaceToPointSideLengthCoeff() const;
};

View File

@ -88,6 +88,30 @@ inline Foam::label Foam::cvControls::surfaceConformationRebuildFrequency() const
}
inline Foam::scalar Foam::cvControls::edgeSearchDistCoeffSqr() const
{
return edgeSearchDistCoeffSqr_;
}
inline Foam::scalar Foam::cvControls::surfacePtReplaceDistCoeffSqr() const
{
return surfacePtReplaceDistCoeffSqr_;
}
inline Foam::label Foam::cvControls::maxConformationIterations() const
{
return maxConformationIterations_;
}
inline Foam::scalar Foam::cvControls::iterationToInitialHitRatioLimit() const
{
return iterationToInitialHitRatioLimit_;
}
inline Foam::Switch Foam::cvControls::objOutput() const
{
return objOutput_;
@ -148,78 +172,20 @@ inline Foam::scalar Foam::cvControls::removalDistCoeff() const
}
inline Foam::Switch Foam::cvControls::filterEdges() const
{
return filterEdges_;
}
inline Foam::Switch Foam::cvControls::filterFaces() const
{
return filterFaces_;
}
inline Foam::Switch Foam::cvControls::writeTetDualMesh() const
{
return writeTetDualMesh_;
}
inline Foam::scalar Foam::cvControls::filterSizeCoeff() const
{
return filterSizeCoeff_;
}
inline Foam::scalar Foam::cvControls::mergeClosenessCoeff() const
{
return mergeClosenessCoeff_;
}
inline Foam::scalar Foam::cvControls::edgeMergeAngle() const
{
return edgeMergeAngle_;
}
inline Foam::Switch
Foam::cvControls::continueFilteringOnBadInitialPolyMesh() const
{
return continueFilteringOnBadInitialPolyMesh_;
}
inline Foam::scalar Foam::cvControls::filterErrorReductionCoeff() const
{
return filterErrorReductionCoeff_;
}
inline Foam::label Foam::cvControls::filterCountSkipThreshold() const
{
return filterCountSkipThreshold_;
}
inline Foam::label Foam::cvControls::maxCollapseIterations() const
{
return maxCollapseIterations_;
}
inline Foam::label Foam::cvControls::maxConsecutiveEqualFaceSets() const
{
return maxConsecutiveEqualFaceSets_;
}
inline Foam::scalar Foam::cvControls::surfaceStepFaceAngle() const
{
return surfaceStepFaceAngle_;
}
inline Foam::scalar Foam::cvControls::edgeCollapseGuardFraction() const
{
return edgeCollapseGuardFraction_;
}
inline Foam::scalar
Foam::cvControls::maxCollapseFaceToPointSideLengthCoeff() const
{
return maxCollapseFaceToPointSideLengthCoeff_;
}
// ************************************************************************* //

View File

@ -339,7 +339,7 @@ bool Foam::autoDensity::fillBox
pointField corners(bb.points());
scalarField cornerSizes = cvMesh_.cellSizeControl().cellSize(corners);
scalarField cornerSizes = cvMesh_.cellShapeControls().cellSize(corners);
Field<bool> insideCorners = combinedWellInside(corners, cornerSizes);
@ -448,7 +448,7 @@ bool Foam::autoDensity::fillBox
);
}
lineSizes = cvMesh_.cellSizeControl().cellSize(linePoints);
lineSizes = cvMesh_.cellShapeControls().cellSize(linePoints);
Field<bool> insideLines = combinedWellInside
(
@ -547,7 +547,7 @@ bool Foam::autoDensity::fillBox
// corner when only some these points are required.
shuffle(samplePoints);
scalarField sampleSizes = cvMesh_.cellSizeControl().cellSize
scalarField sampleSizes = cvMesh_.cellShapeControls().cellSize
(
samplePoints
);
@ -713,7 +713,7 @@ bool Foam::autoDensity::fillBox
point p = min + cmptMultiply(span, rnd.vector01());
scalar localSize = cvMesh_.cellSizeControl().cellSize(p);
scalar localSize = cvMesh_.cellShapeControls().cellSize(p);
bool insidePoint = false;

View File

@ -167,7 +167,7 @@ List<Vb::Point> bodyCentredCubic::initialPoints() const
minimumSurfaceDistanceCoeffSqr_
*sqr
(
cvMesh_.cellSizeControl().cellSize(points)
cvMesh_.cellShapeControls().cellSize(points)
)
);

View File

@ -228,7 +228,7 @@ List<Vb::Point> faceCentredCubic::initialPoints() const
minimumSurfaceDistanceCoeffSqr_
*sqr
(
cvMesh_.cellSizeControl().cellSize(points)
cvMesh_.cellShapeControls().cellSize(points)
)
);

View File

@ -132,7 +132,7 @@ List<Vb::Point> pointFile::initialPoints() const
minimumSurfaceDistanceCoeffSqr_
*sqr
(
cvMesh_.cellSizeControl().cellSize(points)
cvMesh_.cellShapeControls().cellSize(points)
)
);

View File

@ -144,7 +144,7 @@ List<Vb::Point> uniformGrid::initialPoints() const
minimumSurfaceDistanceCoeffSqr_
*sqr
(
cvMesh_.cellSizeControl().cellSize(points)
cvMesh_.cellShapeControls().cellSize(points)
)
);

View File

@ -21,11 +21,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
As a special exception, you have permission to link this program with the
CGAL library and distribute executables, as long as you follow the
requirements of the GNU GPL in regard to all of the software in the
executable aside from CGAL.
Application
cvMesh
@ -44,11 +39,6 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::addBoolOption
(
"noFilter",
"Do not filter the mesh"
);
Foam::argList::addBoolOption
(
"checkGeometry",
@ -60,11 +50,8 @@ int main(int argc, char *argv[])
runTime.functionObjects().off();
const bool noFilter = !args.optionFound("noFilter");
const bool checkGeometry = args.optionFound("checkGeometry");
Info<< "Mesh filtering is " << (noFilter ? "on" : "off") << endl;
IOdictionary cvMeshDict
(
IOobject
@ -112,15 +99,9 @@ int main(int argc, char *argv[])
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
<< endl;
}
mesh.writeMesh(runTime.constant(), noFilter);
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
Info<< nl << "End" << nl << endl;
return 0;

View File

@ -14,14 +14,14 @@ EXE_INC = \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I../vectorTools
EXE_LIBS = \
$(CGAL_LIBS) \
-lboost_thread \
-lmpfr \
-lgmp \
-lconformalVoronoiMesh \
-ldecompositionMethods /* -L$(FOAM_LIBBIN)/dummy -lscotchDecomp */ \
-ledgeMesh \

View File

@ -36,7 +36,7 @@ Description
#include "triSurface.H"
#include "searchableSurfaces.H"
#include "conformationSurfaces.H"
#include "cellSizeControlSurfaces.H"
#include "cellShapeControl.H"
#include "backgroundMeshDecomposition.H"
#include "cellShape.H"
#include "cellModeller.H"
@ -450,10 +450,15 @@ int main(int argc, char *argv[])
cvMeshDict.subDict("surfaceConformation")
);
cellSizeControlSurfaces cellSizeControl
autoPtr<cellShapeControl> cellShapeControls
(
cellShapeControl::New
(
runTime,
cvMeshDict.subDict("motionControl"),
allGeometry,
cvMeshDict.subDict("motionControl")
geometryToConformTo
)
);
@ -464,7 +469,7 @@ int main(int argc, char *argv[])
// Determine the number of cells in each direction.
const vector span = bb.span();
vector nScalarCells = span/cellSizeControl.defaultCellSize();
vector nScalarCells = span/cellShapeControls().defaultCellSize();
// Calculate initial cell size to be a little bit smaller than the
// defaultCellSize to avoid initial refinement triggering.
@ -580,7 +585,7 @@ int main(int argc, char *argv[])
20.0, //maxCellWeightCoeff
runTime,
geometryToConformTo,
cellSizeControl,
cellShapeControls(),
rndGen,
cvMeshDict
);

View File

@ -263,7 +263,7 @@ initialPoints
// It determines the cell size given a location. It then uses all
// the rules
// - defaultCellSize
// - cellSizeControlGeometry
// - cellShapeControl
// to determine target cell size. Rule with highest priority wins. If same
// priority smallest cell size wins.
motionControl
@ -271,10 +271,28 @@ motionControl
// Absolute cell size of back ground mesh. This is the maximum cell size.
defaultCellSize 0.00075;
// Assign a priority to all requests for cell sizes, the highest overrules.
defaultPriority 0;
//cellShapeControl constantControl;
//cellShapeControl fileControl;
cellShapeControl surfaceControl;
cellSizeControlGeometry
// Provide constant values for cell size and alignment
constantControlCoeffs
{
cellSize 0.00075;
cellAlignment (1 0 0 0 1 0 0 0 1);
}
// Read in the points of the background grid used for cell shape control
// from a file, with corresponding files for alignment and size
fileControlCoeffs
{
pointFile "";
sizesFile "";
alignmentsFile "";
}
// Calculate the sizes and alignments from surfaces
surfaceControlCoeffs
{
ref7_outside
{
@ -319,6 +337,16 @@ motionControl
}
}
// Provide an aspect ratio and the direction in which it acts on the mesh.
// Default is 1.0 if this section is not present in the dictionary
cellAspectRatioControl
{
// Aspect ratio.
aspectRatio 2.0;
// Direction of action of the aspect ratio
aspectRatioDirection (1 0 0);
}
// Underrelaxation for point motion. Simulated annealing: starts off at 1
// and lowers to 0 (at simulation endTime) to converge points.
// adaptiveLinear is preferred choice.
@ -396,6 +424,12 @@ motionControl
// Do not change. See cvControls.H
polyMeshFiltering
{
// Filter small edges
filterEdges on;
// Filter small and sliver faces
filterFaces off;
// Write the underlying Delaunay tet mesh at output time
writeTetDualMesh false; //true;

View File

@ -7,4 +7,5 @@ CGAL_INC = \
CGAL_LIBS = \
-L$(MPFR_ARCH_PATH)/lib \
-L$(GMP_ARCH_PATH)/lib \
-L$(BOOST_ARCH_PATH)/lib