openfoam/applications/test/syncTools/Test-syncTools.C

621 lines
16 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
syncToolsTest
Description
Test some functionality in syncTools.
\*---------------------------------------------------------------------------*/
#include "syncTools.H"
#include "argList.H"
#include "polyMesh.H"
#include "Time.H"
#include "Random.H"
#include "PackedList.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void testPackedList(const polyMesh& mesh, Random& rndGen)
{
Info<< nl << "Testing PackedList synchronisation." << endl;
{
PackedList<3> bits(mesh.nEdges());
forAll(bits, i)
{
bits.set(i, rndGen.position<label>(0,3));
}
labelList edgeValues(mesh.nEdges());
forAll(bits, i)
{
edgeValues[i] = bits.get(i);
}
PackedList<3> maxBits(bits);
labelList maxEdgeValues(edgeValues);
syncTools::syncEdgeList(mesh, bits, minEqOp<unsigned int>(), 0);
syncTools::syncEdgeList(mesh, edgeValues, minEqOp<label>(), 0);
syncTools::syncEdgeList(mesh, maxBits, maxEqOp<unsigned int>(), 0);
syncTools::syncEdgeList
(
mesh,
maxEdgeValues,
maxEqOp<label>(),
0
);
forAll(bits, i)
{
if
(
edgeValues[i] != label(bits.get(i))
|| maxEdgeValues[i] != label(maxBits.get(i))
)
{
FatalErrorInFunction
<< "edge:" << i
<< " minlabel:" << edgeValues[i]
<< " minbits:" << bits.get(i)
<< " maxLabel:" << maxEdgeValues[i]
<< " maxBits:" << maxBits.get(i)
<< exit(FatalError);
}
}
}
{
PackedList<3> bits(mesh.nPoints());
forAll(bits, i)
{
bits.set(i, rndGen.position<label>(0,3));
}
labelList pointValues(mesh.nPoints());
forAll(bits, i)
{
pointValues[i] = bits.get(i);
}
PackedList<3> maxBits(bits);
labelList maxPointValues(pointValues);
syncTools::syncPointList(mesh, bits, minEqOp<unsigned int>(), 0);
syncTools::syncPointList(mesh, pointValues, minEqOp<label>(), 0);
syncTools::syncPointList(mesh, maxBits, maxEqOp<unsigned int>(), 0);
syncTools::syncPointList
(
mesh,
maxPointValues,
maxEqOp<label>(),
0
);
forAll(bits, i)
{
if
(
pointValues[i] != label(bits.get(i))
|| maxPointValues[i] != label(maxBits.get(i))
)
{
FatalErrorInFunction
<< "point:" << i
<< " at:" << mesh.points()[i]
<< " minlabel:" << pointValues[i]
<< " minbits:" << bits.get(i)
<< " maxLabel:" << maxPointValues[i]
<< " maxBits:" << maxBits.get(i)
<< exit(FatalError);
}
}
}
{
PackedList<3> bits(mesh.nFaces());
forAll(bits, facei)
{
bits.set(facei, rndGen.position<label>(0,3));
}
labelList faceValues(mesh.nFaces());
forAll(bits, facei)
{
faceValues[facei] = bits.get(facei);
}
PackedList<3> maxBits(bits);
labelList maxFaceValues(faceValues);
syncTools::syncFaceList(mesh, bits, minEqOp<unsigned int>());
syncTools::syncFaceList(mesh, faceValues, minEqOp<label>());
syncTools::syncFaceList(mesh, maxBits, maxEqOp<unsigned int>());
syncTools::syncFaceList(mesh, maxFaceValues, maxEqOp<label>());
forAll(bits, facei)
{
if
(
faceValues[facei] != label(bits.get(facei))
|| maxFaceValues[facei] != label(maxBits.get(facei))
)
{
FatalErrorInFunction
<< "face:" << facei
<< " minlabel:" << faceValues[facei]
<< " minbits:" << bits.get(facei)
<< " maxLabel:" << maxFaceValues[facei]
<< " maxBits:" << maxBits.get(facei)
<< exit(FatalError);
}
}
}
}
void testSparseData(const polyMesh& mesh, Random& rndGen)
{
Info<< nl << "Testing Map synchronisation." << endl;
WarningInFunction
<< "Position test of sparse data only correct for cases without cyclics"
<< " with shared points." << endl;
primitivePatch allBoundary
(
SubList<face>
(
mesh.faces(),
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
),
mesh.points()
);
const pointField& localPoints = allBoundary.localPoints();
// Point data
// ~~~~~~~~~~
{
// Create some data. Use slightly perturbed positions.
Map<point> sparseData;
pointField fullData(mesh.nPoints(), point(GREAT, GREAT, GREAT));
forAll(localPoints, i)
{
const point pt = localPoints[i] + 1e-4*rndGen.sample01<vector>();
label meshPointi = allBoundary.meshPoints()[i];
sparseData.insert(meshPointi, pt);
fullData[meshPointi] = pt;
}
//Pout<< "sparseData:" << sparseData << endl;
syncTools::syncPointMap
(
mesh,
sparseData,
minMagSqrEqOp<point>()
// true // apply separation
);
syncTools::syncPointList
(
mesh,
fullData,
minMagSqrEqOp<point>(),
point(GREAT, GREAT, GREAT)
// true // apply separation
);
// Compare.
// 1. Is all fullData also present in sparseData and same value
forAll(fullData, meshPointi)
{
const point& fullPt = fullData[meshPointi];
if (fullPt != point(GREAT, GREAT, GREAT))
{
const point& sparsePt = sparseData[meshPointi];
if (fullPt != sparsePt)
{
FatalErrorInFunction
<< "point:" << meshPointi
<< " full:" << fullPt
<< " sparse:" << sparsePt
<< exit(FatalError);
}
}
}
// 2. Does sparseData contain more?
forAllConstIter(Map<point>, sparseData, iter)
{
const point& sparsePt = iter();
label meshPointi = iter.key();
const point& fullPt = fullData[meshPointi];
if (fullPt != sparsePt)
{
FatalErrorInFunction
<< "point:" << meshPointi
<< " full:" << fullPt
<< " sparse:" << sparsePt
<< exit(FatalError);
}
}
}
// Edge data
// ~~~~~~~~~
{
// Create some data. Use slightly perturbed positions.
EdgeMap<point> sparseData;
pointField fullData(mesh.nEdges(), point(GREAT, GREAT, GREAT));
const edgeList& edges = allBoundary.edges();
const labelList meshEdges = allBoundary.meshEdges
(
mesh.edges(),
mesh.pointEdges()
);
forAll(edges, i)
{
const edge& e = edges[i];
const point pt =
e.centre(localPoints) + 1e-4*rndGen.sample01<vector>();
label meshEdgeI = meshEdges[i];
sparseData.insert(mesh.edges()[meshEdgeI], pt);
fullData[meshEdgeI] = pt;
}
//Pout<< "sparseData:" << sparseData << endl;
syncTools::syncEdgeMap
(
mesh,
sparseData,
minMagSqrEqOp<point>()
);
syncTools::syncEdgeList
(
mesh,
fullData,
minMagSqrEqOp<point>(),
point(GREAT, GREAT, GREAT)
);
// Compare.
// 1. Is all fullData also present in sparseData and same value
forAll(fullData, meshEdgeI)
{
const point& fullPt = fullData[meshEdgeI];
if (fullPt != point(GREAT, GREAT, GREAT))
{
const point& sparsePt = sparseData[mesh.edges()[meshEdgeI]];
if (fullPt != sparsePt)
{
FatalErrorInFunction
<< "edge:" << meshEdgeI
<< " points:" << mesh.edges()[meshEdgeI]
<< " full:" << fullPt
<< " sparse:" << sparsePt
<< exit(FatalError);
}
}
}
// 2. Does sparseData contain more?
forAll(fullData, meshEdgeI)
{
const edge& e = mesh.edges()[meshEdgeI];
EdgeMap<point>::const_iterator iter = sparseData.find(e);
if (iter != sparseData.end())
{
const point& sparsePt = iter();
const point& fullPt = fullData[meshEdgeI];
if (fullPt != sparsePt)
{
FatalErrorInFunction
<< "Extra edge:" << meshEdgeI
<< " points:" << mesh.edges()[meshEdgeI]
<< " full:" << fullPt
<< " sparse:" << sparsePt
<< exit(FatalError);
}
}
}
}
}
void testPointSync(const polyMesh& mesh, Random& rndGen)
{
Info<< nl << "Testing point-wise data synchronisation." << endl;
// Test position.
{
pointField syncedPoints(mesh.points());
syncTools::syncPointPositions
(
mesh,
syncedPoints,
minMagSqrEqOp<point>(),
point(GREAT, GREAT, GREAT)
);
forAll(syncedPoints, pointi)
{
if (mag(syncedPoints[pointi] - mesh.points()[pointi]) > SMALL)
{
FatalErrorInFunction
<< "Point " << pointi
<< " original location " << mesh.points()[pointi]
<< " synced location " << syncedPoints[pointi]
<< exit(FatalError);
}
}
}
// Test masterPoints
{
labelList nMasters(mesh.nPoints(), 0);
bitSet isMasterPoint(syncTools::getMasterPoints(mesh));
forAll(isMasterPoint, pointi)
{
if (isMasterPoint.test(pointi))
{
nMasters[pointi] = 1;
}
}
syncTools::syncPointList
(
mesh,
nMasters,
plusEqOp<label>(),
0
);
forAll(nMasters, pointi)
{
if (nMasters[pointi] != 1)
{
WarningInFunction
<< "Point " << pointi
<< " original location " << mesh.points()[pointi]
<< " has " << nMasters[pointi]
<< " masters."
<< endl;
}
}
}
}
void testEdgeSync(const polyMesh& mesh, Random& rndGen)
{
Info<< nl << "Testing edge-wise data synchronisation." << endl;
const edgeList& edges = mesh.edges();
// Test position.
{
pointField syncedMids(edges.size());
forAll(syncedMids, edgeI)
{
syncedMids[edgeI] = edges[edgeI].centre(mesh.points());
}
syncTools::syncEdgePositions
(
mesh,
syncedMids,
minMagSqrEqOp<point>(),
point(GREAT, GREAT, GREAT)
);
forAll(syncedMids, edgeI)
{
point eMid = edges[edgeI].centre(mesh.points());
if (mag(syncedMids[edgeI] - eMid) > SMALL)
{
FatalErrorInFunction
<< "Edge " << edgeI
<< " original midpoint " << eMid
<< " synced location " << syncedMids[edgeI]
<< exit(FatalError);
}
}
}
// Test masterEdges
{
labelList nMasters(edges.size(), 0);
bitSet isMasterEdge(syncTools::getMasterEdges(mesh));
forAll(isMasterEdge, edgeI)
{
if (isMasterEdge.test(edgeI))
{
nMasters[edgeI] = 1;
}
}
syncTools::syncEdgeList
(
mesh,
nMasters,
plusEqOp<label>(),
0
);
forAll(nMasters, edgeI)
{
if (nMasters[edgeI] != 1)
{
const edge& e = edges[edgeI];
WarningInFunction
<< "Edge " << edgeI
<< " at:" << mesh.points()[e[0]] << mesh.points()[e[1]]
<< " has " << nMasters[edgeI]
<< " masters."
<< endl;
}
}
}
}
void testFaceSync(const polyMesh& mesh, Random& rndGen)
{
Info<< nl << "Testing face-wise data synchronisation." << endl;
// Test position.
{
pointField syncedFc(mesh.faceCentres());
syncTools::syncFacePositions
(
mesh,
syncedFc,
maxMagSqrEqOp<point>()
);
forAll(syncedFc, facei)
{
if (mag(syncedFc[facei] - mesh.faceCentres()[facei]) > SMALL)
{
FatalErrorInFunction
<< "Face " << facei
<< " original centre " << mesh.faceCentres()[facei]
<< " synced centre " << syncedFc[facei]
<< exit(FatalError);
}
}
}
// Test masterFaces
{
labelList nMasters(mesh.nFaces(), 0);
bitSet isMasterFace(syncTools::getMasterFaces(mesh));
forAll(isMasterFace, facei)
{
if (isMasterFace.test(facei))
{
nMasters[facei] = 1;
}
}
syncTools::syncFaceList
(
mesh,
nMasters,
plusEqOp<label>()
);
forAll(nMasters, facei)
{
if (nMasters[facei] != 1)
{
FatalErrorInFunction
<< "Face " << facei
<< " centre " << mesh.faceCentres()[facei]
<< " has " << nMasters[facei]
<< " masters."
<< exit(FatalError);
}
}
}
}
// Main program:
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createPolyMesh.H"
Random rndGen(5341*(Pstream::myProcNo()+1));
// Face sync
testFaceSync(mesh, rndGen);
// Edge sync
testEdgeSync(mesh, rndGen);
// Point sync
testPointSync(mesh, rndGen);
// PackedList synchronisation
testPackedList(mesh, rndGen);
// Sparse synchronisation
testSparseData(mesh, rndGen);
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //