diff --git a/applications/test/syncTools/missing_cell/Allclean b/applications/test/syncTools/missing_cell/Allclean new file mode 100755 index 0000000000..b44c686537 --- /dev/null +++ b/applications/test/syncTools/missing_cell/Allclean @@ -0,0 +1,11 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase + +# Remove surface and features +rm -rf constant/triSurface + +#------------------------------------------------------------------------------ diff --git a/applications/test/syncTools/missing_cell/Allrun b/applications/test/syncTools/missing_cell/Allrun new file mode 100755 index 0000000000..7404338383 --- /dev/null +++ b/applications/test/syncTools/missing_cell/Allrun @@ -0,0 +1,27 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +#- Generate 2x2x1 cells +runApplication blockMesh + +#- Remove cell0 +runApplication topoSet +runApplication subsetMesh c0 -patch exposed0 -overwrite + +#- Put exposed faces (2) into separate patches +runApplication -s face topoSet +runApplication createPatch -overwrite + +#- Decompose - creates one processor without any faces in patches +runApplication decomposePar + +#- Extract inter-patch points. Should include processor that does not +#- have faces on patch ... +mkdir -p constant/triSurface +runParallel surfaceMeshExtract \ + -patches '(exposed0 exposed1)' -featureAngle 180 \ + constant/triSurface/blockMesh.obj + +#------------------------------------------------------------------------------ diff --git a/applications/test/syncTools/missing_cell/README.txt b/applications/test/syncTools/missing_cell/README.txt new file mode 100644 index 0000000000..776e9a7483 --- /dev/null +++ b/applications/test/syncTools/missing_cell/README.txt @@ -0,0 +1,7 @@ +- 2x2x1 mesh +- remove one cell, exposing two faces +- move exposed faces into two patches +- decompose onto 3 +- run surfaceMeshExtract -featureAngle 180 +- should also mark points on the processor that has no + faces but is coupled diff --git a/applications/test/syncTools/missing_cell/constant/transportProperties b/applications/test/syncTools/missing_cell/constant/transportProperties new file mode 100644 index 0000000000..81751433ad --- /dev/null +++ b/applications/test/syncTools/missing_cell/constant/transportProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: 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/missing_cell/system/blockMeshDict b/applications/test/syncTools/missing_cell/system/blockMeshDict new file mode 100644 index 0000000000..b0b42b9b08 --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/blockMeshDict @@ -0,0 +1,88 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +vertices +( + //- 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) + ); + } + exposed0 + { + type patch; + faces (); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/applications/test/syncTools/missing_cell/system/controlDict b/applications/test/syncTools/missing_cell/system/controlDict new file mode 100644 index 0000000000..67583ffe68 --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/controlDict @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: 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/missing_cell/system/createPatchDict b/applications/test/syncTools/missing_cell/system/createPatchDict new file mode 100644 index 0000000000..2b8eb0d704 --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/createPatchDict @@ -0,0 +1,44 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object createPatchDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +pointSync false; + +// Patches to create. +patches +( + // Example of creating mapped patches using geometric matching + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { + // Name of new patch + name exposed1; + + // Dictionary to construct new patch from + patchInfo + { + type patch; + } + + // How to select the faces: + // - set : specify faceSet in 'set' + // - patches : specify names in 'patches' + // - autoPatch : attempts automatic patching of the specified + // candidates in 'patches'. + constructFrom set; + set exposed0; + } +); + +// ************************************************************************* // diff --git a/applications/test/syncTools/missing_cell/system/decomposeParDict b/applications/test/syncTools/missing_cell/system/decomposeParDict new file mode 100644 index 0000000000..2eb5272d0d --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/decomposeParDict @@ -0,0 +1,24 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: 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 3; + +//- The decomposition method (mandatory) +method scotch; + +// ************************************************************************* // diff --git a/applications/test/syncTools/missing_cell/system/fvSchemes b/applications/test/syncTools/missing_cell/system/fvSchemes new file mode 100644 index 0000000000..51748f98ad --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/fvSchemes @@ -0,0 +1,51 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: 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/missing_cell/system/fvSolution b/applications/test/syncTools/missing_cell/system/fvSolution new file mode 100644 index 0000000000..e19b1d1560 --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/fvSolution @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: 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; +} + + +// ************************************************************************* // diff --git a/applications/test/syncTools/missing_cell/system/topoSetDict b/applications/test/syncTools/missing_cell/system/topoSetDict new file mode 100644 index 0000000000..b58c9dc308 --- /dev/null +++ b/applications/test/syncTools/missing_cell/system/topoSetDict @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2312 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object topoSetDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +actions +( + { + name c0; + type cellSet; + action new; + source labelToCell; + value (0); + } + { + name c0; + type cellSet; + action invert; + } + + { + name exposed0; + type faceSet; + action new; + source patchToFace; + patch exposed0; + } + { + name exposed0; + type faceSet; + action subset; + source boxToFace; + box (-100 1 -100)(100 100 100); + } +); + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C index aed6edfbea..9023c4f164 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C +++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C @@ -99,21 +99,21 @@ label findPatchID(const polyBoundaryMesh& patches, const word& name) } -labelList patchFaces(const polyBoundaryMesh& patches, const wordList& names) +labelList patchFaces(const polyBoundaryMesh& patches, const wordRes& names) { + const labelList patchIDs(patches.indices(names)); + label n = 0; - forAll(names, i) + for (label patchi : patchIDs) { - const polyPatch& pp = patches[findPatchID(patches, names[i])]; - - n += pp.size(); + n += patches[patchi].size(); } labelList faceLabels(n); n = 0; - forAll(names, i) + for (label patchi : patchIDs) { - const polyPatch& pp = patches[findPatchID(patches, names[i])]; + const polyPatch& pp = patches[patchi]; forAll(pp, j) { @@ -128,24 +128,25 @@ labelList patchFaces(const polyBoundaryMesh& patches, const wordList& names) void zoneFaces ( const faceZoneMesh& fzs, - const wordList& names, + const wordRes& names, labelList& faceLabels, bitSet& faceFlip ) { + const labelList zoneIDs(fzs.indices(names)); + label n = 0; - forAll(names, i) + for (label zonei : zoneIDs) { - const auto& pp = fzs[fzs.findZoneID(names[i])]; - n += pp.size(); + n += fzs[zonei].size(); } faceLabels.setSize(n); faceFlip.setSize(n); n = 0; - forAll(names, i) + for (label zonei : zoneIDs) { - const auto& pp = fzs[fzs.findZoneID(names[i])]; + const auto& pp = fzs[zonei]; const boolList& ppFlip = pp.flipMap(); forAll(pp, i) { @@ -345,8 +346,8 @@ int main(int argc, char *argv[]) sourceCaseDir = sourceCaseDir/("processor" + Foam::name(Pstream::myProcNo())); } - wordList sourcePatches; - wordList sourceFaceZones; + wordRes sourcePatches; + wordRes sourceFaceZones; if ( dict.readIfPresent @@ -868,13 +869,13 @@ int main(int argc, char *argv[]) frontPatchFaces = patchFaces ( meshFromSurface().boundaryMesh(), - wordList(1, frontPatchName) + wordRes(1, frontPatchName) ); backPatchName = "otherSide"; backPatchFaces = patchFaces ( meshFromSurface().boundaryMesh(), - wordList(1, backPatchName) + wordRes(1, backPatchName) ); } diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index 2002149f22..2cec08501c 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -825,6 +825,17 @@ int main(int argc, char *argv[]) #include "setSystemMeshDictionaryIO.H" const IOdictionary meshDict(dictIO); + // Overall mesh generation mode + const meshRefinement::MeshType meshType + ( + meshRefinement::MeshTypeNames.getOrDefault + ( + "type", + meshDict, + meshRefinement::CASTELLATED + ) + ); + // all surface geometry const dictionary& geometryDict = @@ -1339,6 +1350,7 @@ int main(int argc, char *argv[]) shells, // for volume (inside/outside) refinement limitShells, // limit of volume refinement labelList(), // initial faces to test + meshType, // how to operate dryRun ); diff --git a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C index 1a195e3600..1b195acc03 100644 --- a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C +++ b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2016-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -220,7 +220,7 @@ PtrList subsetFields const pointMesh& pMesh ) { - const fvMesh& baseMesh = subsetter.baseMesh(); + //const fvMesh& baseMesh = subsetter.baseMesh(); const UPtrList fieldObjects ( @@ -247,8 +247,8 @@ PtrList subsetFields IOobject ( io.name(), - baseMesh.time().timeName(), - baseMesh, + pMesh.thisDb().time().timeName(), + pMesh.thisDb(), IOobjectOption::MUST_READ, IOobjectOption::NO_WRITE, IOobjectOption::NO_REGISTER @@ -382,6 +382,8 @@ int main(int argc, char *argv[]) #include "createTime.H" #include "createNamedMesh.H" + // Make sure pointMesh gets constructed/read as well + (void)pointMesh::New(mesh, IOobject::READ_IF_PRESENT); // arg[1] = word (cellSet) or wordRes (cellZone) // const word selectionName = args[1]; @@ -583,7 +585,7 @@ int main(int argc, char *argv[]) // Read point fields and subset // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - const pointMesh& pMesh = pointMesh::New(mesh); + const pointMesh& pMesh = pointMesh::New(mesh, IOobject::READ_IF_PRESENT); #undef createSubsetFields #define createSubsetFields(FieldType, Variable) \ @@ -663,6 +665,18 @@ int main(int argc, char *argv[]) subsetter.subMesh().write(); processorMeshes::removeFiles(subsetter.subMesh()); + auto* subPointMeshPtr = + subsetter.subMesh().thisDb().findObject + ( + pointMesh::typeName + ); + if (subPointMeshPtr) + { + pointMesh& subPointMesh = const_cast(*subPointMeshPtr); + subPointMesh.setInstance(subsetter.subMesh().facesInstance()); + subPointMesh.write(); + } + // Volume fields for (const auto& fld : vScalarFlds) { fld.write(); } diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index df9c6d9ce2..4322246884 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2022,2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -666,6 +666,9 @@ int main(int argc, char *argv[]) ), decompDictFile ); + // Make sure pointMesh gets read as well + (void)pointMesh::New(mesh, IOobject::READ_IF_PRESENT); + // Decompose the mesh if (!decomposeFieldsOnly) @@ -785,6 +788,7 @@ int main(int argc, char *argv[]) PtrList cellProcAddressingList(mesh.nProcs()); PtrList boundaryProcAddressingList(mesh.nProcs()); PtrList pointProcAddressingList(mesh.nProcs()); + PtrList pointBoundaryProcAddressingList(mesh.nProcs()); PtrList fieldDecomposerList(mesh.nProcs()); PtrList pointFieldDecomposerList @@ -869,7 +873,10 @@ int main(int argc, char *argv[]) // Point fields // ~~~~~~~~~~~~ - const pointMesh& pMesh = pointMesh::New(mesh); + + // Read decomposed pointMesh + const pointMesh& pMesh = + pointMesh::New(mesh, IOobject::READ_IF_PRESENT); pointFieldDecomposer::fieldsCache pointFieldCache; @@ -1138,7 +1145,34 @@ int main(int argc, char *argv[]) pointProcAddressingList ); - const pointMesh& procPMesh = pointMesh::New(procMesh); + const pointMesh& procPMesh = + pointMesh::New(procMesh, IOobject::READ_IF_PRESENT); + + if (!pointBoundaryProcAddressingList.set(proci)) + { + pointBoundaryProcAddressingList.set + ( + proci, + autoPtr::New + ( + IOobject + ( + "boundaryProcAddressing", + procMesh.facesInstance(), + polyMesh::meshSubDir + /pointMesh::meshSubDir, + procPMesh.thisDb(), + IOobject::READ_IF_PRESENT, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + boundaryProcAddressing + ) + ); + } + const auto& pointBoundaryProcAddressing = + pointBoundaryProcAddressingList[proci]; + if (!pointFieldDecomposerList.set(proci)) { @@ -1150,7 +1184,7 @@ int main(int argc, char *argv[]) pMesh, procPMesh, pointProcAddressing, - boundaryProcAddressing + pointBoundaryProcAddressing ) ); } @@ -1162,6 +1196,12 @@ int main(int argc, char *argv[]) if (times.size() == 1) { + // Early deletion + pointBoundaryProcAddressingList.set + ( + proci, + nullptr + ); pointProcAddressingList.set(proci, nullptr); pointFieldDecomposerList.set(proci, nullptr); } diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C index 2158e2a19e..c3d8ca5f8d 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C @@ -44,6 +44,12 @@ License #include "decompositionModel.H" #include "hexRef8Data.H" +// For handling pointMeshes with additional patches +#include "pointMesh.H" +#include "meshPointPatch.H" +#include "processorPointPatch.H" +#include "DynamicField.H" + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::domainDecomposition::mark @@ -740,6 +746,101 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) procMesh.write(); + // Add pointMesh if it was available + const auto* pMeshPtr = + thisDb().cfindObject(pointMesh::typeName); + if (pMeshPtr) + { + const auto& pMesh = *pMeshPtr; + const auto& pMeshBoundary = pMesh.boundary(); + + + // 1. Generate pointBoundaryMesh from polyBoundaryMesh (so ignoring + // any additional patches + const auto& procPointMesh = pointMesh::New(procMesh); + + pointBoundaryMesh& procBoundary = + const_cast(procPointMesh.boundary()); + + + // 2. Explicitly add subsetted meshPointPatches + forAll(pMeshBoundary, patchi) + { + const auto* mppPtr = isA(pMeshBoundary[patchi]); + if (mppPtr && (procBoundary.findPatchID(mppPtr->name()) == -1)) + { + const auto& mpp = *mppPtr; + + DynamicList