mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' of ssh://dm/home/dm4/OpenFOAM/OpenFOAM-dev
This commit is contained in:
@ -526,7 +526,7 @@ $(Fields)/symmTensorField/symmTensorField.C
|
||||
$(Fields)/tensorField/tensorField.C
|
||||
$(Fields)/complexFields/complexFields.C
|
||||
|
||||
$(Fields)/labelField/labelIOField.
|
||||
$(Fields)/labelField/labelIOField.C
|
||||
$(Fields)/labelField/labelFieldIOField.C
|
||||
$(Fields)/scalarField/scalarIOField.C
|
||||
$(Fields)/scalarField/scalarFieldIOField.C
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -24,6 +24,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "SlicedGeometricField.H"
|
||||
#include "processorFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
@ -40,7 +41,8 @@ slicedBoundaryField
|
||||
(
|
||||
const Mesh& mesh,
|
||||
const Field<Type>& completeField,
|
||||
const bool preserveCouples
|
||||
const bool preserveCouples,
|
||||
const bool preserveProcessorOnly
|
||||
)
|
||||
{
|
||||
tmp<FieldField<PatchField, Type> > tbf
|
||||
@ -52,7 +54,15 @@ slicedBoundaryField
|
||||
|
||||
forAll(mesh.boundary(), patchi)
|
||||
{
|
||||
if (preserveCouples && mesh.boundary()[patchi].coupled())
|
||||
if
|
||||
(
|
||||
preserveCouples
|
||||
&& mesh.boundary()[patchi].coupled()
|
||||
&& (
|
||||
!preserveProcessorOnly
|
||||
|| isA<processorFvPatch>(mesh.boundary()[patchi])
|
||||
)
|
||||
)
|
||||
{
|
||||
// For coupled patched construct the correct patch field type
|
||||
bf.set
|
||||
@ -243,7 +253,8 @@ SlicedGeometricField
|
||||
const dimensionSet& ds,
|
||||
const Field<Type>& completeIField,
|
||||
const Field<Type>& completeBField,
|
||||
const bool preserveCouples
|
||||
const bool preserveCouples,
|
||||
const bool preserveProcessorOnly
|
||||
)
|
||||
:
|
||||
GeometricField<Type, PatchField, GeoMesh>
|
||||
@ -252,7 +263,13 @@ SlicedGeometricField
|
||||
mesh,
|
||||
ds,
|
||||
Field<Type>(),
|
||||
slicedBoundaryField(mesh, completeBField, preserveCouples)
|
||||
slicedBoundaryField
|
||||
(
|
||||
mesh,
|
||||
completeBField,
|
||||
preserveCouples,
|
||||
preserveProcessorOnly
|
||||
)
|
||||
)
|
||||
{
|
||||
// Set the internalField to the slice of the complete field
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -83,7 +83,8 @@ private:
|
||||
(
|
||||
const Mesh& mesh,
|
||||
const Field<Type>& completeField,
|
||||
const bool preserveCouples
|
||||
const bool preserveCouples,
|
||||
const bool preserveProcessorOnly = false
|
||||
);
|
||||
|
||||
//- Slice the given field and a create a PtrList of SlicedPatchField
|
||||
@ -133,7 +134,8 @@ public:
|
||||
const dimensionSet&,
|
||||
const Field<Type>& completeIField,
|
||||
const Field<Type>& completeBField,
|
||||
const bool preserveCouples=true
|
||||
const bool preserveCouples=true,
|
||||
const bool preserveProcessorOnly = false
|
||||
);
|
||||
|
||||
//- Construct from GeometricField. Reuses full internal and
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -303,14 +303,12 @@ void Foam::meshReader::createPolyBoundary()
|
||||
|
||||
Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
|
||||
|
||||
// Add missing faces to last patch ('Default_Empty' etc.)
|
||||
if (nMissingFaces > 0)
|
||||
{
|
||||
patchSizes_.last() = nMissingFaces;
|
||||
}
|
||||
else
|
||||
{
|
||||
patchStarts_.setSize(patchStarts_.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
// reset the size of the face list
|
||||
meshFaces_.setSize(nCreatedFaces);
|
||||
|
||||
@ -133,6 +133,8 @@ void fvMesh::makeC() const
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Construct as slices. Only preserve processor (not e.g. cyclic)
|
||||
|
||||
CPtr_ = new slicedVolVectorField
|
||||
(
|
||||
IOobject
|
||||
@ -148,33 +150,10 @@ void fvMesh::makeC() const
|
||||
*this,
|
||||
dimLength,
|
||||
cellCentres(),
|
||||
faceCentres()
|
||||
faceCentres(),
|
||||
true, //preserveCouples
|
||||
true //preserveProcOnly
|
||||
);
|
||||
|
||||
|
||||
// Need to correct for cyclics transformation since absolute quantity.
|
||||
// Ok on processor patches since hold opposite cell centre (no
|
||||
// transformation)
|
||||
slicedVolVectorField& C = *CPtr_;
|
||||
|
||||
forAll(C.boundaryField(), patchi)
|
||||
{
|
||||
if
|
||||
(
|
||||
isA<cyclicFvPatchVectorField>(C.boundaryField()[patchi])
|
||||
|| isA<cyclicAMIFvPatchVectorField>(C.boundaryField()[patchi])
|
||||
)
|
||||
{
|
||||
// Note: cyclic is not slice but proper field
|
||||
C.boundaryField()[patchi] == static_cast<const vectorField&>
|
||||
(
|
||||
static_cast<const List<vector>&>
|
||||
(
|
||||
boundary_[patchi].patchSlice(faceCentres())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/postProcessing/functionObjects/forces/lnInclude \
|
||||
|
||||
LIB_LIBS = \
|
||||
|
||||
@ -4,6 +4,7 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude
|
||||
|
||||
@ -167,7 +167,7 @@ class autoSnapDriver
|
||||
void correctAttraction
|
||||
(
|
||||
const DynamicList<point>& surfacePoints,
|
||||
const DynamicList<label>& surfaceCount,
|
||||
const DynamicList<label>& surfaceCounts,
|
||||
const point& edgePt,
|
||||
const vector& edgeNormal, // normalised normal
|
||||
const point& pt,
|
||||
@ -213,7 +213,7 @@ class autoSnapDriver
|
||||
|
||||
DynamicList<point>& surfacePoints,
|
||||
DynamicList<vector>& surfaceNormals,
|
||||
DynamicList<label>& surfaceCount
|
||||
DynamicList<label>& surfaceCounts
|
||||
) const;
|
||||
void binFeatureFaces
|
||||
(
|
||||
@ -224,13 +224,13 @@ class autoSnapDriver
|
||||
const scalarField& snapDist,
|
||||
const label pointI,
|
||||
|
||||
const List<List<point> >& pointFaceNormals,
|
||||
const List<List<point> >& pointFaceSurfNormals,
|
||||
const List<List<point> >& pointFaceDisp,
|
||||
const List<List<point> >& pointFaceCentres,
|
||||
|
||||
DynamicList<point>& surfacePoints,
|
||||
DynamicList<vector>& surfaceNormals,
|
||||
DynamicList<label>& surfaceCount
|
||||
DynamicList<label>& surfaceCounts
|
||||
) const;
|
||||
|
||||
|
||||
@ -259,7 +259,7 @@ class autoSnapDriver
|
||||
const indirectPrimitivePatch& pp,
|
||||
const scalarField& snapDist,
|
||||
|
||||
const List<List<point> >& pointFaceNormals,
|
||||
const List<List<point> >& pointFaceSurfNormals,
|
||||
const List<List<point> >& pointFaceDisp,
|
||||
const List<List<point> >& pointFaceCentres,
|
||||
const labelListList& pointFacePatchID,
|
||||
@ -277,7 +277,7 @@ class autoSnapDriver
|
||||
const indirectPrimitivePatch&,
|
||||
const scalarField&,
|
||||
|
||||
const List<List<point> >& pointFaceNormals,
|
||||
const List<List<point> >& pointFaceSurfNormals,
|
||||
const List<List<point> >& pointFaceDisp,
|
||||
const List<List<point> >& pointFaceCentres,
|
||||
const labelListList& pointFacePatchID,
|
||||
|
||||
@ -690,7 +690,7 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
|
||||
void Foam::autoSnapDriver::correctAttraction
|
||||
(
|
||||
const DynamicList<point>& surfacePoints,
|
||||
const DynamicList<label>& surfaceCount,
|
||||
const DynamicList<label>& surfaceCounts,
|
||||
const point& edgePt,
|
||||
const vector& edgeNormal, // normalised normal
|
||||
const point& pt,
|
||||
@ -702,7 +702,7 @@ void Foam::autoSnapDriver::correctAttraction
|
||||
scalar tang = ((pt-edgePt)&edgeNormal);
|
||||
|
||||
labelList order;
|
||||
Foam::sortedOrder(surfaceCount, order);
|
||||
Foam::sortedOrder(surfaceCounts, order);
|
||||
|
||||
if (order[0] < order[1])
|
||||
{
|
||||
@ -763,7 +763,7 @@ void Foam::autoSnapDriver::binFeatureFace
|
||||
|
||||
DynamicList<point>& surfacePoints,
|
||||
DynamicList<vector>& surfaceNormals,
|
||||
DynamicList<label>& surfaceCount
|
||||
DynamicList<label>& surfaceCounts
|
||||
) const
|
||||
{
|
||||
// What to do with very far attraction? For now just ignore the face
|
||||
@ -783,7 +783,7 @@ void Foam::autoSnapDriver::binFeatureFace
|
||||
)
|
||||
{
|
||||
same = true;
|
||||
surfaceCount[j]++;
|
||||
surfaceCounts[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -796,7 +796,7 @@ void Foam::autoSnapDriver::binFeatureFace
|
||||
{
|
||||
surfacePoints.append(pt);
|
||||
surfaceNormals.append(faceSurfaceNormal);
|
||||
surfaceCount.append(1);
|
||||
surfaceCounts.append(1);
|
||||
}
|
||||
else if (surfacePoints.size() == 2)
|
||||
{
|
||||
@ -810,7 +810,7 @@ void Foam::autoSnapDriver::binFeatureFace
|
||||
// Definitely makes a feature point
|
||||
surfacePoints.append(pt);
|
||||
surfaceNormals.append(faceSurfaceNormal);
|
||||
surfaceCount.append(1);
|
||||
surfaceCounts.append(1);
|
||||
}
|
||||
}
|
||||
else if (surfacePoints.size() == 3)
|
||||
@ -834,7 +834,7 @@ void Foam::autoSnapDriver::binFeatureFace
|
||||
// Different feature point
|
||||
surfacePoints.append(pt);
|
||||
surfaceNormals.append(faceSurfaceNormal);
|
||||
surfaceCount.append(1);
|
||||
surfaceCounts.append(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -860,15 +860,15 @@ void Foam::autoSnapDriver::binFeatureFaces
|
||||
|
||||
DynamicList<point>& surfacePoints,
|
||||
DynamicList<vector>& surfaceNormals,
|
||||
DynamicList<label>& surfaceCount
|
||||
DynamicList<label>& surfaceCounts
|
||||
) const
|
||||
{
|
||||
const List<point>& pfNormals = pointFaceSurfNormals[pointI];
|
||||
const List<point>& pfSurfNormals = pointFaceSurfNormals[pointI];
|
||||
const List<point>& pfDisp = pointFaceDisp[pointI];
|
||||
const List<point>& pfCentres = pointFaceCentres[pointI];
|
||||
|
||||
// Collect all different directions
|
||||
forAll(pfNormals, i)
|
||||
forAll(pfSurfNormals, i)
|
||||
{
|
||||
binFeatureFace
|
||||
(
|
||||
@ -879,12 +879,12 @@ void Foam::autoSnapDriver::binFeatureFaces
|
||||
snapDist[pointI],
|
||||
|
||||
pfCentres[i],
|
||||
pfNormals[i],
|
||||
pfSurfNormals[i],
|
||||
pfDisp[i],
|
||||
|
||||
surfacePoints,
|
||||
surfaceNormals,
|
||||
surfaceCount
|
||||
surfaceCounts
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -914,7 +914,7 @@ void Foam::autoSnapDriver::featureAttractionUsingReconstruction
|
||||
// Collect all different directions
|
||||
DynamicList<point> surfacePoints(4);
|
||||
DynamicList<vector> surfaceNormals(4);
|
||||
DynamicList<label> surfaceCount(4);
|
||||
DynamicList<label> surfaceCounts(4);
|
||||
|
||||
binFeatureFaces
|
||||
(
|
||||
@ -931,7 +931,7 @@ void Foam::autoSnapDriver::featureAttractionUsingReconstruction
|
||||
|
||||
surfacePoints,
|
||||
surfaceNormals,
|
||||
surfaceCount
|
||||
surfaceCounts
|
||||
);
|
||||
|
||||
const point& pt = pp.localPoints()[pointI];
|
||||
@ -966,11 +966,13 @@ void Foam::autoSnapDriver::featureAttractionUsingReconstruction
|
||||
vector d = r.refPoint()-pt;
|
||||
d -= (d&n)*n;
|
||||
|
||||
//- This does not help much but distorts a perfectly aligned mesh
|
||||
// so disabled for now.
|
||||
//// Correct for attraction to non-dominant face
|
||||
//correctAttraction
|
||||
//(
|
||||
// surfacePoints,
|
||||
// surfaceCount,
|
||||
// surfaceCounts,
|
||||
// r.refPoint(),
|
||||
// n, // normalised normal
|
||||
// pt,
|
||||
@ -1813,8 +1815,8 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
}
|
||||
|
||||
// Reverse: from pp point to nearest feature
|
||||
vectorField allPatchAttraction(pp.nPoints(), vector::zero);
|
||||
List<pointConstraint> allPatchConstraints(pp.nPoints());
|
||||
vectorField rawPatchAttraction(pp.nPoints(), vector::zero);
|
||||
List<pointConstraint> rawPatchConstraints(pp.nPoints());
|
||||
|
||||
determineFeatures
|
||||
(
|
||||
@ -1837,15 +1839,15 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
edgeAttractors,
|
||||
edgeConstraints,
|
||||
// pp point to nearest feature
|
||||
allPatchAttraction,
|
||||
allPatchConstraints
|
||||
rawPatchAttraction,
|
||||
rawPatchConstraints
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Baffle handling
|
||||
// ~~~~~~~~~~~~~~~
|
||||
// Override pointAttractor, edgeAttractor, allPatchAttration etc. to
|
||||
// Override pointAttractor, edgeAttractor, rawPatchAttration etc. to
|
||||
// implement 'baffle' handling.
|
||||
// Baffle: the mesh pp point originates from a loose standing
|
||||
// baffle.
|
||||
@ -1983,8 +1985,8 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
featI,
|
||||
edgeAttractors,
|
||||
edgeConstraints,
|
||||
allPatchAttraction,
|
||||
allPatchConstraints
|
||||
rawPatchAttraction,
|
||||
rawPatchConstraints
|
||||
);
|
||||
|
||||
if (!nearInfo.hit())
|
||||
@ -2033,8 +2035,8 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
vector::zero;
|
||||
|
||||
// Store for later use
|
||||
allPatchAttraction[pointI] = featPt-pt;
|
||||
allPatchConstraints[pointI] =
|
||||
rawPatchAttraction[pointI] = featPt-pt;
|
||||
rawPatchConstraints[pointI] =
|
||||
pointConstraints[featI][featPointI];
|
||||
|
||||
if (oldPointI != -1)
|
||||
@ -2053,8 +2055,8 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
edgeFeatI,
|
||||
edgeAttractors,
|
||||
edgeConstraints,
|
||||
allPatchAttraction,
|
||||
allPatchConstraints
|
||||
rawPatchAttraction,
|
||||
rawPatchConstraints
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2084,8 +2086,8 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
featI,
|
||||
edgeAttractors,
|
||||
edgeConstraints,
|
||||
allPatchAttraction,
|
||||
allPatchConstraints
|
||||
rawPatchAttraction,
|
||||
rawPatchConstraints
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2296,11 +2298,11 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
if
|
||||
(
|
||||
patchConstraints[pointI].first() <= 1
|
||||
&& allPatchConstraints[pointI].first() > 1
|
||||
&& rawPatchConstraints[pointI].first() > 1
|
||||
)
|
||||
{
|
||||
patchAttraction[pointI] = allPatchAttraction[pointI];
|
||||
patchConstraints[pointI] = allPatchConstraints[pointI];
|
||||
patchAttraction[pointI] = rawPatchAttraction[pointI];
|
||||
patchConstraints[pointI] = rawPatchConstraints[pointI];
|
||||
|
||||
if (multiPatchStr.valid())
|
||||
{
|
||||
@ -2434,7 +2436,7 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
// Snap edges to feature edges
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Walk existing edges and snap remaining ones (that are marked as
|
||||
// feature edges in allPatchConstraints)
|
||||
// feature edges in rawPatchConstraints)
|
||||
|
||||
stringFeatureEdges
|
||||
(
|
||||
@ -2444,8 +2446,8 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
|
||||
pp,
|
||||
snapDist,
|
||||
|
||||
allPatchAttraction,
|
||||
allPatchConstraints,
|
||||
rawPatchAttraction,
|
||||
rawPatchConstraints,
|
||||
|
||||
patchAttraction,
|
||||
patchConstraints
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-ltriSurface
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -27,12 +27,42 @@ License
|
||||
#include "searchableSurfacesQueries.H"
|
||||
#include "ListOps.H"
|
||||
#include "Time.H"
|
||||
//#include "vtkSetWriter.H"
|
||||
#include "DynamicField.H"
|
||||
//#include "OBJstream.H"
|
||||
#include "PatchTools.H"
|
||||
#include "triSurfaceMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(Foam::searchableSurfaces, 0);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
//- Is edge connected to triangle
|
||||
bool Foam::searchableSurfaces::connected
|
||||
(
|
||||
const triSurface& s,
|
||||
const label edgeI,
|
||||
const pointIndexHit& hit
|
||||
)
|
||||
{
|
||||
const triFace& localFace = s.localFaces()[hit.index()];
|
||||
const edge& e = s.edges()[edgeI];
|
||||
|
||||
forAll(localFace, i)
|
||||
{
|
||||
if (e.otherVertex(localFace[i]) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct with length.
|
||||
@ -378,6 +408,468 @@ Foam::pointIndexHit Foam::searchableSurfaces::facesIntersection
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::searchableSurfaces::checkClosed(const bool report) const
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
Info<< "Checking for closedness." << endl;
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
forAll(*this, surfI)
|
||||
{
|
||||
if (!operator[](surfI).hasVolumeType())
|
||||
{
|
||||
hasError = true;
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< " " << names()[surfI]
|
||||
<< " : not closed" << endl;
|
||||
}
|
||||
|
||||
if (isA<triSurface>(operator[](surfI)))
|
||||
{
|
||||
const triSurface& s = dynamic_cast<const triSurface&>
|
||||
(
|
||||
operator[](surfI)
|
||||
);
|
||||
const labelListList& edgeFaces = s.edgeFaces();
|
||||
|
||||
label nSingleEdges = 0;
|
||||
forAll(edgeFaces, edgeI)
|
||||
{
|
||||
if (edgeFaces[edgeI].size() == 1)
|
||||
{
|
||||
nSingleEdges++;
|
||||
}
|
||||
}
|
||||
|
||||
label nMultEdges = 0;
|
||||
forAll(edgeFaces, edgeI)
|
||||
{
|
||||
if (edgeFaces[edgeI].size() > 2)
|
||||
{
|
||||
nMultEdges++;
|
||||
}
|
||||
}
|
||||
|
||||
if (report && (nSingleEdges != 0 || nMultEdges != 0))
|
||||
{
|
||||
Info<< " connected to one face : "
|
||||
<< nSingleEdges << nl
|
||||
<< " connected to >2 faces : "
|
||||
<< nMultEdges << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
return returnReduce(hasError, orOp<bool>());
|
||||
}
|
||||
|
||||
|
||||
bool Foam::searchableSurfaces::checkNormalOrientation(const bool report) const
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
Info<< "Checking for normal orientation." << endl;
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
forAll(*this, surfI)
|
||||
{
|
||||
if (isA<triSurface>(operator[](surfI)))
|
||||
{
|
||||
const triSurface& s = dynamic_cast<const triSurface&>
|
||||
(
|
||||
operator[](surfI)
|
||||
);
|
||||
|
||||
labelHashSet borderEdge(s.size()/1000);
|
||||
PatchTools::checkOrientation(s, false, &borderEdge);
|
||||
// Colour all faces into zones using borderEdge
|
||||
labelList normalZone;
|
||||
label nZones = PatchTools::markZones(s, borderEdge, normalZone);
|
||||
if (nZones > 1)
|
||||
{
|
||||
hasError = true;
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< " " << names()[surfI]
|
||||
<< " : has multiple orientation zones ("
|
||||
<< nZones << ")" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
return returnReduce(hasError, orOp<bool>());
|
||||
}
|
||||
|
||||
|
||||
bool Foam::searchableSurfaces::checkSizes
|
||||
(
|
||||
const scalar maxRatio,
|
||||
const bool report
|
||||
) const
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
Info<< "Checking for size." << endl;
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
forAll(*this, i)
|
||||
{
|
||||
const boundBox& bb = operator[](i).bounds();
|
||||
|
||||
for (label j = i+1; j < size(); j++)
|
||||
{
|
||||
scalar ratio = bb.mag()/operator[](j).bounds().mag();
|
||||
|
||||
if (ratio > maxRatio || ratio < 1.0/maxRatio)
|
||||
{
|
||||
hasError = true;
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< " " << names()[i]
|
||||
<< " bounds differ from " << names()[j]
|
||||
<< " by more than a factor 100:" << nl
|
||||
<< " bounding box : " << bb << nl
|
||||
<< " bounding box : " << operator[](j).bounds()
|
||||
<< endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
return returnReduce(hasError, orOp<bool>());
|
||||
}
|
||||
|
||||
|
||||
bool Foam::searchableSurfaces::checkIntersection
|
||||
(
|
||||
const scalar tolerance,
|
||||
const autoPtr<writer<scalar> >& setWriter,
|
||||
const bool report
|
||||
) const
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
Info<< "Checking for intersection." << endl;
|
||||
}
|
||||
|
||||
//cpuTime timer;
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
forAll(*this, i)
|
||||
{
|
||||
if (isA<triSurfaceMesh>(operator[](i)))
|
||||
{
|
||||
const triSurfaceMesh& s0 = dynamic_cast<const triSurfaceMesh&>
|
||||
(
|
||||
operator[](i)
|
||||
);
|
||||
const edgeList& edges0 = s0.edges();
|
||||
const pointField& localPoints0 = s0.localPoints();
|
||||
|
||||
// Collect all the edge vectors
|
||||
pointField start(edges0.size());
|
||||
pointField end(edges0.size());
|
||||
forAll(edges0, edgeI)
|
||||
{
|
||||
const edge& e = edges0[edgeI];
|
||||
start[edgeI] = localPoints0[e[0]];
|
||||
end[edgeI] = localPoints0[e[1]];
|
||||
}
|
||||
|
||||
// Test all other surfaces for intersection
|
||||
forAll(*this, j)
|
||||
{
|
||||
List<pointIndexHit> hits;
|
||||
|
||||
if (i == j)
|
||||
{
|
||||
// Slightly shorten the edges to prevent finding lots of
|
||||
// intersections. The fast triangle intersection routine
|
||||
// has problems with rays passing through a point of the
|
||||
// triangle.
|
||||
vectorField d
|
||||
(
|
||||
max(tolerance, 10*s0.tolerance())
|
||||
*(end-start)
|
||||
);
|
||||
start += d;
|
||||
end -= d;
|
||||
}
|
||||
|
||||
operator[](j).findLineAny(start, end, hits);
|
||||
|
||||
label nHits = 0;
|
||||
DynamicField<point> intersections(edges0.size()/100);
|
||||
DynamicField<scalar> intersectionEdge(intersections.capacity());
|
||||
|
||||
forAll(hits, edgeI)
|
||||
{
|
||||
if
|
||||
(
|
||||
hits[edgeI].hit()
|
||||
&& (i != j || !connected(s0, edgeI, hits[edgeI]))
|
||||
)
|
||||
{
|
||||
intersections.append(hits[edgeI].hitPoint());
|
||||
intersectionEdge.append(1.0*edgeI);
|
||||
nHits++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nHits > 0)
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
Info<< " " << names()[i]
|
||||
<< " intersects " << names()[j]
|
||||
<< " at " << nHits
|
||||
<< " locations."
|
||||
<< endl;
|
||||
|
||||
//vtkSetWriter<scalar> setWriter;
|
||||
if (setWriter.valid())
|
||||
{
|
||||
scalarField dist(mag(intersections));
|
||||
coordSet track
|
||||
(
|
||||
names()[i] + '_' + names()[j],
|
||||
"xyz",
|
||||
intersections.xfer(),
|
||||
dist
|
||||
);
|
||||
wordList valueSetNames(1, "edgeIndex");
|
||||
List<const scalarField*> valueSets
|
||||
(
|
||||
1,
|
||||
&intersectionEdge
|
||||
);
|
||||
|
||||
fileName fName
|
||||
(
|
||||
setWriter().getFileName(track, valueSetNames)
|
||||
);
|
||||
Info<< " Writing intersection locations to "
|
||||
<< fName << endl;
|
||||
OFstream os
|
||||
(
|
||||
s0.searchableSurface::time().path()
|
||||
/fName
|
||||
);
|
||||
setWriter().write
|
||||
(
|
||||
track,
|
||||
valueSetNames,
|
||||
valueSets,
|
||||
os
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
return returnReduce(hasError, orOp<bool>());
|
||||
}
|
||||
|
||||
|
||||
bool Foam::searchableSurfaces::checkQuality
|
||||
(
|
||||
const scalar minQuality,
|
||||
const bool report
|
||||
) const
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
Info<< "Checking for triangle quality." << endl;
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
forAll(*this, surfI)
|
||||
{
|
||||
if (isA<triSurface>(operator[](surfI)))
|
||||
{
|
||||
const triSurface& s = dynamic_cast<const triSurface&>
|
||||
(
|
||||
operator[](surfI)
|
||||
);
|
||||
|
||||
label nBadTris = 0;
|
||||
forAll(s, faceI)
|
||||
{
|
||||
const labelledTri& f = s[faceI];
|
||||
|
||||
scalar q = triPointRef
|
||||
(
|
||||
s.points()[f[0]],
|
||||
s.points()[f[1]],
|
||||
s.points()[f[2]]
|
||||
).quality();
|
||||
|
||||
if (q < minQuality)
|
||||
{
|
||||
nBadTris++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nBadTris > 0)
|
||||
{
|
||||
hasError = true;
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< " " << names()[surfI]
|
||||
<< " : has " << nBadTris << " bad quality triangles "
|
||||
<< " (quality < " << minQuality << ")" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (report)
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
return returnReduce(hasError, orOp<bool>());
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Check all surfaces. Return number of failures.
|
||||
Foam::label Foam::searchableSurfaces::checkTopology
|
||||
(
|
||||
const bool report
|
||||
) const
|
||||
{
|
||||
label noFailedChecks = 0;
|
||||
|
||||
if (checkClosed(report))
|
||||
{
|
||||
noFailedChecks++;
|
||||
}
|
||||
|
||||
if (checkNormalOrientation(report))
|
||||
{
|
||||
noFailedChecks++;
|
||||
}
|
||||
return noFailedChecks;
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::searchableSurfaces::checkGeometry
|
||||
(
|
||||
const scalar maxRatio,
|
||||
const scalar tol,
|
||||
const autoPtr<writer<scalar> >& setWriter,
|
||||
const scalar minQuality,
|
||||
const bool report
|
||||
) const
|
||||
{
|
||||
label noFailedChecks = 0;
|
||||
|
||||
if (maxRatio > 0 && checkSizes(maxRatio, report))
|
||||
{
|
||||
noFailedChecks++;
|
||||
}
|
||||
|
||||
if (checkIntersection(tol, setWriter, report))
|
||||
{
|
||||
noFailedChecks++;
|
||||
}
|
||||
|
||||
if (checkQuality(minQuality, report))
|
||||
{
|
||||
noFailedChecks++;
|
||||
}
|
||||
|
||||
return noFailedChecks;
|
||||
}
|
||||
|
||||
|
||||
void Foam::searchableSurfaces::writeStats
|
||||
(
|
||||
const List<wordList>& patchTypes,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
Info<< "Statistics." << endl;
|
||||
forAll(*this, surfI)
|
||||
{
|
||||
Info<< " " << names()[surfI] << ':' << endl;
|
||||
|
||||
const searchableSurface& s = operator[](surfI);
|
||||
|
||||
Info<< " type : " << s.type() << nl
|
||||
<< " size : " << s.globalSize() << nl;
|
||||
if (isA<triSurfaceMesh>(s))
|
||||
{
|
||||
const triSurfaceMesh& ts = dynamic_cast<const triSurfaceMesh&>(s);
|
||||
Info<< " edges : " << ts.nEdges() << nl
|
||||
<< " points : " << ts.points().size() << nl;
|
||||
}
|
||||
Info<< " bounds : " << s.bounds() << nl
|
||||
<< " closed : " << Switch(s.hasVolumeType()) << endl;
|
||||
|
||||
if (patchTypes.size() && patchTypes[surfI].size() >= 1)
|
||||
{
|
||||
wordList unique(HashSet<word>(patchTypes[surfI]).sortedToc());
|
||||
Info<< " patches : ";
|
||||
forAll(unique, i)
|
||||
{
|
||||
Info<< unique[i];
|
||||
if (i < unique.size()-1)
|
||||
{
|
||||
Info<< ',';
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::searchableSurface& Foam::searchableSurfaces::operator[]
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -37,6 +37,7 @@ SourceFiles
|
||||
|
||||
#include "searchableSurface.H"
|
||||
#include "labelPair.H"
|
||||
#include "writer.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -44,6 +45,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class triSurface;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class searchableSurfaces Declaration
|
||||
@ -70,6 +72,15 @@ class searchableSurfaces
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Is edge on face
|
||||
static bool connected
|
||||
(
|
||||
const triSurface& s,
|
||||
const label edgeI,
|
||||
const pointIndexHit& hit
|
||||
);
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
searchableSurfaces(const searchableSurfaces&);
|
||||
|
||||
@ -189,6 +200,49 @@ public:
|
||||
) const;
|
||||
|
||||
|
||||
// Checking
|
||||
|
||||
//- Are all surfaces closed and manifold
|
||||
bool checkClosed(const bool report) const;
|
||||
|
||||
//- Are all (triangulated) surfaces consistent normal orientation
|
||||
bool checkNormalOrientation(const bool report) const;
|
||||
|
||||
//- Are all bounding boxes of similar size
|
||||
bool checkSizes(const scalar maxRatio, const bool report) const;
|
||||
|
||||
//- Do surfaces self-intersect or intersect others
|
||||
bool checkIntersection
|
||||
(
|
||||
const scalar tol,
|
||||
const autoPtr<writer<scalar> >&,
|
||||
const bool report
|
||||
) const;
|
||||
|
||||
//- Check triangle quality
|
||||
bool checkQuality
|
||||
(
|
||||
const scalar minQuality,
|
||||
const bool report
|
||||
) const;
|
||||
|
||||
//- All topological checks. Return number of failed checks
|
||||
label checkTopology(const bool report) const;
|
||||
|
||||
//- All geometric checks. Return number of failed checks
|
||||
label checkGeometry
|
||||
(
|
||||
const scalar maxRatio,
|
||||
const scalar tolerance,
|
||||
const autoPtr<writer<scalar> >& setWriter,
|
||||
const scalar minQuality,
|
||||
const bool report
|
||||
) const;
|
||||
|
||||
//- Write some stats
|
||||
void writeStats(const List<wordList>&, Ostream&) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Return const and non-const reference to searchableSurface by index.
|
||||
|
||||
@ -625,6 +625,12 @@ Foam::triSurfaceMesh::edgeTree() const
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::triSurfaceMesh::tolerance() const
|
||||
{
|
||||
return tolerance_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::wordList& Foam::triSurfaceMesh::regions() const
|
||||
{
|
||||
if (regions_.empty())
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -182,6 +182,7 @@ public:
|
||||
//- Demand driven contruction of octree for boundary edges
|
||||
const indexedOctree<treeDataEdge>& edgeTree() const;
|
||||
|
||||
scalar tolerance() const;
|
||||
|
||||
// searchableSurface implementation
|
||||
|
||||
|
||||
@ -238,6 +238,38 @@ Foam::Ostream& Foam::OBJstream::write(const linePointRef& ln)
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::OBJstream::write
|
||||
(
|
||||
const triPointRef& f,
|
||||
const bool lines
|
||||
)
|
||||
{
|
||||
label start = nVertices_;
|
||||
write(f.a());
|
||||
write(f.b());
|
||||
write(f.c());
|
||||
if (lines)
|
||||
{
|
||||
write('l');
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
write(' ') << start+1+i;
|
||||
}
|
||||
write(' ') << start+1 << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
write('f');
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
write(' ') << start+1+i;
|
||||
}
|
||||
write('\n');
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::OBJstream::write
|
||||
(
|
||||
const face& f,
|
||||
|
||||
@ -39,13 +39,14 @@ SourceFiles
|
||||
#include "point.H"
|
||||
#include "edge.H"
|
||||
#include "face.H"
|
||||
#include "triPointRef.H"
|
||||
#include "linePointRef.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class OBJstream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -134,6 +135,9 @@ public:
|
||||
//- Write line
|
||||
Ostream& write(const linePointRef&);
|
||||
|
||||
//- Write triangle as points with lines or filled polygon
|
||||
Ostream& write(const triPointRef&, const bool lines = true);
|
||||
|
||||
//- Write face as points with lines or filled polygon
|
||||
Ostream& write
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user