From 27d420983963b50e58c6d952bb365eed2995bb2a Mon Sep 17 00:00:00 2001 From: mattijs <mattijs> Date: Mon, 17 Oct 2011 18:31:41 +0100 Subject: [PATCH] ENH: PatchEdgeFaceWave: new wave method --- .../test/PatchEdgeFaceWave/Make/files | 3 + .../test/PatchEdgeFaceWave/Make/options | 7 + .../Test-PatchEdgeFaceWave.C | 132 ++++ .../polyMesh/globalMeshData/globalMeshData.C | 147 ++++ .../polyMesh/globalMeshData/globalMeshData.H | 7 + .../primitiveMesh/PatchTools/PatchTools.C | 1 + .../primitiveMesh/PatchTools/PatchTools.H | 51 ++ .../PatchTools/PatchToolsMatch.C | 137 ++++ src/meshTools/Make/files | 9 +- .../PatchEdgeFaceWave/PatchEdgeFaceWave.C | 681 ++++++++++++++++++ .../PatchEdgeFaceWave/PatchEdgeFaceWave.H | 368 ++++++++++ .../PatchEdgeFaceWave/PatchEdgeFaceWaveName.C | 32 + .../PatchEdgeFaceWave/patchEdgeFaceInfo.C | 50 ++ .../PatchEdgeFaceWave/patchEdgeFaceInfo.H | 212 ++++++ .../PatchEdgeFaceWave/patchEdgeFaceInfoI.H | 268 +++++++ 15 files changed, 2103 insertions(+), 2 deletions(-) create mode 100644 applications/test/PatchEdgeFaceWave/Make/files create mode 100644 applications/test/PatchEdgeFaceWave/Make/options create mode 100644 applications/test/PatchEdgeFaceWave/Test-PatchEdgeFaceWave.C create mode 100644 src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C create mode 100644 src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.C create mode 100644 src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.H create mode 100644 src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C create mode 100644 src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.C create mode 100644 src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.H create mode 100644 src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfoI.H diff --git a/applications/test/PatchEdgeFaceWave/Make/files b/applications/test/PatchEdgeFaceWave/Make/files new file mode 100644 index 00000000000..01051a35533 --- /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 00000000000..d27c95d033d --- /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 00000000000..2dfb19118b2 --- /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 <http://www.gnu.org/licenses/>. + +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<patchEdgeFaceInfo> allEdgeInfo(patch.nEdges()); + List<patchEdgeFaceInfo> allFaceInfo(patch.size()); + + // Initial seed + DynamicList<label> initialEdges; + DynamicList<patchEdgeFaceInfo> 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<label>()) + ); + + + // 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 9800ba6006d..d1b4926e763 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<labelPair> +{ +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<label>() + ); + } + + // 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<labelPair>() + ); + + // 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 3fca52ae976..a3530dc86c3 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 T> class EdgeMap; class globalIndex; class globalIndexAndTransform; +class PackedBoolList; /*---------------------------------------------------------------------------*\ Class globalMeshData Declaration @@ -191,6 +192,7 @@ class globalMeshData mutable autoPtr<globalIndex> globalEdgeNumberingPtr_; mutable autoPtr<labelListList> globalEdgeSlavesPtr_; mutable autoPtr<labelListList> globalEdgeTransformedSlavesPtr_; + mutable autoPtr<PackedBoolList> globalEdgeOrientationPtr_; mutable autoPtr<mapDistribute> 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 4a40eac11aa..793411c162a 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 80e50333bdf..e4ade383ef3 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> class FaceList1, + class PointField1, + class PointType1, + class Face2, + template<class> class FaceList2, + class PointField2, + class PointType2 + > + static void matchPoints + ( + const PrimitivePatch<Face1, FaceList1, PointField1, PointType1>& p1, + const PrimitivePatch<Face2, FaceList2, PointField2, PointType2>& 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> class FaceList1, + class PointField1, + class PointType1, + class Face2, + template<class> class FaceList2, + class PointField2, + class PointType2 + > + static void matchEdges + ( + const PrimitivePatch<Face1, FaceList1, PointField1, PointType1>& p1, + const PrimitivePatch<Face2, FaceList2, PointField2, PointType2>& 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 00000000000..1af68e89912 --- /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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "PatchTools.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template +< + class Face1, + template<class> class FaceList1, + class PointField1, + class PointType1, + class Face2, + template<class> class FaceList2, + class PointField2, + class PointType2 +> +void Foam::PatchTools::matchPoints +( + const PrimitivePatch<Face1, FaceList1, PointField1, PointType1>& p1, + const PrimitivePatch<Face2, FaceList2, PointField2, PointType2>& 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<label>::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> class FaceList1, + class PointField1, + class PointType1, + class Face2, + template<class> class FaceList2, + class PointField2, + class PointType2 +> +void Foam::PatchTools::matchEdges +( + const PrimitivePatch<Face1, FaceList1, PointField1, PointType1>& p1, + const PrimitivePatch<Face2, FaceList2, PointField2, PointType2>& 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<label> 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<label>::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 51be5477869..1c981f47887 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 00000000000..129d82ae12b --- /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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#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<PrimitivePatchType, Type, TrackingData>:: +propagationTol_ = 0.01; + +template +< + class PrimitivePatchType, + class Type, + class TrackingData +> +Foam::label +Foam::PatchEdgeFaceWave<PrimitivePatchType, Type, TrackingData>:: +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<PrimitivePatchType, Type, TrackingData>:: +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<PrimitivePatchType, Type, TrackingData>:: +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<PrimitivePatchType, Type, TrackingData>:: +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<Type> 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<PrimitivePatchType, Type, TrackingData> + ( + mesh_, + patch_, + propagationTol_, + td_ + ), + transformOp<PrimitivePatchType, Type, TrackingData> + ( + 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<PrimitivePatchType, Type, TrackingData>:: +PatchEdgeFaceWave +( + const polyMesh& mesh, + const PrimitivePatchType& patch, + const labelList& changedEdges, + const List<Type>& changedEdgesInfo, + + UList<Type>& allEdgeInfo, + UList<Type>& 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<Type, TrackingData>::PatchEdgeFaceWave" + "(const polyMesh&, const labelList&, const List<Type>," + " List<Type>&, List<Type>&, 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<Type, TrackingData>::PatchEdgeFaceWave" + "(const polyMesh&, const labelList&, const List<Type>," + " List<Type>&, List<Type>&, 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<Type, TrackingData>::PatchEdgeFaceWave" + "(const polyMesh&, const labelList&, const List<Type>," + " List<Type>&, List<Type>&, 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<PrimitivePatchType, Type, TrackingData>:: +PatchEdgeFaceWave +( + const polyMesh& mesh, + const PrimitivePatchType& patch, + UList<Type>& allEdgeInfo, + UList<Type>& 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<PrimitivePatchType, Type, TrackingData>:: +getUnsetEdges() const +{ + return nUnvisitedEdges_; +} + + +template +< + class PrimitivePatchType, + class Type, + class TrackingData +> +Foam::label Foam::PatchEdgeFaceWave<PrimitivePatchType, Type, TrackingData>:: +getUnsetFaces() const +{ + return nUnvisitedFaces_; +} + + +// Copy edge information into member data +template +< + class PrimitivePatchType, + class Type, + class TrackingData +> +void Foam::PatchEdgeFaceWave<PrimitivePatchType, Type, TrackingData>:: +setEdgeInfo +( + const labelList& changedEdges, + const List<Type>& 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<PrimitivePatchType, Type, TrackingData>:: +faceToEdge() +{ + changedEdges_.clear(); + changedEdge_ = false; + + forAll(changedFaces_, changedFaceI) + { + label faceI = changedFaces_[changedFaceI]; + + if (!changedFace_[faceI]) + { + FatalErrorIn("PatchEdgeFaceWave<Type, TrackingData>::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<label>()); +} + + +// Propagate information from edge to face. Return number of faces changed. +template +< + class PrimitivePatchType, + class Type, + class TrackingData +> +Foam::label Foam::PatchEdgeFaceWave<PrimitivePatchType, Type, TrackingData>:: +edgeToFace() +{ + changedFaces_.clear(); + changedFace_ = false; + + const labelListList& edgeFaces = patch_.edgeFaces(); + + forAll(changedEdges_, changedEdgeI) + { + label edgeI = changedEdges_[changedEdgeI]; + + if (!changedEdge_[edgeI]) + { + FatalErrorIn("PatchEdgeFaceWave<Type, TrackingData>::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<label>()); +} + + +// Iterate +template +< + class PrimitivePatchType, + class Type, + class TrackingData +> +Foam::label Foam::PatchEdgeFaceWave<PrimitivePatchType, Type, TrackingData>:: +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 00000000000..1551152c13b --- /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 <http://www.gnu.org/licenses/>. + +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<Type>& allEdgeInfo_; + + //- Information on all patch faces + UList<Type>& allFaceInfo_; + + //- Additional data to be passed into container + TrackingData& td_; + + //- Has edge changed + PackedBoolList changedEdge_; + + //- List of changed edges + DynamicList<label> changedEdges_; + + //- Has face changed + PackedBoolList changedFace_; + + //- List of changed faces + DynamicList<label> 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<Type>& initialEdgesInfo, + UList<Type>& allEdgeInfo, + UList<Type>& 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<Type>& allEdgeInfo, + UList<Type>& allFaceInfo, + TrackingData& td = dummyTrackData_ + ); + + + // Member Functions + + //- Access allEdgeInfo + UList<Type>& allEdgeInfo() const + { + return allEdgeInfo_; + } + + //- Access allFaceInfo + UList<Type>& 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<Type>& 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<Type>& 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 00000000000..4ed5d675709 --- /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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#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 00000000000..f6e72fed998 --- /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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#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 00000000000..f02120d7d9a --- /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 <http://www.gnu.org/licenses/>. + +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<class TrackingData> + 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<class TrackingData> + 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<class TrackingData> + inline bool valid(TrackingData& td) const; + + //- Apply rotation matrix + template<class TrackingData> + inline void transform + ( + const polyMesh& mesh, + const primitivePatch& patch, + const tensor& rotTensor, + const scalar tol, + TrackingData& td + ); + + //- Influence of face on edge + template<class TrackingData> + 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<class TrackingData> + 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<class TrackingData> + 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<class TrackingData> + 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<patchEdgeFaceInfo>() +{ + 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 00000000000..881e586626a --- /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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "polyMesh.H" +#include "transform.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Update this with w2 if w2 nearer to pt. +template<class TrackingData> +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<class TrackingData> +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<class TrackingData> +inline bool Foam::patchEdgeFaceInfo::valid(TrackingData& td) const +{ + return origin_ != point::max; +} + + +template<class TrackingData> +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<class TrackingData> +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<class TrackingData> +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<class TrackingData> +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 <class TrackingData> +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); +} + + +// ************************************************************************* // -- GitLab