diff --git a/applications/test/PatchEdgeFaceWave/Make/files b/applications/test/PatchEdgeFaceWave/Make/files
new file mode 100644
index 0000000000..01051a3553
--- /dev/null
+++ b/applications/test/PatchEdgeFaceWave/Make/files
@@ -0,0 +1,3 @@
+Test-PatchEdgeFaceWave.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-PatchEdgeFaceWave
diff --git a/applications/test/PatchEdgeFaceWave/Make/options b/applications/test/PatchEdgeFaceWave/Make/options
new file mode 100644
index 0000000000..d27c95d033
--- /dev/null
+++ b/applications/test/PatchEdgeFaceWave/Make/options
@@ -0,0 +1,7 @@
+EXE_INC = \
+ -I$(LIB_SRC)/finiteVolume/lnInclude \
+ -I$(LIB_SRC)/meshTools/lnInclude
+
+EXE_LIBS = \
+ -lfiniteVolume \
+ -lmeshTools
diff --git a/applications/test/PatchEdgeFaceWave/Test-PatchEdgeFaceWave.C b/applications/test/PatchEdgeFaceWave/Test-PatchEdgeFaceWave.C
new file mode 100644
index 0000000000..2dfb19118b
--- /dev/null
+++ b/applications/test/PatchEdgeFaceWave/Test-PatchEdgeFaceWave.C
@@ -0,0 +1,132 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2011 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 .
+
+Description
+ Test PatchEdgeFaceWave.
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "Time.H"
+#include "fvMesh.H"
+#include "volFields.H"
+#include "PatchEdgeFaceWave.H"
+#include "patchEdgeFaceInfo.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+int main(int argc, char *argv[])
+{
+ argList::validArgs.append("patch");
+
+# include "setRootCase.H"
+# include "createTime.H"
+# include "createMesh.H"
+
+ const polyBoundaryMesh& patches = mesh.boundaryMesh();
+
+ // Get name of patch
+ const word patchName = args[1];
+
+ const polyPatch& patch = patches[patchName];
+
+ // Data on all edges and faces
+ List allEdgeInfo(patch.nEdges());
+ List allFaceInfo(patch.size());
+
+ // Initial seed
+ DynamicList initialEdges;
+ DynamicList initialEdgesInfo;
+
+
+ // Just set an edge on the master
+ if (Pstream::master())
+ {
+ label edgeI = 0;
+ Info<< "Starting walk on edge " << edgeI << endl;
+
+ initialEdges.append(edgeI);
+ const edge& e = patch.edges()[edgeI];
+ initialEdgesInfo.append
+ (
+ patchEdgeFaceInfo
+ (
+ e.centre(patch.localPoints()),
+ 0.0
+ )
+ );
+ }
+
+
+ // Walk
+ PatchEdgeFaceWave
+ <
+ primitivePatch,
+ patchEdgeFaceInfo
+ > calc
+ (
+ mesh,
+ patch,
+ initialEdges,
+ initialEdgesInfo,
+ allEdgeInfo,
+ allFaceInfo,
+ returnReduce(patch.nEdges(), sumOp())
+ );
+
+
+ // Extract as patchField
+ volScalarField vsf
+ (
+ IOobject
+ (
+ "patchDist",
+ runTime.timeName(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::AUTO_WRITE
+ ),
+ mesh,
+ dimensionedScalar("patchDist", dimLength, 0.0)
+ );
+ scalarField pf(vsf.boundaryField()[patch.index()].size());
+ forAll(pf, faceI)
+ {
+ pf[faceI] = Foam::sqrt(allFaceInfo[faceI].distSqr());
+ }
+ vsf.boundaryField()[patch.index()] = pf;
+
+ Info<< "Writing patchDist volScalarField to " << runTime.value()
+ << endl;
+
+ vsf.write();
+
+
+ Info<< "\nEnd\n" << endl;
+ return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
index 9800ba6006..d1b4926e76 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
@@ -46,6 +46,20 @@ defineTypeNameAndDebug(Foam::globalMeshData, 0);
// Geometric matching tolerance. Factor of mesh bounding box.
const Foam::scalar Foam::globalMeshData::matchTol_ = 1E-8;
+namespace Foam
+{
+template<>
+class minEqOp
+{
+public:
+ void operator()(labelPair& x, const labelPair& y) const
+ {
+ x[0] = min(x[0], y[0]);
+ x[1] = min(x[1], y[1]);
+ }
+};
+}
+
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@@ -1063,6 +1077,128 @@ void Foam::globalMeshData::calcGlobalEdgeSlaves() const
}
+void Foam::globalMeshData::calcGlobalEdgeOrientation() const
+{
+ if (debug)
+ {
+ Pout<< "globalMeshData::calcGlobalEdgeOrientation() :"
+ << " calculating edge orientation w.r.t. master edge." << endl;
+ }
+
+ const globalIndex& globalPoints = globalPointNumbering();
+
+ // 1. Determine master point
+ labelList masterPoint;
+ {
+ const mapDistribute& map = globalPointSlavesMap();
+
+ masterPoint.setSize(map.constructSize());
+ masterPoint = labelMax;
+
+ for (label pointI = 0; pointI < coupledPatch().nPoints(); pointI++)
+ {
+ masterPoint[pointI] = globalPoints.toGlobal(pointI);
+ }
+ syncData
+ (
+ masterPoint,
+ globalPointSlaves(),
+ globalPointTransformedSlaves(),
+ map,
+ minEqOp()
+ );
+ }
+
+ // Now all points should know who is master by comparing their global
+ // pointID with the masterPointID. We now can use this information
+ // to find the orientation of the master edge.
+
+ {
+ const mapDistribute& map = globalEdgeSlavesMap();
+ const labelListList& slaves = globalEdgeSlaves();
+ const labelListList& transformedSlaves = globalEdgeTransformedSlaves();
+
+ // Distribute orientation of master edge (in masterPoint numbering)
+ labelPairList masterEdgeVerts(map.constructSize());
+ masterEdgeVerts = labelPair(labelMax, labelMax);
+
+ for (label edgeI = 0; edgeI < coupledPatch().nEdges(); edgeI++)
+ {
+ if
+ (
+ (
+ slaves[edgeI].size()
+ + transformedSlaves[edgeI].size()
+ )
+ > 0
+ )
+ {
+ // I am master. Fill in my masterPoint equivalent.
+
+ const edge& e = coupledPatch().edges()[edgeI];
+ masterEdgeVerts[edgeI] = labelPair
+ (
+ masterPoint[e[0]],
+ masterPoint[e[1]]
+ );
+ }
+ }
+ syncData
+ (
+ masterEdgeVerts,
+ slaves,
+ transformedSlaves,
+ map,
+ minEqOp()
+ );
+
+ // Now check my edges on how they relate to the master's edgeVerts
+ globalEdgeOrientationPtr_.reset
+ (
+ new PackedBoolList(coupledPatch().nEdges())
+ );
+ PackedBoolList& globalEdgeOrientation = globalEdgeOrientationPtr_();
+
+ forAll(coupledPatch().edges(), edgeI)
+ {
+ const edge& e = coupledPatch().edges()[edgeI];
+ const labelPair masterE
+ (
+ masterPoint[e[0]],
+ masterPoint[e[1]]
+ );
+
+ label stat = labelPair::compare
+ (
+ masterE,
+ masterEdgeVerts[edgeI]
+ );
+ if (stat == 0)
+ {
+ FatalErrorIn
+ (
+ "globalMeshData::calcGlobalEdgeOrientation() const"
+ ) << "problem : my edge:" << e
+ << " in master points:" << masterE
+ << " v.s. masterEdgeVerts:" << masterEdgeVerts[edgeI]
+ << exit(FatalError);
+ }
+ else
+ {
+ globalEdgeOrientation[edgeI] = (stat == 1);
+ }
+ }
+ }
+
+ if (debug)
+ {
+ Pout<< "globalMeshData::calcGlobalEdgeOrientation() :"
+ << " finished calculating edge orientation."
+ << endl;
+ }
+}
+
+
// Calculate uncoupled boundary faces (without calculating
// primitiveMesh::pointFaces())
void Foam::globalMeshData::calcPointBoundaryFaces
@@ -1660,6 +1796,7 @@ void Foam::globalMeshData::clearOut()
globalEdgeNumberingPtr_.clear();
globalEdgeSlavesPtr_.clear();
globalEdgeTransformedSlavesPtr_.clear();
+ globalEdgeOrientationPtr_.clear();
globalEdgeSlavesMapPtr_.clear();
// Face
@@ -2095,6 +2232,16 @@ const
}
+const Foam::PackedBoolList& Foam::globalMeshData::globalEdgeOrientation() const
+{
+ if (!globalEdgeOrientationPtr_.valid())
+ {
+ calcGlobalEdgeOrientation();
+ }
+ return globalEdgeOrientationPtr_();
+}
+
+
const Foam::mapDistribute& Foam::globalMeshData::globalEdgeSlavesMap() const
{
if (!globalEdgeSlavesMapPtr_.valid())
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H
index 3fca52ae97..a3530dc86c 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H
@@ -95,6 +95,7 @@ class mapDistribute;
template class EdgeMap;
class globalIndex;
class globalIndexAndTransform;
+class PackedBoolList;
/*---------------------------------------------------------------------------*\
Class globalMeshData Declaration
@@ -191,6 +192,7 @@ class globalMeshData
mutable autoPtr globalEdgeNumberingPtr_;
mutable autoPtr globalEdgeSlavesPtr_;
mutable autoPtr globalEdgeTransformedSlavesPtr_;
+ mutable autoPtr globalEdgeOrientationPtr_;
mutable autoPtr globalEdgeSlavesMapPtr_;
@@ -297,6 +299,9 @@ class globalMeshData
//- Calculate global edge addressing.
void calcGlobalEdgeSlaves() const;
+ //- Calculate orientation w.r.t. edge master.
+ void calcGlobalEdgeOrientation() const;
+
// Global boundary face/cell addressing
@@ -539,6 +544,8 @@ public:
const labelListList& globalEdgeSlaves() const;
const labelListList& globalEdgeTransformedSlaves() const;
const mapDistribute& globalEdgeSlavesMap() const;
+ //- Is my edge same orientation master edge
+ const PackedBoolList& globalEdgeOrientation() const;
// Coupled point to boundary faces. These are uncoupled boundary
// faces only but include empty patches.
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C
index 4a40eac11a..793411c162 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C
@@ -30,6 +30,7 @@ License
#include "PatchToolsSearch.C"
#include "PatchToolsSortEdges.C"
#include "PatchToolsNormals.C"
+#include "PatchToolsMatch.C"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
index 80e50333bd..e4ade383ef 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
@@ -36,6 +36,7 @@ SourceFiles
PatchToolsSearch.C
PatchToolsSortEdges.C
PatchToolsNormals.C
+ PatchToolsMatch.C
\*---------------------------------------------------------------------------*/
@@ -51,6 +52,7 @@ namespace Foam
{
class polyMesh;
+class PackedBoolList;
/*---------------------------------------------------------------------------*\
Class PatchTools Declaration
@@ -169,6 +171,55 @@ public:
);
+ //- Find corresponding points on patches sharing the same points
+ // p1PointLabels : points on p1 that were matched
+ // p2PointLabels : corresponding points on p2
+ template
+ <
+ class Face1,
+ template class FaceList1,
+ class PointField1,
+ class PointType1,
+ class Face2,
+ template class FaceList2,
+ class PointField2,
+ class PointType2
+ >
+ static void matchPoints
+ (
+ const PrimitivePatch& p1,
+ const PrimitivePatch& p2,
+
+ labelList& p1PointLabels,
+ labelList& p2PointLabels
+ );
+
+ //- Find corresponding edges on patches sharing the same points
+ // p1EdgeLabels : edges on p1 that were matched
+ // p2EdgeLabels : corresponding edges on p2
+ // sameOrientation : same orientation?
+ template
+ <
+ class Face1,
+ template class FaceList1,
+ class PointField1,
+ class PointType1,
+ class Face2,
+ template class FaceList2,
+ class PointField2,
+ class PointType2
+ >
+ static void matchEdges
+ (
+ const PrimitivePatch& p1,
+ const PrimitivePatch& p2,
+
+ labelList& p1EdgeLabels,
+ labelList& p2EdgeLabels,
+ PackedBoolList& sameOrientation
+ );
+
+
//- Return parallel consistent point normals for patches (on boundary faces)
// using mesh points.
template
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C
new file mode 100644
index 0000000000..1af68e8991
--- /dev/null
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C
@@ -0,0 +1,137 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2011 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchTools.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+<
+ class Face1,
+ template class FaceList1,
+ class PointField1,
+ class PointType1,
+ class Face2,
+ template class FaceList2,
+ class PointField2,
+ class PointType2
+>
+void Foam::PatchTools::matchPoints
+(
+ const PrimitivePatch& p1,
+ const PrimitivePatch& p2,
+
+ labelList& p1PointLabels,
+ labelList& p2PointLabels
+)
+{
+ p1PointLabels.setSize(p1.nPoints());
+ p2PointLabels.setSize(p1.nPoints());
+
+ label nMatches = 0;
+
+ forAll(p1.meshPoints(), pointI)
+ {
+ label meshPointI = p1.meshPoints()[pointI];
+
+ Map::const_iterator iter = p2.meshPointMap().find
+ (
+ meshPointI
+ );
+
+ if (iter != p2.meshPointMap().end())
+ {
+ p1PointLabels[nMatches] = pointI;
+ p2PointLabels[nMatches] = iter();
+ nMatches++;
+ }
+ }
+ p1PointLabels.setSize(nMatches);
+ p2PointLabels.setSize(nMatches);
+}
+
+
+template
+<
+ class Face1,
+ template class FaceList1,
+ class PointField1,
+ class PointType1,
+ class Face2,
+ template class FaceList2,
+ class PointField2,
+ class PointType2
+>
+void Foam::PatchTools::matchEdges
+(
+ const PrimitivePatch& p1,
+ const PrimitivePatch& p2,
+
+ labelList& p1EdgeLabels,
+ labelList& p2EdgeLabels,
+ PackedBoolList& sameOrientation
+)
+{
+ p1EdgeLabels.setSize(p1.nEdges());
+ p2EdgeLabels.setSize(p1.nEdges());
+ sameOrientation.setSize(p1.nEdges());
+ sameOrientation = 0;
+
+ label nMatches = 0;
+
+ EdgeMap edgeToIndex(2*p1.nEdges());
+ forAll(p1.edges(), edgeI)
+ {
+ const edge& e = p1.edges()[edgeI];
+ const edge meshE
+ (
+ p1.meshPoints()[e[0]],
+ p1.meshPoints()[e[1]]
+ );
+ edgeToIndex.insert(meshE, edgeI);
+ }
+
+ forAll(p2.edges(), edgeI)
+ {
+ const edge& e = p2.edges()[edgeI];
+ const edge meshE(p2.meshPoints()[e[0]], p2.meshPoints()[e[1]]);
+
+ EdgeMap::const_iterator iter = edgeToIndex.find(meshE);
+
+ if (iter != edgeToIndex.end())
+ {
+ p1EdgeLabels[nMatches] = iter();
+ p2EdgeLabels[nMatches] = edgeI;
+ sameOrientation[nMatches] = (meshE[0] == iter.key()[0]);
+ nMatches++;
+ }
+ }
+ p1EdgeLabels.setSize(nMatches);
+ p2EdgeLabels.setSize(nMatches);
+ sameOrientation.setSize(nMatches);
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 51be547786..1c981f4788 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -30,8 +30,13 @@ meshSearch/meshSearch.C
meshTools/meshTools.C
-PointEdgeWave/PointEdgeWaveName.C
-PointEdgeWave/pointEdgePoint.C
+pWave = PointEdgeWave
+$(pWave)/PointEdgeWaveName.C
+$(pWave)/pointEdgePoint.C
+
+patchWave = PatchEdgeFaceWave
+$(patchWave)/PatchEdgeFaceWaveName.C
+$(patchWave)/patchEdgeFaceInfo.C
regionSplit/regionSplit.C
diff --git a/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.C b/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.C
new file mode 100644
index 0000000000..129d82ae12
--- /dev/null
+++ b/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.C
@@ -0,0 +1,681 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchEdgeFaceWave.H"
+#include "polyMesh.H"
+#include "globalMeshData.H"
+#include "PatchTools.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::scalar Foam::PatchEdgeFaceWave::
+propagationTol_ = 0.01;
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::label
+Foam::PatchEdgeFaceWave::
+dummyTrackData_ = 12345;
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+// Update info for edgeI, at position pt, with information from
+// neighbouring face.
+// Updates:
+// - changedEdge_, changedEdges_,
+// - statistics: nEvals_, nUnvisitedEdges_
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+bool Foam::PatchEdgeFaceWave::
+updateEdge
+(
+ const label edgeI,
+ const label neighbourFaceI,
+ const Type& neighbourInfo,
+ Type& edgeInfo
+)
+{
+ nEvals_++;
+
+ bool wasValid = edgeInfo.valid(td_);
+
+ bool propagate =
+ edgeInfo.updateEdge
+ (
+ mesh_,
+ patch_,
+ edgeI,
+ neighbourFaceI,
+ neighbourInfo,
+ propagationTol_,
+ td_
+ );
+
+ if (propagate)
+ {
+ if (!changedEdge_[edgeI])
+ {
+ changedEdge_[edgeI] = true;
+ changedEdges_.append(edgeI);
+ }
+ }
+
+ if (!wasValid && edgeInfo.valid(td_))
+ {
+ --nUnvisitedEdges_;
+ }
+
+ return propagate;
+}
+
+
+// Update info for faceI, at position pt, with information from
+// neighbouring edge.
+// Updates:
+// - changedFace_, changedFaces_,
+// - statistics: nEvals_, nUnvisitedFace_
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+bool Foam::PatchEdgeFaceWave::
+updateFace
+(
+ const label faceI,
+ const label neighbourEdgeI,
+ const Type& neighbourInfo,
+ Type& faceInfo
+)
+{
+ nEvals_++;
+
+ bool wasValid = faceInfo.valid(td_);
+
+ bool propagate =
+ faceInfo.updateFace
+ (
+ mesh_,
+ patch_,
+ faceI,
+ neighbourEdgeI,
+ neighbourInfo,
+ propagationTol_,
+ td_
+ );
+
+ if (propagate)
+ {
+ if (!changedFace_[faceI])
+ {
+ changedFace_[faceI] = true;
+ changedFaces_.append(faceI);
+ }
+ }
+
+ if (!wasValid && faceInfo.valid(td_))
+ {
+ --nUnvisitedFaces_;
+ }
+
+ return propagate;
+}
+
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+void Foam::PatchEdgeFaceWave::
+syncEdges()
+{
+ const globalMeshData& globalData = mesh_.globalData();
+ const mapDistribute& map = globalData.globalEdgeSlavesMap();
+ const PackedBoolList& cppOrientation = globalData.globalEdgeOrientation();
+
+ // Convert patch-edge data into cpp-edge data
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ //- Construct with all data in consistent orientation
+ List cppEdgeData(map.constructSize());
+
+ forAll(patchEdges_, i)
+ {
+ label patchEdgeI = patchEdges_[i];
+ label coupledEdgeI = coupledEdges_[i];
+
+ if (changedEdge_[patchEdgeI])
+ {
+ const Type& data = allEdgeInfo_[patchEdgeI];
+
+ // Patch-edge data needs to be converted into coupled-edge data
+ // (optionally flipped) and consistent in orientation with
+ // master of coupled edge (optionally flipped)
+ bool sameOrientation =
+ (
+ sameEdgeOrientation_[i]
+ == cppOrientation[coupledEdgeI]
+ );
+
+ cppEdgeData[coupledEdgeI].updateEdge
+ (
+ mesh_,
+ patch_,
+ data,
+ sameOrientation,
+ propagationTol_,
+ td_
+ );
+ }
+ }
+
+
+ // Synchronise
+ // ~~~~~~~~~~~
+
+ globalData.syncData
+ (
+ cppEdgeData,
+ globalData.globalEdgeSlaves(),
+ globalData.globalEdgeTransformedSlaves(),
+ map,
+ globalData.globalTransforms(),
+ updateOp
+ (
+ mesh_,
+ patch_,
+ propagationTol_,
+ td_
+ ),
+ transformOp
+ (
+ mesh_,
+ patch_,
+ propagationTol_,
+ td_
+ )
+ );
+
+
+ // Back from cpp-edge to patch-edge data
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ forAll(patchEdges_, i)
+ {
+ label patchEdgeI = patchEdges_[i];
+ label coupledEdgeI = coupledEdges_[i];
+
+ const Type& data = cppEdgeData[coupledEdgeI];
+
+ if (data.valid(td_))
+ {
+ bool sameOrientation =
+ (
+ sameEdgeOrientation_[i]
+ == cppOrientation[coupledEdgeI]
+ );
+
+ allEdgeInfo_[patchEdgeI].updateEdge
+ (
+ mesh_,
+ patch_,
+ data,
+ sameOrientation,
+ propagationTol_,
+ td_
+ );
+
+ if (!changedEdge_[patchEdgeI])
+ {
+ changedEdges_.append(patchEdgeI);
+ changedEdge_[patchEdgeI] = true;
+ }
+ }
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+// Iterate, propagating changedEdgesInfo across patch, until no change (or
+// maxIter reached). Initial edge values specified.
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::PatchEdgeFaceWave::
+PatchEdgeFaceWave
+(
+ const polyMesh& mesh,
+ const PrimitivePatchType& patch,
+ const labelList& changedEdges,
+ const List& changedEdgesInfo,
+
+ UList& allEdgeInfo,
+ UList& allFaceInfo,
+
+ const label maxIter,
+ TrackingData& td
+)
+:
+ mesh_(mesh),
+ patch_(patch),
+ allEdgeInfo_(allEdgeInfo),
+ allFaceInfo_(allFaceInfo),
+ td_(td),
+ changedEdge_(patch_.nEdges()),
+ changedEdges_(patch_.size()),
+ changedFace_(patch_.size()),
+ changedFaces_(patch_.size()),
+ nEvals_(0),
+ nUnvisitedEdges_(patch_.nEdges()),
+ nUnvisitedFaces_(patch_.size())
+{
+ // Calculate addressing between patch_ and mesh.globalData().coupledPatch()
+ // for ease of synchronisation
+ PatchTools::matchEdges
+ (
+ patch_,
+ mesh_.globalData().coupledPatch(),
+
+ patchEdges_,
+ coupledEdges_,
+ sameEdgeOrientation_
+ );
+
+
+ if (allEdgeInfo_.size() != patch_.nEdges())
+ {
+ FatalErrorIn
+ (
+ "PatchEdgeFaceWave::PatchEdgeFaceWave"
+ "(const polyMesh&, const labelList&, const List,"
+ " List&, List&, const label maxIter)"
+ ) << "size of edgeInfo work array is not equal to the number"
+ << " of edges in the patch" << endl
+ << " edgeInfo :" << allEdgeInfo_.size() << endl
+ << " patch.nEdges:" << patch_.nEdges()
+ << exit(FatalError);
+ }
+ if (allFaceInfo_.size() != patch_.size())
+ {
+ FatalErrorIn
+ (
+ "PatchEdgeFaceWave::PatchEdgeFaceWave"
+ "(const polyMesh&, const labelList&, const List,"
+ " List&, List&, const label maxIter)"
+ ) << "size of edgeInfo work array is not equal to the number"
+ << " of faces in the patch" << endl
+ << " faceInfo :" << allFaceInfo_.size() << endl
+ << " patch.size:" << patch_.size()
+ << exit(FatalError);
+ }
+
+
+ // Set from initial changed edges data
+ setEdgeInfo(changedEdges, changedEdgesInfo);
+
+ if (debug)
+ {
+ Pout<< "Seed edges : " << changedEdges_.size() << endl;
+ }
+
+ // Iterate until nothing changes
+ label iter = iterate(maxIter);
+
+ if ((maxIter > 0) && (iter >= maxIter))
+ {
+ FatalErrorIn
+ (
+ "PatchEdgeFaceWave::PatchEdgeFaceWave"
+ "(const polyMesh&, const labelList&, const List,"
+ " List&, List&, const label maxIter)"
+ ) << "Maximum number of iterations reached. Increase maxIter." << endl
+ << " maxIter:" << maxIter << endl
+ << " changedEdges:" << changedEdges_.size() << endl
+ << " changedFaces:" << changedFaces_.size() << endl
+ << exit(FatalError);
+ }
+}
+
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::PatchEdgeFaceWave::
+PatchEdgeFaceWave
+(
+ const polyMesh& mesh,
+ const PrimitivePatchType& patch,
+ UList& allEdgeInfo,
+ UList& allFaceInfo,
+ TrackingData& td
+)
+:
+ mesh_(mesh),
+ patch_(patch),
+ allEdgeInfo_(allEdgeInfo),
+ allFaceInfo_(allFaceInfo),
+ td_(td),
+ changedEdge_(patch_.nEdges()),
+ changedEdges_(patch_.nEdges()),
+ changedFace_(patch_.size()),
+ changedFaces_(patch_.size()),
+ nEvals_(0),
+ nUnvisitedEdges_(patch_.nEdges()),
+ nUnvisitedFaces_(patch_.size())
+{
+ // Calculate addressing between patch_ and mesh.globalData().coupledPatch()
+ // for ease of synchronisation
+ PatchTools::matchEdges
+ (
+ patch_,
+ mesh_.globalData().coupledPatch(),
+
+ patchEdges_,
+ coupledEdges_,
+ sameEdgeOrientation_
+ );
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::label Foam::PatchEdgeFaceWave::
+getUnsetEdges() const
+{
+ return nUnvisitedEdges_;
+}
+
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::label Foam::PatchEdgeFaceWave::
+getUnsetFaces() const
+{
+ return nUnvisitedFaces_;
+}
+
+
+// Copy edge information into member data
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+void Foam::PatchEdgeFaceWave::
+setEdgeInfo
+(
+ const labelList& changedEdges,
+ const List& changedEdgesInfo
+)
+{
+ forAll(changedEdges, changedEdgeI)
+ {
+ label edgeI = changedEdges[changedEdgeI];
+
+ bool wasValid = allEdgeInfo_[edgeI].valid(td_);
+
+ // Copy info for edgeI
+ allEdgeInfo_[edgeI] = changedEdgesInfo[changedEdgeI];
+
+ // Maintain count of unset edges
+ if (!wasValid && allEdgeInfo_[edgeI].valid(td_))
+ {
+ --nUnvisitedEdges_;
+ }
+
+ // Mark edgeI as changed, both on list and on edge itself.
+
+ if (!changedEdge_[edgeI])
+ {
+ changedEdge_[edgeI] = true;
+ changedEdges_.append(edgeI);
+ }
+ }
+}
+
+
+// Propagate information from face to edge. Return number of edges changed.
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::label Foam::PatchEdgeFaceWave::
+faceToEdge()
+{
+ changedEdges_.clear();
+ changedEdge_ = false;
+
+ forAll(changedFaces_, changedFaceI)
+ {
+ label faceI = changedFaces_[changedFaceI];
+
+ if (!changedFace_[faceI])
+ {
+ FatalErrorIn("PatchEdgeFaceWave::faceToEdge()")
+ << "face " << faceI
+ << " not marked as having been changed" << nl
+ << "This might be caused by multiple occurences of the same"
+ << " seed edge." << abort(FatalError);
+ }
+
+ const Type& neighbourWallInfo = allFaceInfo_[faceI];
+
+ // Evaluate all connected edges
+ const labelList& fEdges = patch_.faceEdges()[faceI];
+
+ forAll(fEdges, fEdgeI)
+ {
+ label edgeI = fEdges[fEdgeI];
+
+ Type& currentWallInfo = allEdgeInfo_[edgeI];
+
+ if (!currentWallInfo.equal(neighbourWallInfo, td_))
+ {
+ updateEdge
+ (
+ edgeI,
+ faceI,
+ neighbourWallInfo,
+ currentWallInfo
+ );
+ }
+ }
+ }
+
+
+ syncEdges();
+
+
+ if (debug)
+ {
+ Pout<< "Changed edges : " << changedEdges_.size() << endl;
+ }
+
+ return returnReduce(changedEdges_.size(), sumOp());
+}
+
+
+// Propagate information from edge to face. Return number of faces changed.
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::label Foam::PatchEdgeFaceWave::
+edgeToFace()
+{
+ changedFaces_.clear();
+ changedFace_ = false;
+
+ const labelListList& edgeFaces = patch_.edgeFaces();
+
+ forAll(changedEdges_, changedEdgeI)
+ {
+ label edgeI = changedEdges_[changedEdgeI];
+
+ if (!changedEdge_[edgeI])
+ {
+ FatalErrorIn("PatchEdgeFaceWave::edgeToFace()")
+ << "edge " << edgeI
+ << " not marked as having been changed" << nl
+ << "This might be caused by multiple occurences of the same"
+ << " seed edge." << abort(FatalError);
+ }
+
+ const Type& neighbourWallInfo = allEdgeInfo_[edgeI];
+
+ // Evaluate all connected faces
+
+ const labelList& eFaces = edgeFaces[edgeI];
+ forAll(eFaces, eFaceI)
+ {
+ label faceI = eFaces[eFaceI];
+
+ Type& currentWallInfo = allFaceInfo_[faceI];
+
+ if (!currentWallInfo.equal(neighbourWallInfo, td_))
+ {
+ updateFace
+ (
+ faceI,
+ edgeI,
+ neighbourWallInfo,
+ currentWallInfo
+ );
+ }
+ }
+ }
+
+ if (debug)
+ {
+ Pout<< "Changed faces : " << changedFaces_.size() << endl;
+ }
+
+ return returnReduce(changedFaces_.size(), sumOp());
+}
+
+
+// Iterate
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData
+>
+Foam::label Foam::PatchEdgeFaceWave::
+iterate
+(
+ const label maxIter
+)
+{
+ // Make sure coupled edges contain same info
+ syncEdges();
+
+ nEvals_ = 0;
+
+ label iter = 0;
+
+ while (iter < maxIter)
+ {
+ if (debug)
+ {
+ Pout<< "Iteration " << iter << endl;
+ }
+
+ label nFaces = edgeToFace();
+
+ if (debug)
+ {
+ Pout<< "Total changed faces : " << nFaces << endl;
+ }
+
+ if (nFaces == 0)
+ {
+ break;
+ }
+
+ label nEdges = faceToEdge();
+
+ if (debug)
+ {
+ Pout<< "Total changed edges : " << nEdges << nl
+ << "Total evaluations : " << nEvals_ << nl
+ << "Remaining unvisited edges : " << nUnvisitedEdges_ << nl
+ << "Remaining unvisited faces : " << nUnvisitedFaces_ << nl
+ << endl;
+ }
+
+ if (nEdges == 0)
+ {
+ break;
+ }
+
+ iter++;
+ }
+
+ return iter;
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.H b/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.H
new file mode 100644
index 0000000000..1551152c13
--- /dev/null
+++ b/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.H
@@ -0,0 +1,368 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 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 .
+
+Class
+ Foam::PatchEdgeFaceWave
+
+Description
+ Wave propagation of information along patch. Every iteration
+ information goes through one layer of faces. Templated on information
+ that is transferred.
+
+SourceFiles
+ PatchEdgeFaceWave.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PatchEdgeFaceWave_H
+#define PatchEdgeFaceWave_H
+
+#include "scalarField.H"
+#include "PackedBoolList.H"
+#include "PrimitivePatch.H"
+#include "vectorTensorTransform.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+ Class PatchEdgeFaceWaveName Declaration
+\*---------------------------------------------------------------------------*/
+
+TemplateName(PatchEdgeFaceWave);
+
+
+/*---------------------------------------------------------------------------*\
+ Class PatchEdgeFaceWave Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData = int
+>
+class PatchEdgeFaceWave
+:
+ public PatchEdgeFaceWaveName
+{
+ // Private static data
+
+ //- Relative tolerance. Stop propagation if relative changes
+ // less than this tolerance (responsability for checking this is
+ // up to Type implementation)
+ static scalar propagationTol_;
+
+ //- Used as default trackdata value to satisfy default template
+ // argument.
+ static label dummyTrackData_;
+
+
+ // Private data
+
+ //- Reference to mesh
+ const polyMesh& mesh_;
+
+ //- Reference to patch
+ const PrimitivePatchType& patch_;
+
+ //- Wall information for all edges
+ UList& allEdgeInfo_;
+
+ //- Information on all patch faces
+ UList& allFaceInfo_;
+
+ //- Additional data to be passed into container
+ TrackingData& td_;
+
+ //- Has edge changed
+ PackedBoolList changedEdge_;
+
+ //- List of changed edges
+ DynamicList changedEdges_;
+
+ //- Has face changed
+ PackedBoolList changedFace_;
+
+ //- List of changed faces
+ DynamicList changedFaces_;
+
+ //- Number of evaluations
+ label nEvals_;
+
+ //- Number of unvisited faces/edges
+ label nUnvisitedEdges_;
+ label nUnvisitedFaces_;
+
+
+ // Addressing between edges of patch_ and globalData.coupledPatch()
+ labelList patchEdges_;
+ labelList coupledEdges_;
+ PackedBoolList sameEdgeOrientation_;
+
+
+ // Private Member Functions
+
+ //- Updates edgeInfo with information from neighbour. Updates all
+ // statistics.
+ bool updateEdge
+ (
+ const label edgeI,
+ const label neighbourFaceI,
+ const Type& neighbourInfo,
+ Type& edgeInfo
+ );
+
+ //- Updates faceInfo with information from neighbour. Updates all
+ // statistics.
+ bool updateFace
+ (
+ const label faceI,
+ const label neighbourEdgeI,
+ const Type& neighbourInfo,
+ Type& faceInfo
+ );
+
+ //- Update coupled edges
+ void syncEdges();
+
+ //- Disallow default bitwise copy construct
+ PatchEdgeFaceWave(const PatchEdgeFaceWave&);
+
+ //- Disallow default bitwise assignment
+ void operator=(const PatchEdgeFaceWave&);
+
+
+public:
+
+ // Static Functions
+
+ //- Access to tolerance
+ static scalar propagationTol()
+ {
+ return propagationTol_;
+ }
+
+ //- Change tolerance
+ static void setPropagationTol(const scalar tol)
+ {
+ propagationTol_ = tol;
+ }
+
+
+ // Constructors
+
+ //- Construct from patch, list of changed edges with the Type
+ // for these edges. Gets work arrays to operate on, one of size
+ // number of patch edges, the other number of patch faces.
+ // Iterates until nothing changes or maxIter reached.
+ // (maxIter can be 0)
+ PatchEdgeFaceWave
+ (
+ const polyMesh& mesh,
+ const PrimitivePatchType& patch,
+ const labelList& initialEdges,
+ const List& initialEdgesInfo,
+ UList& allEdgeInfo,
+ UList& allFaceInfo,
+ const label maxIter,
+ TrackingData& td = dummyTrackData_
+ );
+
+ //- Construct from patch. Use setEdgeInfo and iterate() to do
+ // actual calculation
+ PatchEdgeFaceWave
+ (
+ const polyMesh& mesh,
+ const PrimitivePatchType& patch,
+ UList& allEdgeInfo,
+ UList& allFaceInfo,
+ TrackingData& td = dummyTrackData_
+ );
+
+
+ // Member Functions
+
+ //- Access allEdgeInfo
+ UList& allEdgeInfo() const
+ {
+ return allEdgeInfo_;
+ }
+
+ //- Access allFaceInfo
+ UList& allFaceInfo() const
+ {
+ return allFaceInfo_;
+ }
+
+ //- Additional data to be passed into container
+ const TrackingData& data() const
+ {
+ return td_;
+ }
+
+ //- Get number of unvisited faces, i.e. faces that were not (yet)
+ // reached from walking across patch. This can happen from
+ // - not enough iterations done
+ // - a disconnected patch
+ // - a patch without walls in it
+ label getUnsetFaces() const;
+
+ label getUnsetEdges() const;
+
+ //- Copy initial data into allEdgeInfo_
+ void setEdgeInfo
+ (
+ const labelList& changedEdges,
+ const List& changedEdgesInfo
+ );
+
+ //- Propagate from edge to face. Returns total number of faces
+ // (over all processors) changed.
+ label edgeToFace();
+
+ //- Propagate from face to edge. Returns total number of edges
+ // (over all processors) changed.
+ label faceToEdge();
+
+ //- Iterate until no changes or maxIter reached. Returns actual
+ // number of iterations.
+ label iterate(const label maxIter);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//- Update operation
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData = int
+>
+class updateOp
+{
+ //- Additional data to be passed into container
+ const polyMesh& mesh_;
+ const PrimitivePatchType& patch_;
+ const scalar tol_;
+ TrackingData& td_;
+
+public:
+ updateOp
+ (
+ const polyMesh& mesh,
+ const PrimitivePatchType& patch,
+ const scalar tol,
+ TrackingData& td
+ )
+ :
+ mesh_(mesh),
+ patch_(patch),
+ tol_(tol),
+ td_(td)
+ {}
+
+ void operator()(Type& x, const Type& y) const
+ {
+ if (y.valid(td_))
+ {
+ x.updateEdge(mesh_, patch_, y, true, tol_, td_);
+ }
+ }
+};
+
+
+//- Transform operation
+template
+<
+ class PrimitivePatchType,
+ class Type,
+ class TrackingData = int
+>
+class transformOp
+{
+ //- Additional data to be passed into container
+ const polyMesh& mesh_;
+ const PrimitivePatchType& patch_;
+ const scalar tol_;
+ TrackingData& td_;
+
+public:
+ transformOp
+ (
+ const polyMesh& mesh,
+ const PrimitivePatchType& patch,
+ const scalar tol,
+ TrackingData& td
+ )
+ :
+ mesh_(mesh),
+ patch_(patch),
+ tol_(tol),
+ td_(td)
+ {}
+
+ void operator()
+ (
+ const vectorTensorTransform& vt,
+ const bool forward,
+ List& fld
+ ) const
+ {
+ if (forward)
+ {
+ forAll(fld, i)
+ {
+ fld[i].transform(mesh_, patch_, vt.R(), tol_, td_);
+ }
+ }
+ else
+ {
+ forAll(fld, i)
+ {
+ fld[i].transform(mesh_, patch_, vt.R().T(), tol_, td_);
+ }
+ }
+ }
+};
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+# include "PatchEdgeFaceWave.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C b/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C
new file mode 100644
index 0000000000..4ed5d67570
--- /dev/null
+++ b/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C
@@ -0,0 +1,32 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchEdgeFaceWave.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(Foam::PatchEdgeFaceWaveName, 0);
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.C b/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.C
new file mode 100644
index 0000000000..f6e72fed99
--- /dev/null
+++ b/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.C
@@ -0,0 +1,50 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2011 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "patchEdgeFaceInfo.H"
+
+// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<
+(
+ Foam::Ostream& os,
+ const Foam::patchEdgeFaceInfo& wDist
+)
+{
+ return os << wDist.origin() << wDist.distSqr();
+}
+
+
+Foam::Istream& Foam::operator>>
+(
+ Foam::Istream& is,
+ Foam::patchEdgeFaceInfo& wDist
+)
+{
+ return is >> wDist.origin_ >> wDist.distSqr_;
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.H b/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.H
new file mode 100644
index 0000000000..f02120d7d9
--- /dev/null
+++ b/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.H
@@ -0,0 +1,212 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2011 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 .
+
+Class
+ Foam::patchEdgeFaceInfo
+
+Description
+
+SourceFiles
+ patchEdgeFaceInfoI.H
+ patchEdgeFaceInfo.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef patchEdgeFaceInfo_H
+#define patchEdgeFaceInfo_H
+
+#include "point.H"
+#include "label.H"
+#include "scalar.H"
+#include "tensor.H"
+#include "pTraits.H"
+#include "primitivePatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class polyPatch;
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+ Class patchEdgeFaceInfo Declaration
+\*---------------------------------------------------------------------------*/
+
+class patchEdgeFaceInfo
+{
+ // Private data
+
+ //- position of nearest wall center
+ point origin_;
+
+ //- normal distance (squared) from point to origin
+ scalar distSqr_;
+
+
+ // Private Member Functions
+
+ //- Evaluate distance to point. Update distSqr, origin from whomever
+ // is nearer pt. Return true if w2 is closer to point,
+ // false otherwise.
+ template
+ inline bool update
+ (
+ const point&,
+ const patchEdgeFaceInfo& w2,
+ const scalar tol,
+ TrackingData& td
+ );
+
+ //- Combine current with w2. Update distSqr, origin if w2 has smaller
+ // quantities and returns true.
+ template
+ inline bool update
+ (
+ const patchEdgeFaceInfo& w2,
+ const scalar tol,
+ TrackingData& td
+ );
+
+
+public:
+
+ // Constructors
+
+ //- Construct null
+ inline patchEdgeFaceInfo();
+
+ //- Construct from origin, distance
+ inline patchEdgeFaceInfo(const point&, const scalar);
+
+ //- Construct as copy
+ inline patchEdgeFaceInfo(const patchEdgeFaceInfo&);
+
+
+ // Member Functions
+
+ // Access
+
+ inline const point& origin() const;
+
+ inline scalar distSqr() const;
+
+
+ // Needed by meshWave
+
+ //- Check whether origin has been changed at all or
+ // still contains original (invalid) value.
+ template
+ inline bool valid(TrackingData& td) const;
+
+ //- Apply rotation matrix
+ template
+ inline void transform
+ (
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const tensor& rotTensor,
+ const scalar tol,
+ TrackingData& td
+ );
+
+ //- Influence of face on edge
+ template
+ inline bool updateEdge
+ (
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const label edgeI,
+ const label faceI,
+ const patchEdgeFaceInfo& faceInfo,
+ const scalar tol,
+ TrackingData& td
+ );
+
+ //- New information for edge (from e.g. coupled edge)
+ template
+ inline bool updateEdge
+ (
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const patchEdgeFaceInfo& edgeInfo,
+ const bool sameOrientation,
+ const scalar tol,
+ TrackingData& td
+ );
+
+ //- Influence of edge on face.
+ template
+ inline bool updateFace
+ (
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const label faceI,
+ const label edgeI,
+ const patchEdgeFaceInfo& edgeInfo,
+ const scalar tol,
+ TrackingData& td
+ );
+
+ //- Same (like operator==)
+ template
+ inline bool equal(const patchEdgeFaceInfo&, TrackingData& td) const;
+
+
+ // Member Operators
+
+ // Needed for List IO
+ inline bool operator==(const patchEdgeFaceInfo&) const;
+ inline bool operator!=(const patchEdgeFaceInfo&) const;
+
+
+ // IOstream Operators
+
+ friend Ostream& operator<<(Ostream&, const patchEdgeFaceInfo&);
+ friend Istream& operator>>(Istream&, patchEdgeFaceInfo&);
+};
+
+
+//- Data associated with patchEdgeFaceInfo type are contiguous
+template<>
+inline bool contiguous()
+{
+ return true;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "patchEdgeFaceInfoI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfoI.H b/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfoI.H
new file mode 100644
index 0000000000..881e586626
--- /dev/null
+++ b/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfoI.H
@@ -0,0 +1,268 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2011 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "polyMesh.H"
+#include "transform.H"
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+// Update this with w2 if w2 nearer to pt.
+template
+inline bool Foam::patchEdgeFaceInfo::update
+(
+ const point& pt,
+ const patchEdgeFaceInfo& w2,
+ const scalar tol,
+ TrackingData& td
+)
+{
+ scalar dist2 = magSqr(pt - w2.origin());
+
+ if (!valid(td))
+ {
+ // current not yet set so use any value
+ distSqr_ = dist2;
+ origin_ = w2.origin();
+
+ return true;
+ }
+
+ scalar diff = distSqr_ - dist2;
+
+ if (diff < 0)
+ {
+ // already nearer to pt
+ return false;
+ }
+
+ if ((diff < SMALL) || ((distSqr_ > SMALL) && (diff/distSqr_ < tol)))
+ {
+ // don't propagate small changes
+ return false;
+ }
+ else
+ {
+ // update with new values
+ distSqr_ = dist2;
+ origin_ = w2.origin();
+
+ return true;
+ }
+}
+
+
+// Update this with w2 (information on same edge)
+template
+inline bool Foam::patchEdgeFaceInfo::update
+(
+ const patchEdgeFaceInfo& w2,
+ const scalar tol,
+ TrackingData& td
+)
+{
+ if (!valid(td))
+ {
+ // current not yet set so use any value
+ distSqr_ = w2.distSqr();
+ origin_ = w2.origin();
+
+ return true;
+ }
+
+ scalar diff = distSqr_ - w2.distSqr();
+
+ if (diff < 0)
+ {
+ // already nearer to pt
+ return false;
+ }
+
+ if ((diff < SMALL) || ((distSqr_ > SMALL) && (diff/distSqr_ < tol)))
+ {
+ // don't propagate small changes
+ return false;
+ }
+ else
+ {
+ // update with new values
+ distSqr_ = w2.distSqr();
+ origin_ = w2.origin();
+
+ return true;
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+// Null constructor
+inline Foam::patchEdgeFaceInfo::patchEdgeFaceInfo()
+:
+ origin_(point::max),
+ distSqr_(sqr(GREAT))
+{}
+
+
+// Construct from origin, distance
+inline Foam::patchEdgeFaceInfo::patchEdgeFaceInfo
+(
+ const point& origin,
+ const scalar distSqr
+)
+:
+ origin_(origin),
+ distSqr_(distSqr)
+{}
+
+
+// Construct as copy
+inline Foam::patchEdgeFaceInfo::patchEdgeFaceInfo(const patchEdgeFaceInfo& wpt)
+:
+ origin_(wpt.origin()),
+ distSqr_(wpt.distSqr())
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+inline const Foam::point& Foam::patchEdgeFaceInfo::origin() const
+{
+ return origin_;
+}
+
+
+inline Foam::scalar Foam::patchEdgeFaceInfo::distSqr() const
+{
+ return distSqr_;
+}
+
+
+template
+inline bool Foam::patchEdgeFaceInfo::valid(TrackingData& td) const
+{
+ return origin_ != point::max;
+}
+
+
+template
+inline void Foam::patchEdgeFaceInfo::transform
+(
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const tensor& rotTensor,
+ const scalar tol,
+ TrackingData& td
+)
+{
+ origin_ = Foam::transform(rotTensor, origin_);
+}
+
+
+template
+inline bool Foam::patchEdgeFaceInfo::updateEdge
+(
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const label edgeI,
+ const label faceI,
+ const patchEdgeFaceInfo& faceInfo,
+ const scalar tol,
+ TrackingData& td
+)
+{
+ const edge& e = patch.edges()[edgeI];
+ point eMid =
+ 0.5
+ * (
+ patch.points()[patch.meshPoints()[e[0]]]
+ + patch.points()[patch.meshPoints()[e[1]]]
+ );
+ return update(eMid, faceInfo, tol, td);
+}
+
+
+template
+inline bool Foam::patchEdgeFaceInfo::updateEdge
+(
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const patchEdgeFaceInfo& edgeInfo,
+ const bool sameOrientation,
+ const scalar tol,
+ TrackingData& td
+)
+{
+ return update(edgeInfo, tol, td);
+}
+
+
+template
+inline bool Foam::patchEdgeFaceInfo::updateFace
+(
+ const polyMesh& mesh,
+ const primitivePatch& patch,
+ const label faceI,
+ const label edgeI,
+ const patchEdgeFaceInfo& edgeInfo,
+ const scalar tol,
+ TrackingData& td
+)
+{
+ return update(patch.faceCentres()[faceI], edgeInfo, tol, td);
+}
+
+
+template
+inline bool Foam::patchEdgeFaceInfo::equal
+(
+ const patchEdgeFaceInfo& rhs,
+ TrackingData& td
+) const
+{
+ return operator==(rhs);
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
+
+inline bool Foam::patchEdgeFaceInfo::operator==
+(
+ const Foam::patchEdgeFaceInfo& rhs
+) const
+{
+ return origin() == rhs.origin();
+}
+
+
+inline bool Foam::patchEdgeFaceInfo::operator!=
+(
+ const Foam::patchEdgeFaceInfo& rhs
+) const
+{
+ return !(*this == rhs);
+}
+
+
+// ************************************************************************* //