diff --git a/applications/test/syncTools/Test-syncTools.C b/applications/test/syncTools/Test-syncTools.C index 270a083e24269432b3a45110f523ee405496d970..bdfd2007e863cbc3d75aad1f7a425e775f175e21 100644 --- a/applications/test/syncTools/Test-syncTools.C +++ b/applications/test/syncTools/Test-syncTools.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation ------------------------------------------------------------------------------- @@ -37,6 +37,7 @@ Description #include "Time.H" #include "Random.H" #include "PackedList.H" +#include "flipOp.H" using namespace Foam; @@ -408,7 +409,7 @@ void testPointSync(const polyMesh& mesh, Random& rndGen) { labelList nMasters(mesh.nPoints(), Zero); - bitSet isMasterPoint(syncTools::getMasterPoints(mesh)); + const bitSet isMasterPoint(syncTools::getMasterPoints(mesh)); forAll(isMasterPoint, pointi) { @@ -484,7 +485,7 @@ void testEdgeSync(const polyMesh& mesh, Random& rndGen) { labelList nMasters(edges.size(), Zero); - bitSet isMasterEdge(syncTools::getMasterEdges(mesh)); + const bitSet isMasterEdge(syncTools::getMasterEdges(mesh)); forAll(isMasterEdge, edgeI) { @@ -519,6 +520,252 @@ void testEdgeSync(const polyMesh& mesh, Random& rndGen) } +typedef Pair<point> PointPair; +class edgePointCombineOp +{ +public: + void operator()(PointPair& x, const PointPair& y) const + { + if + ( + (y[0] < x[0]) + || (y[0] == x[0] && y[1] < x[1]) + ) + { + x = y; + } + } +}; +class edgePointTransformOp +{ +public: + void operator() + ( + const vectorTensorTransform& vt, + const bool forward, + List<PointPair>& fld + ) const + { + pointField points0(fld.size()); + pointField points1(fld.size()); + forAll(fld, i) + { + points0[i] = fld[i].first(); + points1[i] = fld[i].second(); + } + + pointField points0New; + pointField points1New; + if (forward) + { + points0New = vt.transformPosition(points0); + points1New = vt.transformPosition(points1); + } + else + { + points0New = vt.invTransformPosition(points0); + points1New = vt.invTransformPosition(points1); + } + + forAll(fld, i) + { + fld[i] = PointPair(points0New[i], points1New[i]); + } + } +}; +class edgePointFlipOp +{ +public: + PointPair operator()(const PointPair& val) const + { + PointPair newVal(val); + newVal.flip(); + return newVal; + } +}; +void testEdgeFlip2(const polyMesh& mesh, Random& rndGen) +{ + Pout<< nl << "Testing edge-wise (oriented) data synchronisation." << endl; + + const edgeList& edges = mesh.edges(); + const pointField& points = mesh.points(); + + // Test position. + + List<PointPair> synEdgeEnds(edges.size()); + { + forAll(synEdgeEnds, edgeI) + { + const edge& e = edges[edgeI]; + synEdgeEnds[edgeI] = PointPair + ( + points[e[0]], + points[e[1]] + ); + } + } + + // 1. Ignore flipping + { + List<PointPair> fld(synEdgeEnds); + + syncTools::syncEdgeList + ( + mesh, + fld, + edgePointCombineOp(), + PointPair(point::max, point::max), + edgePointTransformOp(), + noOp() + ); + + forAll(fld, edgeI) + { + const edge& e = edges[edgeI]; + const PointPair edgeEnd + ( + points[e[0]], + points[e[1]] + ); + + const PointPair& sync = fld[edgeI]; + + if + ( + (mag(edgeEnd[0] - sync[0]) > SMALL) + || (mag(edgeEnd[1] - sync[1]) > SMALL) + ) + { + WarningInFunction + << "Edge " << edgeI + << " original endpoints " << edgeEnd + << " synced endpoints " << sync + << endl; + } + } + } + + // 2. Use flipping operator. Should produce no warnings + { + syncTools::syncEdgeList + ( + mesh, + synEdgeEnds, + edgePointCombineOp(), + PointPair(point::max, point::max), + edgePointTransformOp(), + edgePointFlipOp() + ); + + forAll(synEdgeEnds, edgeI) + { + const edge& e = edges[edgeI]; + const PointPair edgeEnd + ( + points[e[0]], + points[e[1]] + ); + + const PointPair& sync = synEdgeEnds[edgeI]; + + if + ( + (mag(edgeEnd[0] - sync[0]) > SMALL) + || (mag(edgeEnd[1] - sync[1]) > SMALL) + ) + { + FatalErrorInFunction + << "Edge " << edgeI + << " original endpoints " << edgeEnd + << " synced endpoints " << sync + << exit(FatalError); + } + } + } +} + + +void testEdgeFlip(const polyMesh& mesh, Random& rndGen) +{ + Info<< nl << "Testing edge-wise (oriented) data synchronisation." + << endl; + + const edgeList& edges = mesh.edges(); + const pointField& points = mesh.points(); + + // Test vector. + + vectorField synEdgeVecs(edges.size()); + { + forAll(synEdgeVecs, edgeI) + { + synEdgeVecs[edgeI] = edges[edgeI].unitVec(points); + } + } + + // Without flipping (should produce warnings) + { + vectorField fld(synEdgeVecs); + // Ignore flipping + syncTools::syncEdgeList + ( + mesh, + fld, + minEqOp<vector>(), + point::max + ); + + forAll(fld, edgeI) + { + const edge& e = edges[edgeI]; + const vector eVec(e.unitVec(points)); + + if ((eVec & fld[edgeI]) < (1-SMALL)) + { + WarningInFunction + << "Edge " << edgeI + << " at " << e.line(points) + << " original vector " << eVec + << " synced vector " << fld[edgeI] + << " diff:" << (eVec & fld[edgeI]) + << endl; + } + } + } + + + // With consistent flipping. Should never produce difference + { + syncTools::syncEdgeList + ( + mesh, + synEdgeVecs, + minMagSqrEqOp<vector>(), + point::max, + mapDistribute::transform(), + flipOp() + ); + + forAll(synEdgeVecs, edgeI) + { + const edge& e = edges[edgeI]; + const vector eVec(e.unitVec(points)); + + if ((eVec & synEdgeVecs[edgeI]) < (1-SMALL)) + { + FatalErrorInFunction + << "Edge " << edgeI + << " at " << e.line(points) + << " original vector " << eVec + << " synced vector " << synEdgeVecs[edgeI] + << " diff:" << (eVec & synEdgeVecs[edgeI]) + << exit(FatalError); + } + } + } +} + + void testFaceSync(const polyMesh& mesh, Random& rndGen) { Info<< nl << "Testing face-wise data synchronisation." << endl; @@ -553,7 +800,7 @@ void testFaceSync(const polyMesh& mesh, Random& rndGen) { labelList nMasters(mesh.nFaces(), Zero); - bitSet isMasterFace(syncTools::getMasterFaces(mesh)); + const bitSet isMasterFace(syncTools::getMasterFaces(mesh)); forAll(isMasterFace, facei) { @@ -604,6 +851,12 @@ int main(int argc, char *argv[]) // Edge sync testEdgeSync(mesh, rndGen); + // Edge sync and flip + testEdgeFlip(mesh, rndGen); + + // Edge sync and flip of more complex structure + testEdgeFlip2(mesh, rndGen); + // Point sync testPointSync(mesh, rndGen); diff --git a/applications/test/syncTools/block_2x2x1/Allrun b/applications/test/syncTools/block_2x2x1/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..c0d364b068c297597d0b8498e8388f98a0e8b612 --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/Allrun @@ -0,0 +1,17 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh +runApplication decomposePar + +# Swap point 2 and 6 in processor1 +( cd processor1/constant/polyMesh && \ + sed -i -e 's/(1 1 0)/point1/;s/(1 1 2)/(1 1 0)/;s/point1/(1 1 2)/' points && \ + sed -i -e 's/^4\([^2]*\)2/4\1TWO/;s/^4\([^6]*\)6/4\12/;s/TWO/6/' faces \ +) + +runParallel Test-syncTools + +#------------------------------------------------------------------------------ diff --git a/applications/test/syncTools/block_2x2x1/README.txt b/applications/test/syncTools/block_2x2x1/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..16fa0d9e3dd938ec0cbae2813621f2f79a43c661 --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/README.txt @@ -0,0 +1,7 @@ +- blockMesh +- decomposePar +- in processor1: + - swap points 2 (1 1 0) and 6 (1 1 2) in polyMesh/points + - swap indices 2 and 6 in polyMesh/faces + +so now we have the same mesh but different edge orientation on processor1 diff --git a/applications/test/syncTools/block_2x2x1/constant/transportProperties b/applications/test/syncTools/block_2x2x1/constant/transportProperties new file mode 100644 index 0000000000000000000000000000000000000000..fc05a376222c9ce0fd94d4e4134855e949ee5d28 --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/constant/transportProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object transportProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +nu 0.01; + + +// ************************************************************************* // diff --git a/applications/test/syncTools/block_2x2x1/system/blockMeshDict b/applications/test/syncTools/block_2x2x1/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..6666fc0b092a58fb9cf68d97705e9b7fda19a5f1 --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/system/blockMeshDict @@ -0,0 +1,103 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +vertices +( + //- Skewed hexes + //(0 0 0) + //(0.1 0 0) + //(0.2 1 0) + //(0.03 1 0) + //(0 0 0.1) + //(0.1 0 0.1) + //(0.2 1 0.1) + //(0.03 1 0.1) + + ////- Single block + //(0 0 0) + //(4 0 0) + //(4.4 4 0) + //(0.2 4 0) + //(0 0 0.4) + //(4 0 0.4) + //(4.6 4 0.4) + //(0.7 4 0.4) + + //- Single block + (0 0 0) + (2 0 0) + (2 2 0) + (0 2 0) + (0 0 2) + (2 0 2) + (2 2 2) + (0 2 2) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (2 2 1) simpleGrading (1 1 1) +); + +edges +( +); + +boundary +( + topWall + { + type wall; + faces + ( + (3 7 6 2) + ); + } + bottomWall + { + type wall; + faces + ( + (1 5 4 0) + ); + } + fixedWalls + { + type wall; + faces + ( + (0 4 7 3) + (2 6 5 1) + ); + } + frontAndBack + { + type patch; + faces + ( + (0 3 2 1) + (4 5 6 7) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/applications/test/syncTools/block_2x2x1/system/controlDict b/applications/test/syncTools/block_2x2x1/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..f7fc368d3ec3dce246bee04acfd898df08f735c1 --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/system/controlDict @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application icoFoam; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 0.5; + +deltaT 0.005; + +writeControl timeStep; + +writeInterval 20; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 16; + +writeCompression off; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable true; + +// ************************************************************************* // diff --git a/applications/test/syncTools/block_2x2x1/system/decomposeParDict b/applications/test/syncTools/block_2x2x1/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..ac6ac49fa0011322d26adb0165a6d3f98acac29c --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/system/decomposeParDict @@ -0,0 +1,26 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1806 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + note "mesh decomposition control dictionary"; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//- The total number of domains (mandatory) +numberOfSubdomains 4; + +//- The decomposition method (mandatory) +method hierarchical; + +n (2 2 1); + +// ************************************************************************* // diff --git a/applications/test/syncTools/block_2x2x1/system/fvSchemes b/applications/test/syncTools/block_2x2x1/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..9e65bd597658e93fa69212bb055504ff3f4a53ad --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/system/fvSchemes @@ -0,0 +1,51 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; +} + +divSchemes +{ + default none; + div(phi,U) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear orthogonal; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default orthogonal; +} + + +// ************************************************************************* // diff --git a/applications/test/syncTools/block_2x2x1/system/fvSolution b/applications/test/syncTools/block_2x2x1/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..fa297c1118f4b55e8bbdcaffbd0116aea0463b39 --- /dev/null +++ b/applications/test/syncTools/block_2x2x1/system/fvSolution @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + p + { + solver PCG; + preconditioner DIC; + tolerance 1e-06; + relTol 0.05; + } + + pFinal + { + $p; + relTol 0; + } + + U + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-05; + relTol 0; + } +} + +PISO +{ + nCorrectors 2; + nNonOrthogonalCorrectors 0; + pRefCell 0; + pRefValue 0; +} + + +// ************************************************************************* //