ENH: cyclicAMI: handle FaceCellWave (e.g. wall distance)

This commit is contained in:
mattijs
2011-11-15 10:29:59 +00:00
parent 0efe54b50b
commit cf8ad3d936
25 changed files with 479 additions and 205 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,369 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::FaceCellWave
Description
Wave propagation of information through grid. Every iteration
information goes through one layer of cells. Templated on information
that is transferred.
Handles parallel and cyclics and non-parallel cyclics.
Note: whether to propagate depends on the return value of Type::update
which returns true (i.e. propagate) if the value changes by more than a
certain tolerance.
This tolerance can be very strict for normal face-cell and parallel
cyclics (we use a value of 0.01 just to limit propagation of small changes)
but for non-parallel cyclics this tolerance can be critical and if chosen
too small can lead to non-convergence.
SourceFiles
FaceCellWave.C
\*---------------------------------------------------------------------------*/
#ifndef FaceCellWave_H
#define FaceCellWave_H
#include "boolList.H"
#include "labelList.H"
#include "primitiveFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyMesh;
class polyPatch;
/*---------------------------------------------------------------------------*\
Class FaceCellWaveName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(FaceCellWave);
/*---------------------------------------------------------------------------*\
Class FaceCellWave Declaration
\*---------------------------------------------------------------------------*/
template<class Type, class TrackingData = int>
class FaceCellWave
:
public FaceCellWaveName
{
// Private data
//- Reference to mesh
const polyMesh& mesh_;
//- Information for all faces
UList<Type>& allFaceInfo_;
//- Information for all cells
UList<Type>& allCellInfo_;
//- Additional data to be passed into container
TrackingData& td_;
//- Has face changed
boolList changedFace_;
//- List of changed faces
labelList changedFaces_;
//- Number of changed faces
label nChangedFaces_;
// Cells that have changed
boolList changedCell_;
labelList changedCells_;
label nChangedCells_;
//- Contains cyclics
const bool hasCyclicPatches_;
//- Contains cyclicAMI
const bool hasCyclicAMIPatches_;
//- Number of evaluations
label nEvals_;
//- Number of unvisited cells/faces
label nUnvisitedCells_;
label nUnvisitedFaces_;
// Private Member Functions
//- Disallow default bitwise copy construct
FaceCellWave(const FaceCellWave&);
//- Disallow default bitwise assignment
void operator=(const FaceCellWave&);
//- Updates cellInfo with information from neighbour. Updates all
// statistics.
bool updateCell
(
const label cellI,
const label neighbourFaceI,
const Type& neighbourInfo,
const scalar tol,
Type& cellInfo
);
//- Updates faceInfo with information from neighbour. Updates all
// statistics.
bool updateFace
(
const label faceI,
const label neighbourCellI,
const Type& neighbourInfo,
const scalar tol,
Type& faceInfo
);
//- Updates faceInfo with information from same face. Updates all
// statistics.
bool updateFace
(
const label faceI,
const Type& neighbourInfo,
const scalar tol,
Type& faceInfo
);
// Parallel, cyclic
//- Debugging: check info on both sides of cyclic
void checkCyclic(const polyPatch& pPatch) const;
//- Has cyclic patch?
template <class PatchType>
bool hasPatch() const;
//- Merge received patch data into global data
void mergeFaceInfo
(
const polyPatch& patch,
const label nFaces,
const labelList&,
const List<Type>&
);
//- Extract info for single patch only
label getChangedPatchFaces
(
const polyPatch& patch,
const label startFaceI,
const label nFaces,
labelList& changedPatchFaces,
List<Type>& changedPatchFacesInfo
) const;
//- Handle leaving domain. Implementation referred to Type
void leaveDomain
(
const polyPatch& patch,
const label nFaces,
const labelList& faceLabels,
List<Type>& faceInfo
) const;
//- Handle leaving domain. Implementation referred to Type
void enterDomain
(
const polyPatch& patch,
const label nFaces,
const labelList& faceLabels,
List<Type>& faceInfo
) const;
//- Offset face labels by constant value
static void offset
(
const polyPatch& patch,
const label off,
const label nFaces,
labelList& faces
);
//- Apply transformation to Type
void transform
(
const tensorField& rotTensor,
const label nFaces,
List<Type>& faceInfo
);
//- Merge data from across processor boundaries
void handleProcPatches();
//- Merge data from across cyclics
void handleCyclicPatches();
//- Merge data from across AMI cyclics
void handleAMICyclicPatches();
// Private static data
static const scalar geomTol_;
static scalar propagationTol_;
//- Used as default trackdata value to satisfy default template
// argument.
static label dummyTrackData_;
public:
// Static Functions
//- Access to tolerance
static scalar propagationTol()
{
return propagationTol_;
}
//- Change tolerance
static void setPropagationTol(const scalar tol)
{
propagationTol_ = tol;
}
// Constructors
// Construct from mesh. Use setFaceInfo and iterate() to do actual
// calculation.
FaceCellWave
(
const polyMesh&,
UList<Type>& allFaceInfo,
UList<Type>& allCellInfo,
TrackingData& td = dummyTrackData_
);
//- Construct from mesh and list of changed faces with the Type
// for these faces. Iterates until nothing changes or maxIter reached.
// (maxIter can be 0)
FaceCellWave
(
const polyMesh&,
const labelList& initialChangedFaces,
const List<Type>& changedFacesInfo,
UList<Type>& allFaceInfo,
UList<Type>& allCellInfo,
const label maxIter,
TrackingData& td = dummyTrackData_
);
// Member Functions
// Access
//- Access allFaceInfo
UList<Type>& allFaceInfo()
{
return allFaceInfo_;
}
//- Access allCellInfo
UList<Type>& allCellInfo()
{
return allCellInfo_;
}
//- Additional data to be passed into container
const TrackingData& data() const
{
return td_;
}
//- Access mesh
const polyMesh& mesh() const
{
return mesh_;
}
//- Get number of unvisited cells, i.e. cells that were not (yet)
// reached from walking across mesh. This can happen from
// - not enough iterations done
// - a disconnected mesh
// - a mesh without walls in it
label getUnsetCells() const;
//- Get number of unvisited faces
label getUnsetFaces() const;
// Edit
//- Set initial changed faces
void setFaceInfo
(
const labelList& changedFaces,
const List<Type>& changedFacesInfo
);
//- Propagate from face to cell. Returns total number of cells
// (over all processors) changed.
label faceToCell();
//- Propagate from cell to face. Returns total number of faces
// (over all processors) changed. (Faces on processorpatches are
// counted double)
label cellToFace();
//- Iterate until no changes or maxIter reached. Returns actual
// number of iterations.
label iterate(const label maxIter);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "FaceCellWave.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "FaceCellWave.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::FaceCellWaveName, 0);
// ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "MeshWave.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template <class Type, class TrackingData>
Foam::label Foam::MeshWave<Type, TrackingData>::dummyTrackData_ = 12345;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Iterate, propagating changedFacesInfo across mesh, until no change (or
// maxIter reached).
template <class Type, class TrackingData>
Foam::MeshWave<Type, TrackingData>::MeshWave
(
const polyMesh& mesh,
const labelList& changedFaces,
const List<Type>& changedFacesInfo,
const label maxIter,
TrackingData& td
)
:
allFaceInfo_(mesh.nFaces()),
allCellInfo_(mesh.nCells()),
calc_
(
mesh,
changedFaces,
changedFacesInfo,
allFaceInfo_,
allCellInfo_,
maxIter,
td
)
{}
// Iterate, propagating changedFacesInfo across mesh, until no change (or
// maxIter reached). Initial cell values specified.
template <class Type, class TrackingData>
Foam::MeshWave<Type, TrackingData>::MeshWave
(
const polyMesh& mesh,
const labelList& changedFaces,
const List<Type>& changedFacesInfo,
const List<Type>& allCellInfo,
const label maxIter,
TrackingData& td
)
:
allFaceInfo_(mesh.nFaces()),
allCellInfo_(allCellInfo),
calc_
(
mesh,
changedFaces,
changedFacesInfo,
allFaceInfo_,
allCellInfo_,
maxIter,
td
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,177 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::MeshWave
Description
FaceCellWave plus data
SourceFiles
MeshWave.C
\*---------------------------------------------------------------------------*/
#ifndef MeshWave_H
#define MeshWave_H
#include "FaceCellWave.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MeshWaveName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(MeshWave);
/*---------------------------------------------------------------------------*\
Class MeshWave Declaration
\*---------------------------------------------------------------------------*/
template <class Type, class TrackingData = int>
class MeshWave
:
public MeshWaveName
{
// Private data
//- Wall information for all faces
List<Type> allFaceInfo_;
//- Wall information for all cells
List<Type> allCellInfo_;
//- Wave calculation engine.
FaceCellWave<Type, TrackingData> calc_;
// Private Member Functions
//- Disallow default bitwise copy construct
MeshWave(const MeshWave&);
//- Disallow default bitwise assignment
void operator=(const MeshWave&);
// Private static data
//- Used as default trackdata value to satisfy default template
// argument.
static label dummyTrackData_;
public:
// Constructors
//- Construct from mesh and list of changed faces with the Type
// for these faces. Iterates until nothing changes or maxIter reached.
// (maxIter can be 0)
MeshWave
(
const polyMesh& mesh,
const labelList& initialChangedFaces,
const List<Type>& changedFacesInfo,
const label maxIter,
TrackingData& td = dummyTrackData_
);
//- Construct from mesh, list of changed faces with the Type
// for these faces and initial field.
// Iterates until nothing changes or maxIter reached.
// (maxIter can be 0)
MeshWave
(
const polyMesh& mesh,
const labelList& initialChangedFaces,
const List<Type>& changedFacesInfo,
const List<Type>& allCellInfo,
const label maxIter,
TrackingData& td = dummyTrackData_
);
// Member Functions
//- Get allFaceInfo
const List<Type>& allFaceInfo() const
{
return allFaceInfo_;
}
//- Get allCellInfo
const List<Type>& allCellInfo() const
{
return allCellInfo_;
}
//- Additional data to be passed into container
const TrackingData& data() const
{
return calc_.data();
}
//- Iterate until no changes or maxIter reached. Returns actual
// number of iterations.
label iterate(const label maxIter)
{
return calc_.iterate(maxIter);
}
//- Get number of unvisited cells, i.e. cells that were not (yet)
// reached from walking across mesh. This can happen from
// - not enough iterations done
// - a disconnected mesh
// - a mesh without walls in it
label getUnsetCells() const
{
return calc_.getUnsetCells();
}
//- Get number of unvisited faces
label getUnsetFaces() const
{
return calc_.getUnsetFaces();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "MeshWave.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "MeshWave.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::MeshWaveName, 0);
// ************************************************************************* //

View File

@ -0,0 +1,681 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "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;
}
// ************************************************************************* //

View File

@ -0,0 +1,368 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::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
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "PatchEdgeFaceWave.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::PatchEdgeFaceWaveName, 0);
// ************************************************************************* //

View File

@ -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_;
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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);
}
// ************************************************************************* //

View File

@ -0,0 +1,909 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "PointEdgeWave.H"
#include "polyMesh.H"
#include "processorPolyPatch.H"
#include "cyclicPolyPatch.H"
#include "OPstream.H"
#include "IPstream.H"
#include "PstreamCombineReduceOps.H"
#include "debug.H"
#include "typeInfo.H"
#include "globalMeshData.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template <class Type, class TrackingData>
Foam::scalar Foam::PointEdgeWave<Type, TrackingData>::propagationTol_ = 0.01;
template <class Type, class TrackingData>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::dummyTrackData_ = 12345;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Handle leaving domain. Implementation referred to Type
template <class Type, class TrackingData>
void Foam::PointEdgeWave<Type, TrackingData>::leaveDomain
(
const polyPatch& patch,
const labelList& patchPointLabels,
List<Type>& pointInfo
) const
{
const labelList& meshPoints = patch.meshPoints();
forAll(patchPointLabels, i)
{
label patchPointI = patchPointLabels[i];
const point& pt = patch.points()[meshPoints[patchPointI]];
pointInfo[i].leaveDomain(patch, patchPointI, pt, td_);
}
}
// Handle entering domain. Implementation referred to Type
template <class Type, class TrackingData>
void Foam::PointEdgeWave<Type, TrackingData>::enterDomain
(
const polyPatch& patch,
const labelList& patchPointLabels,
List<Type>& pointInfo
) const
{
const labelList& meshPoints = patch.meshPoints();
forAll(patchPointLabels, i)
{
label patchPointI = patchPointLabels[i];
const point& pt = patch.points()[meshPoints[patchPointI]];
pointInfo[i].enterDomain(patch, patchPointI, pt, td_);
}
}
// Transform. Implementation referred to Type
template <class Type, class TrackingData>
void Foam::PointEdgeWave<Type, TrackingData>::transform
(
const polyPatch& patch,
const tensorField& rotTensor,
List<Type>& pointInfo
) const
{
if (rotTensor.size() == 1)
{
const tensor& T = rotTensor[0];
forAll(pointInfo, i)
{
pointInfo[i].transform(T, td_);
}
}
else
{
FatalErrorIn
(
"PointEdgeWave<Type, TrackingData>::transform"
"(const tensorField&, List<Type>&)"
) << "Non-uniform transformation on patch " << patch.name()
<< " not supported for point fields"
<< abort(FatalError);
forAll(pointInfo, i)
{
pointInfo[i].transform(rotTensor[i], td_);
}
}
}
// Update info for pointI, at position pt, with information from
// neighbouring edge.
// Updates:
// - changedPoint_, changedPoints_, nChangedPoints_,
// - statistics: nEvals_, nUnvisitedPoints_
template <class Type, class TrackingData>
bool Foam::PointEdgeWave<Type, TrackingData>::updatePoint
(
const label pointI,
const label neighbourEdgeI,
const Type& neighbourInfo,
Type& pointInfo
)
{
nEvals_++;
bool wasValid = pointInfo.valid(td_);
bool propagate =
pointInfo.updatePoint
(
mesh_,
pointI,
neighbourEdgeI,
neighbourInfo,
propagationTol_,
td_
);
if (propagate)
{
if (!changedPoint_[pointI])
{
changedPoint_[pointI] = true;
changedPoints_[nChangedPoints_++] = pointI;
}
}
if (!wasValid && pointInfo.valid(td_))
{
--nUnvisitedPoints_;
}
return propagate;
}
// Update info for pointI, at position pt, with information from
// same point.
// Updates:
// - changedPoint_, changedPoints_, nChangedPoints_,
// - statistics: nEvals_, nUnvisitedPoints_
template <class Type, class TrackingData>
bool Foam::PointEdgeWave<Type, TrackingData>::updatePoint
(
const label pointI,
const Type& neighbourInfo,
Type& pointInfo
)
{
nEvals_++;
bool wasValid = pointInfo.valid(td_);
bool propagate =
pointInfo.updatePoint
(
mesh_,
pointI,
neighbourInfo,
propagationTol_,
td_
);
if (propagate)
{
if (!changedPoint_[pointI])
{
changedPoint_[pointI] = true;
changedPoints_[nChangedPoints_++] = pointI;
}
}
if (!wasValid && pointInfo.valid(td_))
{
--nUnvisitedPoints_;
}
return propagate;
}
// Update info for edgeI, at position pt, with information from
// neighbouring point.
// Updates:
// - changedEdge_, changedEdges_, nChangedEdges_,
// - statistics: nEvals_, nUnvisitedEdge_
template <class Type, class TrackingData>
bool Foam::PointEdgeWave<Type, TrackingData>::updateEdge
(
const label edgeI,
const label neighbourPointI,
const Type& neighbourInfo,
Type& edgeInfo
)
{
nEvals_++;
bool wasValid = edgeInfo.valid(td_);
bool propagate =
edgeInfo.updateEdge
(
mesh_,
edgeI,
neighbourPointI,
neighbourInfo,
propagationTol_,
td_
);
if (propagate)
{
if (!changedEdge_[edgeI])
{
changedEdge_[edgeI] = true;
changedEdges_[nChangedEdges_++] = edgeI;
}
}
if (!wasValid && edgeInfo.valid(td_))
{
--nUnvisitedEdges_;
}
return propagate;
}
// Check if patches of given type name are present
template <class Type, class TrackingData>
template <class PatchType>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::countPatchType() const
{
label nPatches = 0;
forAll(mesh_.boundaryMesh(), patchI)
{
if (isA<PatchType>(mesh_.boundaryMesh()[patchI]))
{
nPatches++;
}
}
return nPatches;
}
// Transfer all the information to/from neighbouring processors
template <class Type, class TrackingData>
void Foam::PointEdgeWave<Type, TrackingData>::handleProcPatches()
{
// 1. Send all point info on processor patches.
PstreamBuffers pBufs(Pstream::nonBlocking);
DynamicList<Type> patchInfo;
DynamicList<label> thisPoints;
DynamicList<label> nbrPoints;
forAll(mesh_.globalData().processorPatches(), i)
{
label patchI = mesh_.globalData().processorPatches()[i];
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
patchInfo.clear();
patchInfo.reserve(procPatch.nPoints());
thisPoints.clear();
thisPoints.reserve(procPatch.nPoints());
nbrPoints.clear();
nbrPoints.reserve(procPatch.nPoints());
// Get all changed points in reverse order
const labelList& neighbPoints = procPatch.neighbPoints();
forAll(neighbPoints, thisPointI)
{
label meshPointI = procPatch.meshPoints()[thisPointI];
if (changedPoint_[meshPointI])
{
patchInfo.append(allPointInfo_[meshPointI]);
thisPoints.append(thisPointI);
nbrPoints.append(neighbPoints[thisPointI]);
}
}
// Adapt for leaving domain
leaveDomain(procPatch, thisPoints, patchInfo);
if (debug)
{
Pout<< "Processor patch " << patchI << ' ' << procPatch.name()
<< " communicating with " << procPatch.neighbProcNo()
<< " Sending:" << patchInfo.size() << endl;
}
UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
toNeighbour << nbrPoints << patchInfo;
}
pBufs.finishedSends();
//
// 2. Receive all point info on processor patches.
//
forAll(mesh_.globalData().processorPatches(), i)
{
label patchI = mesh_.globalData().processorPatches()[i];
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
List<Type> patchInfo;
labelList patchPoints;
{
UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
fromNeighbour >> patchPoints >> patchInfo;
}
if (debug)
{
Pout<< "Processor patch " << patchI << ' ' << procPatch.name()
<< " communicating with " << procPatch.neighbProcNo()
<< " Received:" << patchInfo.size() << endl;
}
// Apply transform to received data for non-parallel planes
if (!procPatch.parallel())
{
transform(procPatch, procPatch.forwardT(), patchInfo);
}
// Adapt for entering domain
enterDomain(procPatch, patchPoints, patchInfo);
// Merge received info
const labelList& meshPoints = procPatch.meshPoints();
forAll(patchInfo, i)
{
label meshPointI = meshPoints[patchPoints[i]];
if (!allPointInfo_[meshPointI].equal(patchInfo[i], td_))
{
updatePoint
(
meshPointI,
patchInfo[i],
allPointInfo_[meshPointI]
);
}
}
}
//
// 3. Handle all shared points
// (Note:irrespective if changed or not for now)
//
const globalMeshData& pd = mesh_.globalData();
List<Type> sharedData(pd.nGlobalPoints());
forAll(pd.sharedPointLabels(), i)
{
label meshPointI = pd.sharedPointLabels()[i];
// Fill my entries in the shared points
sharedData[pd.sharedPointAddr()[i]] = allPointInfo_[meshPointI];
}
// Combine on master. Reduce operator has to handle a list and call
// Type.updatePoint for all elements
combineReduce(sharedData, listUpdateOp<Type>(propagationTol_, td_));
forAll(pd.sharedPointLabels(), i)
{
label meshPointI = pd.sharedPointLabels()[i];
// Retrieve my entries from the shared points.
const Type& nbrInfo = sharedData[pd.sharedPointAddr()[i]];
if (!allPointInfo_[meshPointI].equal(nbrInfo, td_))
{
updatePoint
(
meshPointI,
nbrInfo,
allPointInfo_[meshPointI]
);
}
}
}
template <class Type, class TrackingData>
void Foam::PointEdgeWave<Type, TrackingData>::handleCyclicPatches()
{
// 1. Send all point info on cyclic patches.
DynamicList<Type> nbrInfo;
DynamicList<label> nbrPoints;
DynamicList<label> thisPoints;
forAll(mesh_.boundaryMesh(), patchI)
{
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
if (isA<cyclicPolyPatch>(patch))
{
const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(patch);
nbrInfo.clear();
nbrInfo.reserve(cycPatch.nPoints());
nbrPoints.clear();
nbrPoints.reserve(cycPatch.nPoints());
thisPoints.clear();
thisPoints.reserve(cycPatch.nPoints());
// Collect nbrPatch points that have changed
{
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
const edgeList& pairs = cycPatch.coupledPoints();
const labelList& meshPoints = nbrPatch.meshPoints();
forAll(pairs, pairI)
{
label thisPointI = pairs[pairI][0];
label nbrPointI = pairs[pairI][1];
label meshPointI = meshPoints[nbrPointI];
if (changedPoint_[meshPointI])
{
nbrInfo.append(allPointInfo_[meshPointI]);
nbrPoints.append(nbrPointI);
thisPoints.append(thisPointI);
}
}
// nbr : adapt for leaving domain
leaveDomain(nbrPatch, nbrPoints, nbrInfo);
}
// Apply rotation for non-parallel planes
if (!cycPatch.parallel())
{
// received data from half1
transform(cycPatch, cycPatch.forwardT(), nbrInfo);
}
if (debug)
{
Pout<< "Cyclic patch " << patchI << ' ' << patch.name()
<< " Changed : " << nbrInfo.size()
<< endl;
}
// Adapt for entering domain
enterDomain(cycPatch, thisPoints, nbrInfo);
// Merge received info
const labelList& meshPoints = cycPatch.meshPoints();
forAll(nbrInfo, i)
{
label meshPointI = meshPoints[thisPoints[i]];
if (!allPointInfo_[meshPointI].equal(nbrInfo[i], td_))
{
updatePoint
(
meshPointI,
nbrInfo[i],
allPointInfo_[meshPointI]
);
}
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Iterate, propagating changedPointsInfo across mesh, until no change (or
// maxIter reached). Initial point values specified.
template <class Type, class TrackingData>
Foam::PointEdgeWave<Type, TrackingData>::PointEdgeWave
(
const polyMesh& mesh,
const labelList& changedPoints,
const List<Type>& changedPointsInfo,
UList<Type>& allPointInfo,
UList<Type>& allEdgeInfo,
const label maxIter,
TrackingData& td
)
:
mesh_(mesh),
allPointInfo_(allPointInfo),
allEdgeInfo_(allEdgeInfo),
td_(td),
changedPoint_(mesh_.nPoints(), false),
changedPoints_(mesh_.nPoints()),
nChangedPoints_(0),
changedEdge_(mesh_.nEdges(), false),
changedEdges_(mesh_.nEdges()),
nChangedEdges_(0),
nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
nEvals_(0),
nUnvisitedPoints_(mesh_.nPoints()),
nUnvisitedEdges_(mesh_.nEdges())
{
if (allPointInfo_.size() != mesh_.nPoints())
{
FatalErrorIn
(
"PointEdgeWave<Type, TrackingData>::PointEdgeWave"
"(const polyMesh&, const labelList&, const List<Type>,"
" List<Type>&, List<Type>&, const label maxIter)"
) << "size of pointInfo work array is not equal to the number"
<< " of points in the mesh" << endl
<< " pointInfo :" << allPointInfo_.size() << endl
<< " mesh.nPoints:" << mesh_.nPoints()
<< exit(FatalError);
}
if (allEdgeInfo_.size() != mesh_.nEdges())
{
FatalErrorIn
(
"PointEdgeWave<Type, TrackingData>::PointEdgeWave"
"(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 mesh" << endl
<< " edgeInfo :" << allEdgeInfo_.size() << endl
<< " mesh.nEdges:" << mesh_.nEdges()
<< exit(FatalError);
}
// Set from initial changed points data
setPointInfo(changedPoints, changedPointsInfo);
if (debug)
{
Pout<< "Seed points : " << nChangedPoints_ << endl;
}
// Iterate until nothing changes
label iter = iterate(maxIter);
if ((maxIter > 0) && (iter >= maxIter))
{
FatalErrorIn
(
"PointEdgeWave<Type, TrackingData>::PointEdgeWave"
"(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
<< " nChangedPoints:" << nChangedPoints_ << endl
<< " nChangedEdges:" << nChangedEdges_ << endl
<< exit(FatalError);
}
}
template <class Type, class TrackingData>
Foam::PointEdgeWave<Type, TrackingData>::PointEdgeWave
(
const polyMesh& mesh,
UList<Type>& allPointInfo,
UList<Type>& allEdgeInfo,
TrackingData& td
)
:
mesh_(mesh),
allPointInfo_(allPointInfo),
allEdgeInfo_(allEdgeInfo),
td_(td),
changedPoint_(mesh_.nPoints(), false),
changedPoints_(mesh_.nPoints()),
nChangedPoints_(0),
changedEdge_(mesh_.nEdges(), false),
changedEdges_(mesh_.nEdges()),
nChangedEdges_(0),
nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
nEvals_(0),
nUnvisitedPoints_(mesh_.nPoints()),
nUnvisitedEdges_(mesh_.nEdges())
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template <class Type, class TrackingData>
Foam::PointEdgeWave<Type, TrackingData>::~PointEdgeWave()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template <class Type, class TrackingData>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::getUnsetPoints() const
{
return nUnvisitedPoints_;
}
template <class Type, class TrackingData>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::getUnsetEdges() const
{
return nUnvisitedEdges_;
}
// Copy point information into member data
template <class Type, class TrackingData>
void Foam::PointEdgeWave<Type, TrackingData>::setPointInfo
(
const labelList& changedPoints,
const List<Type>& changedPointsInfo
)
{
forAll(changedPoints, changedPointI)
{
label pointI = changedPoints[changedPointI];
bool wasValid = allPointInfo_[pointI].valid(td_);
// Copy info for pointI
allPointInfo_[pointI] = changedPointsInfo[changedPointI];
// Maintain count of unset points
if (!wasValid && allPointInfo_[pointI].valid(td_))
{
--nUnvisitedPoints_;
}
// Mark pointI as changed, both on list and on point itself.
if (!changedPoint_[pointI])
{
changedPoint_[pointI] = true;
changedPoints_[nChangedPoints_++] = pointI;
}
}
}
// Propagate information from edge to point. Return number of points changed.
template <class Type, class TrackingData>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::edgeToPoint()
{
for
(
label changedEdgeI = 0;
changedEdgeI < nChangedEdges_;
changedEdgeI++
)
{
label edgeI = changedEdges_[changedEdgeI];
if (!changedEdge_[edgeI])
{
FatalErrorIn("PointEdgeWave<Type, TrackingData>::edgeToPoint()")
<< "edge " << edgeI
<< " not marked as having been changed" << nl
<< "This might be caused by multiple occurences of the same"
<< " seed point." << abort(FatalError);
}
const Type& neighbourWallInfo = allEdgeInfo_[edgeI];
// Evaluate all connected points (= edge endpoints)
const edge& e = mesh_.edges()[edgeI];
forAll(e, eI)
{
Type& currentWallInfo = allPointInfo_[e[eI]];
if (!currentWallInfo.equal(neighbourWallInfo, td_))
{
updatePoint
(
e[eI],
edgeI,
neighbourWallInfo,
currentWallInfo
);
}
}
// Reset status of edge
changedEdge_[edgeI] = false;
}
// Handled all changed edges by now
nChangedEdges_ = 0;
if (nCyclicPatches_ > 0)
{
// Transfer changed points across cyclic halves
handleCyclicPatches();
}
if (Pstream::parRun())
{
// Transfer changed points from neighbouring processors.
handleProcPatches();
}
if (debug)
{
Pout<< "Changed points : " << nChangedPoints_ << endl;
}
// Sum nChangedPoints over all procs
label totNChanged = nChangedPoints_;
reduce(totNChanged, sumOp<label>());
return totNChanged;
}
// Propagate information from point to edge. Return number of edges changed.
template <class Type, class TrackingData>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::pointToEdge()
{
const labelListList& pointEdges = mesh_.pointEdges();
for
(
label changedPointI = 0;
changedPointI < nChangedPoints_;
changedPointI++
)
{
label pointI = changedPoints_[changedPointI];
if (!changedPoint_[pointI])
{
FatalErrorIn("PointEdgeWave<Type, TrackingData>::pointToEdge()")
<< "Point " << pointI
<< " not marked as having been changed" << nl
<< "This might be caused by multiple occurences of the same"
<< " seed point." << abort(FatalError);
}
const Type& neighbourWallInfo = allPointInfo_[pointI];
// Evaluate all connected edges
const labelList& edgeLabels = pointEdges[pointI];
forAll(edgeLabels, edgeLabelI)
{
label edgeI = edgeLabels[edgeLabelI];
Type& currentWallInfo = allEdgeInfo_[edgeI];
if (!currentWallInfo.equal(neighbourWallInfo, td_))
{
updateEdge
(
edgeI,
pointI,
neighbourWallInfo,
currentWallInfo
);
}
}
// Reset status of point
changedPoint_[pointI] = false;
}
// Handled all changed points by now
nChangedPoints_ = 0;
if (debug)
{
Pout<< "Changed edges : " << nChangedEdges_ << endl;
}
// Sum nChangedPoints over all procs
label totNChanged = nChangedEdges_;
reduce(totNChanged, sumOp<label>());
return totNChanged;
}
// Iterate
template <class Type, class TrackingData>
Foam::label Foam::PointEdgeWave<Type, TrackingData>::iterate
(
const label maxIter
)
{
if (nCyclicPatches_ > 0)
{
// Transfer changed points across cyclic halves
handleCyclicPatches();
}
if (Pstream::parRun())
{
// Transfer changed points from neighbouring processors.
handleProcPatches();
}
nEvals_ = 0;
label iter = 0;
while (iter < maxIter)
{
if (debug)
{
Pout<< "Iteration " << iter << endl;
}
label nEdges = pointToEdge();
if (debug)
{
Pout<< "Total changed edges : " << nEdges << endl;
}
if (nEdges == 0)
{
break;
}
label nPoints = edgeToPoint();
if (debug)
{
Pout<< "Total changed points : " << nPoints << endl;
Pout<< "Total evaluations : " << nEvals_ << endl;
Pout<< "Remaining unvisited points: " << nUnvisitedPoints_ << endl;
Pout<< "Remaining unvisited edges : " << nUnvisitedEdges_ << endl;
Pout<< endl;
}
if (nPoints == 0)
{
break;
}
iter++;
}
return iter;
}
// ************************************************************************* //

View File

@ -0,0 +1,364 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::PointEdgeWave
Description
Wave propagation of information through grid. Every iteration
information goes through one layer of edges. Templated on information
that is transferred.
Templated on information that is transferred.
Handles parallel and cyclics. Only parallel reasonably tested. Cyclics
hardly tested.
Note: whether to propagate depends on the return value of Type::update
which returns true (i.e. propagate) if the value changes by more than a
certain tolerance.
Note: parallel is done in two steps:
-# transfer patch points in offset notation, i.e. every patch
point is denoted by a patchface label and an index in this face.
Receiving end uses that fact that f[0] is shared and order is
reversed.
-# do all non-local shared points by means of reduce of data on them.
Note: cyclics is with offset in patchface as well. Patch is divided into
two sub patches and the point-point addressing is never explicitly
calculated but instead use is made of the face-face correspondence.
(it probably is more efficient to calculate a point-point
correspondence at the start and then reuse this; task to be done)
SourceFiles
PointEdgeWave.C
\*---------------------------------------------------------------------------*/
#ifndef PointEdgeWave_H
#define PointEdgeWave_H
#include "boolList.H"
#include "scalarField.H"
#include "tensorField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyMesh;
class polyPatch;
/*---------------------------------------------------------------------------*\
Class PointEdgeWaveName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(PointEdgeWave);
/*---------------------------------------------------------------------------*\
Class PointEdgeWave Declaration
\*---------------------------------------------------------------------------*/
template <class Type, class TrackingData = int>
class PointEdgeWave
:
public PointEdgeWaveName
{
// 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_;
//- Wall information for all points
UList<Type>& allPointInfo_;
//- Information on all mesh edges
UList<Type>& allEdgeInfo_;
//- Additional data to be passed into container
TrackingData& td_;
//- Has point changed
boolList changedPoint_;
//- List of changed points
labelList changedPoints_;
//- Number of changed points
label nChangedPoints_;
//- Edges that have changed
boolList changedEdge_;
labelList changedEdges_;
label nChangedEdges_;
//- Number of cyclic patches
label nCyclicPatches_;
//- Number of evaluations
label nEvals_;
//- Number of unvisited edges/points
label nUnvisitedPoints_;
label nUnvisitedEdges_;
// Private Member Functions
//- Adapt pointInfo for leaving domain
void leaveDomain
(
const polyPatch&,
const List<label>& patchPointLabels,
List<Type>& pointInfo
) const;
//- Adapt pointInfo for entering domain
void enterDomain
(
const polyPatch&,
const List<label>& patchPointLabels,
List<Type>& pointInfo
) const;
//- Transform. Implementation referred to Type
void transform
(
const polyPatch& patch,
const tensorField& rotTensor,
List<Type>& pointInfo
) const;
//- Updates pointInfo with information from neighbour. Updates all
// statistics.
bool updatePoint
(
const label pointI,
const label neighbourEdgeI,
const Type& neighbourInfo,
Type& pointInfo
);
//- Updates pointInfo with information from same point. Updates all
// statistics.
bool updatePoint
(
const label pointI,
const Type& neighbourInfo,
Type& pointInfo
);
//- Updates edgeInfo with information from neighbour. Updates all
// statistics.
bool updateEdge
(
const label edgeI,
const label neighbourPointI,
const Type& neighbourInfo,
Type& edgeInfo
);
// Parallel, cyclic
//- Has patches of certain type?
template <class PatchType>
label countPatchType() const;
//- Merge data from across processor boundaries
void handleProcPatches();
//- Merge data from across cyclic boundaries
void handleCyclicPatches();
//- Disallow default bitwise copy construct
PointEdgeWave(const PointEdgeWave&);
//- Disallow default bitwise assignment
void operator=(const PointEdgeWave&);
public:
// Static Functions
//- Access to tolerance
static scalar propagationTol()
{
return propagationTol_;
}
//- Change tolerance
static void setPropagationTol(const scalar tol)
{
propagationTol_ = tol;
}
// Constructors
//- Construct from mesh, list of changed points with the Type
// for these points. Gets work arrays to operate on, one of size
// number of mesh points, the other number of mesh edges.
// Iterates until nothing changes or maxIter reached.
// (maxIter can be 0)
PointEdgeWave
(
const polyMesh& mesh,
const labelList& initialPoints,
const List<Type>& initialPointsInfo,
UList<Type>& allPointInfo,
UList<Type>& allEdgeInfo,
const label maxIter,
TrackingData& td = dummyTrackData_
);
//- Construct from mesh. Use setPointInfo and iterate() to do
// actual calculation
PointEdgeWave
(
const polyMesh& mesh,
UList<Type>& allPointInfo,
UList<Type>& allEdgeInfo,
TrackingData& td = dummyTrackData_
);
//- Destructor
~PointEdgeWave();
// Member Functions
//- Access allPointInfo
UList<Type>& allPointInfo() const
{
return allPointInfo_;
}
//- Access allEdgeInfo
UList<Type>& allEdgeInfo() const
{
return allEdgeInfo_;
}
//- Additional data to be passed into container
const TrackingData& data() const
{
return td_;
}
//- Get number of unvisited edges, i.e. edges that were not (yet)
// reached from walking across mesh. This can happen from
// - not enough iterations done
// - a disconnected mesh
// - a mesh without walls in it
label getUnsetEdges() const;
label getUnsetPoints() const;
//- Copy initial data into allPointInfo_
void setPointInfo
(
const labelList& changedPoints,
const List<Type>& changedPointsInfo
);
//- Propagate from point to edge. Returns total number of edges
// (over all processors) changed.
label pointToEdge();
//- Propagate from edge to point. Returns total number of points
// (over all processors) changed.
label edgeToPoint();
//- Iterate until no changes or maxIter reached. Returns actual
// number of iterations.
label iterate(const label maxIter);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
/*---------------------------------------------------------------------------*\
Class listUpdateOp Declaration
\*---------------------------------------------------------------------------*/
//- List update operation
template <class Type, class TrackingData = int>
class listUpdateOp
{
//- Additional data to be passed into container
const scalar tol_;
TrackingData& td_;
public:
listUpdateOp(const scalar tol, TrackingData& td)
:
tol_(tol),
td_(td)
{}
void operator()(List<Type>& x, const List<Type>& y) const
{
forAll(x, i)
{
if (y[i].valid(td_))
{
x[i].updatePoint(y[i], tol_, td_);
}
}
}
};
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "PointEdgeWave.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "PointEdgeWave.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::PointEdgeWaveName, 0);
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "pointEdgePoint.H"
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Foam::Ostream& os,
const Foam::pointEdgePoint& wDist
)
{
return os << wDist.origin() << wDist.distSqr();
}
Foam::Istream& Foam::operator>>(Foam::Istream& is, Foam::pointEdgePoint& wDist)
{
return is >> wDist.origin_ >> wDist.distSqr_;
}
// ************************************************************************* //

View File

@ -0,0 +1,249 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::pointEdgePoint
Description
Holds information regarding nearest wall point. Used in pointEdgeWave.
(so not standard meshWave)
To be used in wall distance calculation.
SourceFiles
pointEdgePointI.H
pointEdgePoint.C
\*---------------------------------------------------------------------------*/
#ifndef pointEdgePoint_H
#define pointEdgePoint_H
#include "point.H"
#include "label.H"
#include "scalar.H"
#include "tensor.H"
#include "pTraits.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class polyPatch;
class polyMesh;
/*---------------------------------------------------------------------------*\
Class pointEdgePoint Declaration
\*---------------------------------------------------------------------------*/
class pointEdgePoint
{
// 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 pointEdgePoint& 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 pointEdgePoint& w2,
const scalar tol,
TrackingData& td
);
public:
// Constructors
//- Construct null
inline pointEdgePoint();
//- Construct from origin, distance
inline pointEdgePoint(const point&, const scalar);
//- Construct as copy
inline pointEdgePoint(const pointEdgePoint&);
// 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;
//- Check for identical geometrical data. Used for cyclics checking.
template<class TrackingData>
inline bool sameGeometry
(
const pointEdgePoint&,
const scalar tol,
TrackingData& td
) const;
//- Convert origin to relative vector to leaving point
// (= point coordinate)
template<class TrackingData>
inline void leaveDomain
(
const polyPatch& patch,
const label patchPointI,
const point& pos,
TrackingData& td
);
//- Convert relative origin to absolute by adding entering point
template<class TrackingData>
inline void enterDomain
(
const polyPatch& patch,
const label patchPointI,
const point& pos,
TrackingData& td
);
//- Apply rotation matrix to origin
template<class TrackingData>
inline void transform
(
const tensor& rotTensor,
TrackingData& td
);
//- Influence of edge on point
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointI,
const label edgeI,
const pointEdgePoint& edgeInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// Merge new and old info.
template<class TrackingData>
inline bool updatePoint
(
const polyMesh& mesh,
const label pointI,
const pointEdgePoint& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of different value on same point.
// No information about current position whatsoever.
template<class TrackingData>
inline bool updatePoint
(
const pointEdgePoint& newPointInfo,
const scalar tol,
TrackingData& td
);
//- Influence of point on edge.
template<class TrackingData>
inline bool updateEdge
(
const polyMesh& mesh,
const label edgeI,
const label pointI,
const pointEdgePoint& pointInfo,
const scalar tol,
TrackingData& td
);
//- Same (like operator==)
template<class TrackingData>
inline bool equal(const pointEdgePoint&, TrackingData& td) const;
// Member Operators
// Needed for List IO
inline bool operator==(const pointEdgePoint&) const;
inline bool operator!=(const pointEdgePoint&) const;
// IOstream Operators
friend Ostream& operator<<(Ostream&, const pointEdgePoint&);
friend Istream& operator>>(Istream&, pointEdgePoint&);
};
//- Data associated with pointEdgePoint type are contiguous
template<>
inline bool contiguous<pointEdgePoint>()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "pointEdgePointI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,326 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::pointEdgePoint::update
(
const point& pt,
const pointEdgePoint& 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 point)
template<class TrackingData>
inline bool Foam::pointEdgePoint::update
(
const pointEdgePoint& 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::pointEdgePoint::pointEdgePoint()
:
origin_(point::max),
distSqr_(GREAT)
{}
// Construct from origin, distance
inline Foam::pointEdgePoint::pointEdgePoint
(
const point& origin,
const scalar distSqr
)
:
origin_(origin),
distSqr_(distSqr)
{}
// Construct as copy
inline Foam::pointEdgePoint::pointEdgePoint(const pointEdgePoint& wpt)
:
origin_(wpt.origin()),
distSqr_(wpt.distSqr())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::point& Foam::pointEdgePoint::origin() const
{
return origin_;
}
inline Foam::scalar Foam::pointEdgePoint::distSqr() const
{
return distSqr_;
}
template<class TrackingData>
inline bool Foam::pointEdgePoint::valid(TrackingData& td) const
{
return origin_ != point::max;
}
// Checks for cyclic points
template<class TrackingData>
inline bool Foam::pointEdgePoint::sameGeometry
(
const pointEdgePoint& w2,
const scalar tol,
TrackingData& td
) const
{
scalar diff = Foam::mag(distSqr() - w2.distSqr());
if (diff < SMALL)
{
return true;
}
else
{
if ((distSqr() > SMALL) && ((diff/distSqr()) < tol))
{
return true;
}
else
{
return false;
}
}
}
template<class TrackingData>
inline void Foam::pointEdgePoint::leaveDomain
(
const polyPatch& patch,
const label patchPointI,
const point& coord,
TrackingData& td
)
{
origin_ -= coord;
}
template<class TrackingData>
inline void Foam::pointEdgePoint::transform
(
const tensor& rotTensor,
TrackingData& td
)
{
origin_ = Foam::transform(rotTensor, origin_);
}
// Update absolute geometric quantities. Note that distance (distSqr_)
// is not affected by leaving/entering domain.
template<class TrackingData>
inline void Foam::pointEdgePoint::enterDomain
(
const polyPatch& patch,
const label patchPointI,
const point& coord,
TrackingData& td
)
{
// back to absolute form
origin_ += coord;
}
// Update this with information from connected edge
template<class TrackingData>
inline bool Foam::pointEdgePoint::updatePoint
(
const polyMesh& mesh,
const label pointI,
const label edgeI,
const pointEdgePoint& edgeInfo,
const scalar tol,
TrackingData& td
)
{
return update(mesh.points()[pointI], edgeInfo, tol, td);
}
// Update this with new information on same point
template<class TrackingData>
inline bool Foam::pointEdgePoint::updatePoint
(
const polyMesh& mesh,
const label pointI,
const pointEdgePoint& newPointInfo,
const scalar tol,
TrackingData& td
)
{
return update(mesh.points()[pointI], newPointInfo, tol, td);
}
// Update this with new information on same point. No extra information.
template<class TrackingData>
inline bool Foam::pointEdgePoint::updatePoint
(
const pointEdgePoint& newPointInfo,
const scalar tol,
TrackingData& td
)
{
return update(newPointInfo, tol, td);
}
// Update this with information from connected point
template<class TrackingData>
inline bool Foam::pointEdgePoint::updateEdge
(
const polyMesh& mesh,
const label edgeI,
const label pointI,
const pointEdgePoint& pointInfo,
const scalar tol,
TrackingData& td
)
{
const edge& e = mesh.edges()[edgeI];
return update(e.centre(mesh.points()), pointInfo, tol, td);
}
template <class TrackingData>
inline bool Foam::pointEdgePoint::equal
(
const pointEdgePoint& rhs,
TrackingData& td
) const
{
return operator==(rhs);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::pointEdgePoint::operator==(const Foam::pointEdgePoint& rhs)
const
{
return origin() == rhs.origin();
}
inline bool Foam::pointEdgePoint::operator!=(const Foam::pointEdgePoint& rhs)
const
{
return !(*this == rhs);
}
// ************************************************************************* //