From b5435cc83e9c219219743bcc51b3d8a4aefbc89a Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 17 Apr 2024 14:27:25 +0200 Subject: [PATCH] ENH: separate registry and revised file locations for finite-area - The internal storage location of finite-area changes from being piggybacked on the polyMesh registry to a having its own dedicated registry: * allows a clearer separation of field types without name clashes. * prerequisite for supporting multiple finite-area regions (future) Old Locations: ``` 0/Us constant/faMesh system/faMeshDefinition system/faSchemes system/faSolution ``` New Locations: ``` 0/finite-area/Us constant/finite-area/faMesh system/finite-area/faMeshDefinition (or system/faMeshDefinition) system/finite-area/faSchemes system/finite-area/faSolution ``` NOTES: The new locations represent a hard change (breaking change) that is normally to be avoided, but seamless compatibility handling within the code was found to be unworkable. The `foamUpgradeFiniteArea` script provides assistance with migration. As a convenience, the system/faMeshDefinition location continues to be supported (may be deprecated in the future). --- applications/test/faMesh-try/Make/files | 3 + applications/test/faMesh-try/Make/options | 7 + .../test/faMesh-try/Test-faMesh-try.cxx | 63 +++ applications/test/faMeshesRegistry/Make/files | 3 + .../test/faMeshesRegistry/Make/options | 7 + .../Test-faMeshesRegistry.cxx | 68 +++ .../finiteArea/checkFaMesh/checkFaMesh.C | 6 +- .../finiteArea/makeFaMesh/decomposeFaFields.H | 8 +- .../makeFaMesh/findMeshDefinitionDict.H | 42 +- .../finiteArea/makeFaMesh/makeFaMesh.C | 12 +- .../decomposePar/decomposePar.C | 36 +- .../reconstructPar/reconstructPar.C | 32 +- .../redistributePar/redistributePar.C | 21 +- .../foamToEnsight/checkFieldAvailability.H | 51 ++- .../foamToEnsight/convertAreaFields.H | 6 +- .../foamToEnsight/foamToEnsight.C | 14 + .../foamToEnsight/getTimeIndex.H | 2 +- .../dataConversion/foamToEnsight/readFields.C | 13 +- .../dataConversion/foamToEnsight/readFields.H | 5 +- .../foamToVTK/convertAreaFields.H | 6 +- .../dataConversion/foamToVTK/foamToVTK.C | 17 +- bin/foamUpgradeFiniteArea | 322 +++++++++++++ .../interfaceTrackingFvMesh.C | 2 +- src/finiteArea/Make/files | 2 + src/finiteArea/faMesh/faMesh.C | 423 +++++++++++++++--- src/finiteArea/faMesh/faMesh.H | 226 ++++++++-- src/finiteArea/faMesh/faMeshI.H | 9 +- src/finiteArea/faMesh/faMeshNew.C | 115 +++-- src/finiteArea/faMesh/faMeshRegistry.C | 76 ++++ .../faMesh/faMeshTools/faMeshTools.C | 26 +- .../faMesh/faMeshTools/faMeshTools.H | 5 +- src/finiteArea/faMesh/faMeshesRegistry.C | 100 +++++ src/finiteArea/faMesh/faMeshesRegistry.H | 194 ++++++++ .../shape/surface/sensitivitySurface.C | 126 +++--- .../curvatureSeparation/curvatureSeparation.C | 114 ++--- 35 files changed, 1812 insertions(+), 350 deletions(-) create mode 100644 applications/test/faMesh-try/Make/files create mode 100644 applications/test/faMesh-try/Make/options create mode 100644 applications/test/faMesh-try/Test-faMesh-try.cxx create mode 100644 applications/test/faMeshesRegistry/Make/files create mode 100644 applications/test/faMeshesRegistry/Make/options create mode 100644 applications/test/faMeshesRegistry/Test-faMeshesRegistry.cxx create mode 100755 bin/foamUpgradeFiniteArea create mode 100644 src/finiteArea/faMesh/faMeshRegistry.C create mode 100644 src/finiteArea/faMesh/faMeshesRegistry.C create mode 100644 src/finiteArea/faMesh/faMeshesRegistry.H diff --git a/applications/test/faMesh-try/Make/files b/applications/test/faMesh-try/Make/files new file mode 100644 index 0000000000..30a5d9b42e --- /dev/null +++ b/applications/test/faMesh-try/Make/files @@ -0,0 +1,3 @@ +Test-faMesh-try.cxx + +EXE = $(FOAM_USER_APPBIN)/Test-faMesh-try diff --git a/applications/test/faMesh-try/Make/options b/applications/test/faMesh-try/Make/options new file mode 100644 index 0000000000..b5b735e54b --- /dev/null +++ b/applications/test/faMesh-try/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteArea \ + -lmeshTools diff --git a/applications/test/faMesh-try/Test-faMesh-try.cxx b/applications/test/faMesh-try/Test-faMesh-try.cxx new file mode 100644 index 0000000000..783870b06e --- /dev/null +++ b/applications/test/faMesh-try/Test-faMesh-try.cxx @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 . + +Application + Test-faMesh-try + +Description + Test for loading of faMesh + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "faMesh.H" +#include "polyMesh.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + #include "addRegionOption.H" + #include "addFaRegionOption.H" + #include "setRootCase.H" + + #include "createTime.H" + #include "createNamedPolyMesh.H" + + #include "getFaRegionOption.H" + + autoPtr aMeshPtr = faMesh::TryNew(areaRegionName, mesh); + + Info<< "area-mesh: " << Switch::name(aMeshPtr) << nl; + + Info<< "\nEnd\n" << nl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/faMeshesRegistry/Make/files b/applications/test/faMeshesRegistry/Make/files new file mode 100644 index 0000000000..c393033c0b --- /dev/null +++ b/applications/test/faMeshesRegistry/Make/files @@ -0,0 +1,3 @@ +Test-faMeshesRegistry.cxx + +EXE = $(FOAM_USER_APPBIN)/Test-faMeshesRegistry diff --git a/applications/test/faMeshesRegistry/Make/options b/applications/test/faMeshesRegistry/Make/options new file mode 100644 index 0000000000..b5b735e54b --- /dev/null +++ b/applications/test/faMeshesRegistry/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteArea \ + -lmeshTools diff --git a/applications/test/faMeshesRegistry/Test-faMeshesRegistry.cxx b/applications/test/faMeshesRegistry/Test-faMeshesRegistry.cxx new file mode 100644 index 0000000000..d58ffdad32 --- /dev/null +++ b/applications/test/faMeshesRegistry/Test-faMeshesRegistry.cxx @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 . + +Application + Test-faMeshesRegistry + +Description + Basic tests for faMeshesRegistry + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "faMesh.H" +#include "faMeshesRegistry.H" +#include "polyMesh.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + + #include "createTime.H" + #include "createPolyMesh.H" + + Info<< "mesh 0: " << mesh.sortedNames() << nl; + + faMeshesRegistry& reg = + const_cast(faMeshesRegistry::New(mesh)); + + // faMeshesRegistry faReg = faMeshesRegistry(mesh); + + faMesh mesh1(mesh, Foam::zero{}); + faMesh mesh2("mesh2", mesh, Foam::zero{}); + + reg.write(); + + Info<< "\nEnd\n" << nl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/finiteArea/checkFaMesh/checkFaMesh.C b/applications/utilities/finiteArea/checkFaMesh/checkFaMesh.C index a31468da21..e335c087b7 100644 --- a/applications/utilities/finiteArea/checkFaMesh/checkFaMesh.C +++ b/applications/utilities/finiteArea/checkFaMesh/checkFaMesh.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2021-2022 OpenCFD Ltd. + Copyright (C) 2021-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) ); #include "addRegionOption.H" + #include "addFaRegionOption.H" #include "setRootCase.H" #include "createTime.H" #include "createNamedPolyMesh.H" @@ -90,8 +91,7 @@ int main(int argc, char *argv[]) faMesh::geometryOrder(geometryOrder); } - // Create - faMesh aMesh(mesh); + #include "createNamedFaMesh.H" Info<< "Time = " << runTime.timeName() << nl << endl; diff --git a/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H b/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H index 1e60c422d7..e7110f47fb 100644 --- a/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H +++ b/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H @@ -70,7 +70,13 @@ do const bool oldParRun = UPstream::parRun(false); - objects = IOobjectList(serialMesh.time(), runTime.timeName()); + objects = IOobjectList + ( + serialMesh.time(), + runTime.timeName(), + serialMesh.dbDir(), + IOobjectOption::NO_REGISTER + ); UPstream::parRun(oldParRun); } diff --git a/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H b/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H index e1638a77ee..80b2b65770 100644 --- a/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H +++ b/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2021-2022 OpenCFD Ltd. + Copyright (C) 2021-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM, distributed under GPL-3.0-or-later. @@ -18,7 +18,8 @@ Required Classes - Foam::IOdictionary Required Variables - - regionName [word] + - regionName [word] (the polyMesh region) + - areaRegionName [word] (the areaMesh region) - args [argList] - runTime [Time] @@ -35,6 +36,7 @@ autoPtr meshDictPtr; { fileName dictPath; const word& regionDir = Foam::polyMesh::regionName(regionName); + const word& areaRegionDir = Foam::polyMesh::regionName(areaRegionName); if (args.readIfPresent("dict", dictPath)) { @@ -47,38 +49,30 @@ autoPtr meshDictPtr; } else if ( - // Check global location - exists + // Dictionary under system/faMeshDefinition ? + // (v2312 and earlier) + + areaRegionDir.empty() + && exists ( - runTime.path()/runTime.caseConstant() + runTime.path()/runTime.caseSystem() / regionDir/faMesh::meshSubDir/dictName ) ) { - // Dictionary present in constant faMesh directory (old-style) + // Dictionary present directly in system/ (v2312 and earlier) - dictPath = - ( - runTime.constant() - / regionDir/faMesh::meshSubDir/dictName - ); - - // Warn that constant/faMesh/faMeshDefinition was used - // instead of system/faMeshDefinition - #if 0 - WarningIn(args.executable()) - << "Using the old faMeshDefinition location: " - << dictPath << nl - << " instead of default location: " - << runTime.system()/regionDir/dictName << nl - << endl; - #endif + dictPath = runTime.system()/regionDir/dictName; } else { - // Assume dictionary is in the system directory + // Use system/finite-area/ directory, with region qualifications - dictPath = runTime.system()/regionDir/dictName; + dictPath = + ( + runTime.system()/regionDir + / faMesh::prefix()/areaRegionDir/dictName + ); } IOobject meshDictIO diff --git a/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C b/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C index 21be51ee46..91d74391e0 100644 --- a/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C +++ b/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C @@ -104,10 +104,13 @@ int main(int argc, char *argv[]) ); #include "addRegionOption.H" + #include "addFaRegionOption.H" #include "setRootCase.H" #include "createTime.H" #include "createNamedPolyMesh.H" + #include "getFaRegionOption.H" + const bool doDecompose = !args.found("no-decompose"); const bool doDecompFields = !args.found("no-fields"); @@ -133,8 +136,15 @@ int main(int argc, char *argv[]) // Preliminary checks #include "checkPatchTopology.H" + Info << "Create areaMesh"; + if (!Foam::polyMesh::regionName(areaRegionName).empty()) + { + Foam::Info << ' ' << areaRegionName; + } + Info << " for polyMesh at time = " << runTime.timeName() << nl; + // Create - faMesh aMesh(mesh, meshDefDict); + faMesh aMesh(areaRegionName, mesh, meshDefDict); // Mesh information (less verbose) faMeshTools::printMeshChecks(aMesh, 0); diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 7676ec50d1..1309cac153 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -173,7 +173,7 @@ namespace Foam // Uses polyMesh/fvMesh meshSubDir by default autoPtr procAddressing ( - const fvMesh& procMesh, + const objectRegistry& procRegistry, const word& name, const word& instance, const word& local = fvMesh::meshSubDir @@ -186,7 +186,7 @@ autoPtr procAddressing name, instance, local, - procMesh, + procRegistry, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER @@ -199,13 +199,13 @@ autoPtr procAddressing // Uses the finiteArea meshSubDir autoPtr faProcAddressing ( - const fvMesh& procMesh, + const objectRegistry& procRegistry, const word& name, const word& instance, const word& local = faMesh::meshSubDir ) { - return procAddressing(procMesh, name, instance, local); + return procAddressing(procRegistry, name, instance, local); } @@ -797,11 +797,22 @@ int main(int argc, char *argv[]) // Field objects at this time IOobjectList objects; + IOobjectList faObjects; if (doDecompFields) { + // List of volume mesh objects for this instance objects = IOobjectList(mesh, runTime.timeName()); + // List of area mesh objects (assuming single region) + faObjects = IOobjectList + ( + mesh.time(), + runTime.timeName(), + faMesh::dbDir(mesh, word::null), + IOobjectOption::NO_REGISTER + ); + // Ignore generated fields: (cellDist) objects.remove("cellDist"); } @@ -810,12 +821,15 @@ int main(int argc, char *argv[]) autoPtr faMeshDecompPtr; if (doFiniteArea) { + const word boundaryInst = + mesh.time().findInstance(mesh.meshDir(), "boundary"); + IOobject io ( "faBoundary", - mesh.time().findInstance(mesh.meshDir(), "boundary"), - faMesh::meshSubDir, - mesh, + boundaryInst, + faMesh::meshDir(mesh, word::null), + mesh.time(), IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER @@ -1225,7 +1239,7 @@ int main(int argc, char *argv[]) if (doDecompFields) { - areaFieldCache.readAllFields(aMesh, objects); + areaFieldCache.readAllFields(aMesh, faObjects); } const label nAreaFields = areaFieldCache.size(); @@ -1293,7 +1307,7 @@ int main(int argc, char *argv[]) autoPtr tfaceProcAddr = faProcAddressing ( - procFvMesh, + procMesh, "faceProcAddressing", runTime.constant() ); @@ -1302,7 +1316,7 @@ int main(int argc, char *argv[]) autoPtr tboundaryProcAddr = faProcAddressing ( - procFvMesh, + procMesh, "boundaryProcAddressing", runTime.constant() ); @@ -1311,7 +1325,7 @@ int main(int argc, char *argv[]) autoPtr tedgeProcAddr = faProcAddressing ( - procFvMesh, + procMesh, "edgeProcAddressing", runTime.constant() ); diff --git a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C index 0dd1078dd0..4d2910373d 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C +++ b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C @@ -382,9 +382,25 @@ int main(int argc, char *argv[]) IOobjectList objects ( procMeshes.meshes()[0], - databases[0].timeName() + databases[0].timeName(), + IOobjectOption::NO_REGISTER ); + IOobjectList faObjects; + + if (doFiniteArea && doFields) + { + // List of area mesh objects (assuming single region) + // - scan on processor0 + faObjects = IOobjectList + ( + procMeshes.meshes()[0], + databases[0].timeName(), + faMesh::dbDir(word::null), // local relative to mesh + IOobjectOption::NO_REGISTER + ); + } + if (doFields) { // If there are any FV fields, reconstruct them @@ -545,12 +561,12 @@ int main(int argc, char *argv[]) } else if ( - objects.count() - || objects.count() - || objects.count() - || objects.count() - || objects.count() - || objects.count() + faObjects.count() + || faObjects.count() + || faObjects.count() + || faObjects.count() + || faObjects.count() + || faObjects.count() ) { Info << "Reconstructing FA fields" << nl << endl; @@ -568,7 +584,7 @@ int main(int argc, char *argv[]) procFaMeshes.boundaryProcAddressing() ); - reconstructor.reconstructAllFields(objects); + reconstructor.reconstructAllFields(faObjects); } else { diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C index 23d62c2652..305ec95aca 100644 --- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C +++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C @@ -102,6 +102,7 @@ Usage #include "faMeshSubset.H" #include "faMeshTools.H" #include "faMeshDistributor.H" +#include "faMeshesRegistry.H" #include "parFaFieldDistributorCache.H" #include "redistributeLagrangian.H" @@ -906,12 +907,26 @@ autoPtr redistributeAndWrite } + // If faMeshesRegistry exists, it is also owned by the polyMesh and will + // be destroyed by clearGeom() in fvMeshDistribute::distribute() + // + // Rescue faMeshesRegistry from destruction by temporarily moving + // it to be locally owned. + std::unique_ptr faMeshesRegistry_saved + ( + faMeshesRegistry::Release(mesh) + ); + // Mesh distribution engine fvMeshDistribute distributor(mesh); // Do all the distribution of mesh and fields autoPtr distMap = distributor.distribute(decomp); + // Restore ownership onto the polyMesh + faMeshesRegistry::Store(std::move(faMeshesRegistry_saved)); + + // Print some statistics InfoOrPout<< "After distribution:" << endl; printMeshData(mesh); @@ -1598,7 +1613,8 @@ int main(int argc, char *argv[]) ); const fileName areaMeshSubDir ( - polyMesh::regionName(regionName) / faMesh::meshSubDir + // Assume single-region area mesh + faMesh::meshDir(regionName, word::null) ); InfoOrPout @@ -2501,7 +2517,8 @@ int main(int argc, char *argv[]) ); const fileName areaMeshSubDir ( - polyMesh::regionName(regionName) / faMesh::meshSubDir + // Assume single-region area mesh + faMesh::meshDir(regionName, word::null) ); InfoOrPout diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkFieldAvailability.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkFieldAvailability.H index a51456de2d..b9adb4990a 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkFieldAvailability.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkFieldAvailability.H @@ -21,29 +21,38 @@ Requires // Initially all possible objects that are available at the final time List availableRegionObjectNames(meshes.size()); +List availableFaRegionObjectNames(meshes.size()); forAll(meshes, regioni) { const auto& mesh = meshes[regioni]; IOobjectList objects; + IOobjectList faObjects; if (doConvertFields && !timeDirs.empty()) { + // List of volume mesh objects for this instance objects = IOobjectList(mesh, timeDirs.back().name()); - if (fieldSelector && !fieldSelector().empty()) - { - objects.filterObjects(fieldSelector()); - } + // List of area mesh objects (assuming single region) + faObjects = IOobjectList + ( + mesh.time(), + timeDirs.back().name(), + faMesh::dbDir(mesh, word::null), + IOobjectOption::NO_REGISTER + ); if (fieldSelector && !fieldSelector().empty()) { objects.filterObjects(fieldSelector()); + faObjects.filterObjects(fieldSelector()); } // Remove "*_0" restart fields objects.prune_0(); + faObjects.prune_0(); if (!doPointValues) { @@ -59,12 +68,38 @@ forAll(meshes, regioni) } } - wordList objectNames(objects.sortedNames()); + // Volume fields + if (!objects.empty()) + { + wordList objectNames(objects.sortedNames()); - // Check availability for all times... - checkData(mesh, timeDirs, objectNames); + // Check availability for all times... + checkData + ( + mesh.thisDb(), + timeDirs, + objectNames + ); - availableRegionObjectNames[regioni] = objectNames; + availableRegionObjectNames[regioni] = objectNames; + } + + // Area fields + if (!faObjects.empty()) + { + wordList objectNames(faObjects.sortedNames()); + + // Check availability for all times... (assuming single region) + checkData + ( + mesh.time(), + timeDirs, + objectNames, + faMesh::dbDir(mesh, word::null) + ); + + availableFaRegionObjectNames[regioni] = objectNames; + } } diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertAreaFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertAreaFields.H index 5f2ef2455f..ad2cc77187 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertAreaFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertAreaFields.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2021 OpenCFD Ltd. + Copyright (C) 2021-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM, distributed under GPL-3.0-or-later. @@ -14,6 +14,8 @@ Description Code chunk for converting area fields included by foamToEnsight. + Possible objects to convert are given in faObjects + \*---------------------------------------------------------------------------*/ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -23,7 +25,7 @@ if (doFiniteArea && ensFaCasePtr && ensFaMeshPtr) { Info<< " area field ("; - writeAllAreaFields(*ensFaCasePtr, *ensFaMeshPtr, objects); + writeAllAreaFields(*ensFaCasePtr, *ensFaMeshPtr, faObjects); Info<< " )" << nl; } diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index d47e941ee0..c9b6456ba1 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -577,6 +577,20 @@ int main(int argc, char *argv[]) // Volume, internal, point fields #include "convertVolumeFields.H" + // The finite-area objects at this time + IOobjectList faObjects; + + if (ensFaMeshPtr) + { + faObjects = + IOobjectList(ensFaMeshPtr->mesh(), runTime.timeName()); + + faObjects.filterObjects + ( + availableFaRegionObjectNames[regioni] + ); + } + // The finiteArea fields #include "convertAreaFields.H" diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/getTimeIndex.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/getTimeIndex.H index 5fa3c329c1..224ef692aa 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/getTimeIndex.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/getTimeIndex.H @@ -55,7 +55,7 @@ label timeIndex = 0; else { goodTimeIndex = false; - Info<< "skip ... missing entry " << io.objectPath() << endl; + Info<< "skip ... missing file: " << io.objectRelPath() << endl; } } diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C index a9e92f80ad..0d895f9e8a 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2022 OpenCFD Ltd. + Copyright (C) 2018-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,9 +32,10 @@ License Foam::label Foam::checkData ( - const fvMesh& mesh, + const objectRegistry& obr, const instantList& timeDirs, - wordList& objectNames + wordList& objectNames, + const fileName& local ) { // Assume prune_0() was used prior to calling this @@ -43,6 +44,9 @@ Foam::label Foam::checkData for (const word& fieldName : objectNames) { + // // If prune_0() not previously used... + // if (objectNames.ends_with("_0")) continue; + bool good = false; for (const instant& inst : timeDirs) @@ -52,7 +56,8 @@ Foam::label Foam::checkData ( fieldName, inst.name(), - mesh, + local, + obr, IOobject::NO_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.H index eee09efd9e..716e5134f6 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.H @@ -164,9 +164,10 @@ tmp> makeZeroGradientField // ignore fields that are not available for all time-steps label checkData ( - const fvMesh& mesh, + const objectRegistry& obr, const instantList& timeDirs, - wordList& objectNames + wordList& objectNames, + const fileName& local = fileName::null ); diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/convertAreaFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/convertAreaFields.H index 7d8f467ab7..766ffb7f6c 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/convertAreaFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/convertAreaFields.H @@ -29,7 +29,7 @@ if (doFiniteArea) autoPtr faMeshPtr; const label nAreaFields = - objects.count(stringListOps::foundOp(fieldTypes::area)); + faObjects.count(stringListOps::foundOp(fieldTypes::area)); if (nAreaFields || withMeshIds) { @@ -40,7 +40,7 @@ if (doFiniteArea) { const faMesh& areaMesh = faMeshPtr(); - reportFields::area(Info, objects); + reportFields::area(Info, faObjects); const auto& pp = faMeshPtr->patch(); @@ -97,7 +97,7 @@ if (doFiniteArea) ( writer, areaMesh, - objects, + faObjects, true // syncPar ); diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C index b831277343..ca7782f713 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -781,20 +781,33 @@ int main(int argc, char *argv[]) } IOobjectList objects; + IOobjectList faObjects; if (doConvertFields) { - // List of objects for this time + // List of volume mesh objects for this instance objects = IOobjectList(meshProxy.baseMesh(), runTime.timeName()); + // List of area mesh objects (assuming single region) + faObjects = + IOobjectList + ( + runTime, + runTime.timeName(), + faMesh::dbDir(meshProxy.baseMesh(), word::null), + IOobjectOption::NO_REGISTER + ); + if (fieldSelector && !fieldSelector().empty()) { objects.filterObjects(fieldSelector()); + faObjects.filterObjects(fieldSelector()); } // Remove "*_0" restart fields objects.prune_0(); + faObjects.prune_0(); if (!doPointValues) { diff --git a/bin/foamUpgradeFiniteArea b/bin/foamUpgradeFiniteArea new file mode 100755 index 0000000000..f481f47b5f --- /dev/null +++ b/bin/foamUpgradeFiniteArea @@ -0,0 +1,322 @@ +#!/bin/bash +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | www.openfoam.com +# \\/ M anipulation | +#------------------------------------------------------------------------------ +# Copyright (C) 2023-2024 OpenCFD Ltd. +#------------------------------------------------------------------------------ +# License +# This file is part of OpenFOAM, distributed under GPL-3.0-or-later. +# +# Script +# foamUpgradeFiniteArea +# +# Description +# Relocate finite-area files to new sub-directory locations +# +#------------------------------------------------------------------------------ +printHelp() { + cat <&2 + echo + echo "Error encountered:" + while [ "$#" -ge 1 ]; do echo " $1"; shift; done + echo + echo "See '${0##*/} -help' for usage" + echo + exit 1 +} + +#------------------------------------------------------------------------------ + +# Parse options +unset caseDir optDryRun optGit optVerbose optLink optMeshDef hadError + +while [ "$#" -gt 0 ] +do + case "$1" in + (- | --) + shift + break # Stop option parsing + ;; + (-h | -help*) printHelp ;; + + (-n | -dry-run) optDryRun="(dry-run) " ;; + (-v | -verbose) optVerbose=true ;; + (-f | -force) echo "Ignored option: ${1%%=*}" 1>&2 ;; + (-link-back) optLink=back ;; +# (-link-only) optLink=forward ;; + (-no-mesh) optMeshDef=false ;; + (-git) optGit=true ;; + + (-case=*) + caseDir="${1#*=}" + ;; + (-case) + caseDir="$2" + [ "$#" -ge 2 ] || die "'$1' option requires an argument" + shift + ;; + + (-*) die "unknown option: $1" ;; + (*) die "unknown argument: $1" ;; + + esac + shift +done + +if [ -n "$caseDir" ] +then + cd "$caseDir" 2>/dev/null || { + echo "${0##*/}: No such directory $caseDir" 1>&2 + exit 2 + } +fi + +#------------------------------------------------------------------------------ + +# Proper umask +umask 022 + +# The commands +copy_cmd="cp -a${optVerbose:+ -v}" +move_cmd="mv${optVerbose:+ -v}" +link_cmd="ln -sf${optVerbose:+ -v}" +mkdir_cmd="mkdir -p" + +if [ -n "$optDryRun" ] +then + if [ -n "$optVerbose" ] + then + copy_cmd="echo cp -a" + move_cmd="echo mv" + link_cmd="echo ln -sf" + mkdir_cmd="echo mkdir -p" + else + copy_cmd=true + move_cmd=true + link_cmd=true + mkdir_cmd=true + fi +elif [ -n "$optGit" ] +then + move_cmd="git mv" + link_cmd="echo no symlink for git:" +fi + +regionDir="finite-area" + +#------------------------------------------------------------------------------ +# Various script parts +# +# awk : scan file for FoamFile { ... class NAME; } + +read -d '' getClass_awk << 'AWK_CONTENT' +BEGIN { state = 0 } # 0=begin, 1=header, 2=done + +/FoamFile/ { if (!state) { state = 1; next; } exit; } + +# FoamFile begin contents +/\{/ { if (state == 1) state = 2; next; } + +# FoamFile end contents +/\}/ { if (state == 2) exit; next; } + +/^[ ]*class[ ]/ { + if (state == 2) + { + sub("^[ ]*class[ ]+", "") + sub("[ ;]*$", "") + print + exit + } + next +} +AWK_CONTENT + + +# Check for FoamFile and return extracted 'class' +getFoamFile_class() +{ + local file="$1" + local class + + if grep -q FoamFile "$file" 2>/dev/null + then + # class="$(foamDictionary -disableFunctionEntries -entry FoamFile/class -value "$file" 2> stderr)" + class="$(awk -- "$getClass_awk" "$file")" + fi + echo "$class" +} + + +# Check if class corresponds to an finite-area field +# eg, areaScalarField, ... edgeVectorField +isAreaFieldClass() +{ + case "$1" in + (area*Field | edge*Field) return 0 ;; + esac + + return 1 +} + + +#------------------------------------------------------------------------------ + +#Debug# getFoamFile_class "system/faSchemes" + +#------------------------------------------------------------------------------ + +# Link back from the local finite-area/ directory to the current directory +# variables +# - regionDir = "finite-area" +# +performLinkBack() +{ + local file + + if [ -d "$regionDir" ] + then + find "$regionDir" -maxdepth 1 -type f 2>/dev/null | while read file + do + file="${file#*/}" + + if [ -f "$regionDir/$file" ] && [ ! -f "$file" ] + then + echo "${optDryRun} ln -s $regionDir/$file $file" 1>&2 + $link_cmd "$regionDir/$file" "$file" + fi + done + fi +} + + +# Move from current directory to local finite-area/ directory +# variables +# - regionDir = "finite-area" +# +performMove() +{ + local file="$1" + + if [ -f "$regionDir/$file" ] + then + echo "${optDryRun} already: $regionDir/$file" 1>&2 + elif [ -f "$file" ] + then + $mkdir_cmd "$regionDir" + echo "${optDryRun} mv $file -> $regionDir/" 1>&2 + $move_cmd "$file" "$regionDir/$file" + elif [ -n "$file" ] + then + echo "${optDryRun} no $file" 1>&2 + fi +} + + +#------------------------------------------------------------------------------ + +# system +# ---- +if [ -d system ] +then +( + cd system || exit + currDir="system" + + echo "${optDryRun}Examining files in $currDir/" 1>&2 + + performMove faSchemes + performMove faSolution + + if [ "$optMeshDef" = false ] + then + echo "${optDryRun} ignore: faMeshDefinition" 1>&2 + else + performMove faMeshDefinition + fi + + if [ -d "$regionDir" ] && [ "$optLink" = back ] + then + performLinkBack + fi +) +else + echo "${optDryRun}No system/ directory..." 1>&2 +fi + + +#------------------------------------------------------------------------------ + +# time dirs (initial conditions) +# ---- + +for timeDir in 0 0.orig +do + if [ -d "$timeDir" ] + then + ( + cd "$timeDir" || exit + currDir="$timeDir" + + echo "${optDryRun}Examining $currDir/" 1>&2 + + find . -maxdepth 1 -type f | while read file + do + file="${file#*/}" + + case "$file" in + (*.gz) + echo "${optDryRun} ignoring compressed file: $file" 1>&2 + continue + ;; + esac + + className="$(getFoamFile_class "$file")" + + if isAreaFieldClass "$className" + then + performMove "$file" + fi + done + + if [ -d "$regionDir" ] && [ "$optLink" = back ] + then + performLinkBack + fi + ) + else + echo "${optDryRun}No $timeDir/ directory..." 1>&2 + fi +done + + +#------------------------------------------------------------------------------ diff --git a/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C b/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C index bc97ae9c80..015aa57571 100644 --- a/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C +++ b/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C @@ -512,7 +512,7 @@ void Foam::interfaceTrackingFvMesh::makeBulkSurfactConc() const mesh().time().startTime().value() ), // mesh().time().timeName(), - aMesh().thisDb(), + mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ), diff --git a/src/finiteArea/Make/files b/src/finiteArea/Make/files index 803c8df34f..c318012d21 100644 --- a/src/finiteArea/Make/files +++ b/src/finiteArea/Make/files @@ -1,4 +1,6 @@ faMesh/faGlobalMeshData/faGlobalMeshData.C +faMesh/faMeshesRegistry.C +faMesh/faMeshRegistry.C faMesh/faMesh.C faMesh/faMeshNew.C faMesh/faMeshDemandDrivenData.C diff --git a/src/finiteArea/faMesh/faMesh.C b/src/finiteArea/faMesh/faMesh.C index 49c518363d..1770da3b1e 100644 --- a/src/finiteArea/faMesh/faMesh.C +++ b/src/finiteArea/faMesh/faMesh.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2020-2023 OpenCFD Ltd. + Copyright (C) 2020-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -61,29 +61,135 @@ namespace Foam } -const Foam::word Foam::faMesh::prefix("finite-area"); +const Foam::word Foam::faMesh::prefix_("finite-area"); -Foam::word Foam::faMesh::meshSubDir = "faMesh"; +Foam::word Foam::faMesh::meshSubDir("faMesh"); const int Foam::faMesh::quadricsFit_ = 0; // Tuning (experimental) // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // +const Foam::word& Foam::faMesh::prefix() noexcept +{ + return prefix_; +} + + +Foam::fileName Foam::faMesh::dbDir(const word& areaRegion) +{ + if (areaRegion.empty() || areaRegion == polyMesh::defaultRegion) + { + return faMesh::prefix(); + } + + return (faMesh::prefix() / areaRegion); +} + + +Foam::fileName Foam::faMesh::dbDir +( + const word& volRegion, + const word& areaRegion +) +{ + return + ( + polyMesh::regionName(volRegion) + / faMesh::prefix() + / polyMesh::regionName(areaRegion) + ); +} + + +Foam::fileName Foam::faMesh::dbDir +( + const polyMesh& pMesh, + const word& areaRegion +) +{ + return faMesh::dbDir(pMesh.regionName(), areaRegion); +} + + +Foam::fileName Foam::faMesh::meshDir(const word& areaRegion) +{ + if (areaRegion.empty() || areaRegion == polyMesh::defaultRegion) + { + return faMesh::meshSubDir; + } + + return (areaRegion / faMesh::meshSubDir); +} + + +Foam::fileName Foam::faMesh::meshDir +( + const word& volRegion, + const word& areaRegion +) +{ + return + ( + polyMesh::regionName(volRegion) + / faMesh::prefix() + / polyMesh::regionName(areaRegion) + / faMesh::meshSubDir + ); +} + + +Foam::fileName Foam::faMesh::meshDir +( + const polyMesh& pMesh, + const word& areaRegion +) +{ + return faMesh::meshDir(pMesh.regionName(), areaRegion); +} + + const Foam::objectRegistry* Foam::faMesh::registry(const polyMesh& pMesh) { - // This will change in the near future - return &static_cast(pMesh); + return pMesh.cfindObject(faMesh::prefix()); } +// const Foam::objectRegistry* Foam::faMesh::registry(const objectRegistry& obr) +// { +// return obr.cfindObject(faMesh::prefix()); +// } + + const Foam::faMesh& Foam::faMesh::mesh ( const polyMesh& pMesh ) { - // This will change in the near future - return pMesh.lookupObject("faMesh"); + return faMesh::mesh(pMesh, polyMesh::defaultRegion); +} + + +const Foam::faMesh& Foam::faMesh::mesh +( + const polyMesh& pMesh, + const word& areaRegion +) +{ + const objectRegistry* obr = faMesh::registry(pMesh); + + if (!obr) + { + // Fallback - not really valid, but will fail at the next stage + obr = &(pMesh.thisDb()); + } + + if (areaRegion.empty()) + { + return obr->lookupObject(polyMesh::defaultRegion); + } + + return obr->lookupObject(areaRegion); } @@ -340,19 +446,85 @@ bool Foam::faMesh::init(const bool doInit) } -Foam::faMesh::faMesh(const polyMesh& pMesh, const Foam::zero) +// * * * * * * * * * * * * * Forwarding Constructors * * * * * * * * * * * * // + +Foam::faMesh::faMesh +( + const word& meshName, + const polyMesh& pMesh, + Foam::zero +) : - faMesh(pMesh, labelList(), static_cast(pMesh)) + faMesh(meshName, pMesh, labelList()) {} -Foam::faMesh::faMesh(const faMesh& baseMesh, const Foam::zero) +Foam::faMesh::faMesh +( + const polyMesh& pMesh, + Foam::zero +) +: + faMesh(polyMesh::defaultRegion, pMesh, labelList()) +{} + + +Foam::faMesh::faMesh(const polyMesh& pMesh, const bool doInit) +: + faMesh(polyMesh::defaultRegion, pMesh, doInit) +{} + + +Foam::faMesh::faMesh +( + const word& meshName, + const faMesh& baseMesh, + Foam::zero +) +: + faMesh(meshName, baseMesh, labelList()) +{} + + +Foam::faMesh::faMesh +( + const faMesh& baseMesh, + Foam::zero +) +: + faMesh(polyMesh::defaultRegion, baseMesh, labelList()) +{} + + +Foam::faMesh::faMesh +( + const word& meshName, + const faMesh& baseMesh, + labelList&& faceLabels +) : faMesh ( + meshName, baseMesh, - labelList(), - IOobjectOption(IOobjectOption::NO_READ, IOobjectOption::NO_WRITE) + std::move(faceLabels), + static_cast(baseMesh.thisDb()) + ) +{} + + +Foam::faMesh::faMesh +( + const faMesh& baseMesh, + labelList&& faceLabels +) +: + faMesh + ( + polyMesh::defaultRegion, + baseMesh, + std::move(faceLabels), + static_cast(baseMesh.thisDb()) ) {} @@ -360,13 +532,78 @@ Foam::faMesh::faMesh(const faMesh& baseMesh, const Foam::zero) Foam::faMesh::faMesh ( const polyMesh& pMesh, + labelList&& faceLabels, + IOobjectOption ioOpt +) +: + faMesh + ( + polyMesh::defaultRegion, + pMesh, + std::move(faceLabels), + ioOpt + ) +{} + + +Foam::faMesh::faMesh +( + const polyMesh& pMesh, + labelList&& faceLabels +) +: + faMesh(polyMesh::defaultRegion, pMesh, std::move(faceLabels)) +{} + + +Foam::faMesh::faMesh +( + const polyPatch& pp, const bool doInit ) : - MeshObject(pMesh), - faSchemes(mesh()), + faMesh(polyMesh::defaultRegion, pp, doInit) +{} + + +Foam::faMesh::faMesh +( + const polyMesh& pMesh, + const dictionary& faMeshDefinition, + const bool doInit +) +: + faMesh + ( + polyMesh::defaultRegion, + pMesh, + faMeshDefinition, + doInit + ) +{} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faMesh::faMesh +( + const word& meshName, + const polyMesh& pMesh, + const bool doInit +) +: + faMeshRegistry(meshName, pMesh), + faSchemes + ( + faMesh::thisDb(), + IOobjectOption::MUST_READ + ), + faSolution + ( + faMesh::thisDb(), + IOobjectOption::MUST_READ + ), edgeInterpolation(*this), - faSolution(mesh()), faceLabels_ ( IOobject @@ -418,7 +655,7 @@ Foam::faMesh::faMesh IOobject rio ( - "name", + "any-name", time().timeName(), faMesh::meshSubDir, faMesh::thisDb(), @@ -444,36 +681,29 @@ Foam::faMesh::faMesh Foam::faMesh::faMesh ( + const word& meshName, const polyMesh& pMesh, labelList&& faceLabels ) : - faMesh + faMeshRegistry(meshName, pMesh), + faSchemes ( - pMesh, - std::move(faceLabels), - static_cast(pMesh) - ) -{} - - -Foam::faMesh::faMesh -( - const polyMesh& pMesh, - labelList&& faceLabels, - IOobjectOption ioOpt -) -: - MeshObject(pMesh), - faSchemes(mesh(), ioOpt.readOpt()), + faMesh::thisDb(), + IOobjectOption::MUST_READ + ), + faSolution + ( + faMesh::thisDb(), + IOobjectOption::MUST_READ + ), edgeInterpolation(*this), - faSolution(mesh(), ioOpt.readOpt()), faceLabels_ ( IOobject ( "faceLabels", - mesh().facesInstance(), + pMesh.facesInstance(), faMesh::meshSubDir, faMesh::thisDb(), IOobject::NO_READ, @@ -486,14 +716,14 @@ Foam::faMesh::faMesh IOobject ( "faBoundary", - mesh().facesInstance(), + faceLabels_.instance(), faMesh::meshSubDir, faMesh::thisDb(), IOobject::NO_READ, IOobject::NO_WRITE ), *this, - label(0) + Foam::zero{} ), comm_(UPstream::worldComm), curTimeIndex_(time().timeIndex()) @@ -503,36 +733,103 @@ Foam::faMesh::faMesh nEdges_ = 0; nInternalEdges_ = 0; nFaces_ = faceLabels_.size(); -} + // TDB: can we make a NO_READ readOption persistent for + // faSchemes/faSolution? Or not needed anymore? +} Foam::faMesh::faMesh ( + const word& meshName, + const polyMesh& pMesh, + labelList&& faceLabels, + IOobjectOption ioOpt +) +: + faMeshRegistry(meshName, pMesh), + faSchemes + ( + faMesh::thisDb(), + ioOpt.readOpt() + ), + faSolution + ( + faMesh::thisDb(), + ioOpt.readOpt() + ), + edgeInterpolation(*this), + faceLabels_ + ( + IOobject + ( + "faceLabels", + pMesh.facesInstance(), + faMesh::meshSubDir, + faMesh::thisDb(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + std::move(faceLabels) + ), + boundary_ + ( + IOobject + ( + "faBoundary", + faceLabels_.instance(), + faMesh::meshSubDir, + faMesh::thisDb(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + *this, + Foam::zero{} + ), + comm_(UPstream::worldComm), + curTimeIndex_(time().timeIndex()) +{ + // Not yet much for primitive mesh data possible... + nPoints_ = 0; + nEdges_ = 0; + nInternalEdges_ = 0; + nFaces_ = faceLabels_.size(); + + // TDB: can we make a NO_READ readOption persistent for + // faSchemes/faSolution? Or not needed anymore? +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faMesh::faMesh +( + const word& meshName, const faMesh& baseMesh, labelList&& faceLabels, IOobjectOption ioOpt ) : - MeshObject(baseMesh.mesh()), + faMeshRegistry(meshName, baseMesh.mesh()), faSchemes ( faMesh::thisDb(), ioOpt.readOpt(), static_cast(baseMesh.hasSchemes()) ), - edgeInterpolation(*this), faSolution ( faMesh::thisDb(), ioOpt.readOpt(), static_cast(baseMesh.hasSolution()) ), + edgeInterpolation(*this), faceLabels_ ( IOobject ( "faceLabels", - mesh().facesInstance(), + // Topological instance from polyMesh + baseMesh.mesh().facesInstance(), faMesh::meshSubDir, faMesh::thisDb(), IOobject::NO_READ, @@ -545,14 +842,14 @@ Foam::faMesh::faMesh IOobject ( "faBoundary", - mesh().facesInstance(), + faceLabels_.instance(), faMesh::meshSubDir, faMesh::thisDb(), IOobject::NO_READ, IOobject::NO_WRITE ), *this, - label(0) + Foam::zero{} ), comm_(UPstream::worldComm), curTimeIndex_(time().timeIndex()) @@ -565,10 +862,16 @@ Foam::faMesh::faMesh } -Foam::faMesh::faMesh(const polyPatch& pp, const bool doInit) +Foam::faMesh::faMesh +( + const word& meshName, + const polyPatch& pp, + const bool doInit +) : faMesh ( + meshName, pp.boundaryMesh().mesh(), identity(pp.range()) ) @@ -594,6 +897,7 @@ Foam::faMesh::faMesh(const polyPatch& pp, const bool doInit) Foam::faMesh::faMesh ( + const word& meshName, const polyMesh& pMesh, const dictionary& faMeshDefinition, const bool doInit @@ -601,6 +905,7 @@ Foam::faMesh::faMesh : faMesh ( + meshName, pMesh, selectPatchFaces ( @@ -639,7 +944,7 @@ Foam::faMesh::faMesh IOobject rio ( - "name", + "any-name", time().timeName(), faMesh::meshSubDir, faMesh::thisDb(), @@ -709,15 +1014,21 @@ Foam::faSolution& Foam::faMesh::solution() } +const Foam::polyMesh& Foam::faMesh::mesh() const +{ + return refCast(faMeshRegistry::parent().parent()); +} + + Foam::fileName Foam::faMesh::meshDir() const { - return mesh().dbDir()/faMesh::meshSubDir; + return dbDir()/faMesh::meshSubDir; } const Foam::Time& Foam::faMesh::time() const { - return mesh().time(); + return faMeshRegistry::time(); } @@ -733,21 +1044,9 @@ const Foam::fileName& Foam::faMesh::facesInstance() const } -bool Foam::faMesh::hasDb() const -{ - return true; -} - - -const Foam::objectRegistry& Foam::faMesh::thisDb() const -{ - return mesh().thisDb(); -} - - const Foam::word& Foam::faMesh::regionName() const { - return polyMesh::regionName(thisDb().name()); + return polyMesh::regionName(objectRegistry::name()); } @@ -874,7 +1173,7 @@ Foam::faMesh::S00() const ( "S00", time().timeName(), - faMesh::thisDb(), + *this, IOobject::NO_READ, IOobject::NO_WRITE ), @@ -1008,7 +1307,7 @@ bool Foam::faMesh::movePoints() ( "S0", time().timeName(), - faMesh::thisDb(), + *this, IOobject::NO_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER diff --git a/src/finiteArea/faMesh/faMesh.H b/src/finiteArea/faMesh/faMesh.H index 34e1352250..95d564df4c 100644 --- a/src/finiteArea/faMesh/faMesh.H +++ b/src/finiteArea/faMesh/faMesh.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2021-2023 OpenCFD Ltd. + Copyright (C) 2021-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -56,7 +56,6 @@ Author #ifndef Foam_faMesh_H #define Foam_faMesh_H -#include "MeshObject.H" #include "polyMesh.H" #include "lduMesh.H" #include "faBoundaryMesh.H" @@ -85,17 +84,52 @@ class faMeshLduAddressing; class faMeshMapper; class faPatchData; +/*---------------------------------------------------------------------------*\ + Class faMeshRegistry Declaration +\*---------------------------------------------------------------------------*/ + +//- The objectRegistry for faMesh. +// This is a separate class to ensure it will be fully constructed before +// other data members use it, which ensures that its virtual methods are +// callable during construction (gcc). +class faMeshRegistry +: + public objectRegistry +{ +public: + + // Constructors + + //- Construct an objectRegistry for given area region name. + // Uses faMeshesRegistry internally + faMeshRegistry(const word& areaRegion, const polyMesh& mesh); + + + // Member Functions + + //- True - thisDb() is a valid registry + virtual bool hasDb() const { return true; } + + //- Reference to the mesh database + virtual const objectRegistry& thisDb() const { return *this; } + + //- Local directory path of the objectRegistry relative to Time + //- with override for the single-region case + virtual const fileName& dbDir() const; +}; + + /*---------------------------------------------------------------------------*\ Class faMesh Declaration \*---------------------------------------------------------------------------*/ class faMesh : - public MeshObject, + public faMeshRegistry, public lduMesh, public faSchemes, - public edgeInterpolation, // may need input from faSchemes - public faSolution + public faSolution, + public edgeInterpolation // may need input from faSchemes { // Private (internal) classes/structures @@ -327,6 +361,9 @@ class faMesh // Static Private Data + //- The prefix to local: %finite-area + static const word prefix_; + //- Quadrics fit for pointAreaNormals (experimental) static const int quadricsFit_; @@ -356,7 +393,7 @@ class faMesh ) const; - // Private member functions to calculate demand driven data + // Private Member Functions to calculate demand driven data //- Calculate ldu addressing void calcLduAddressing() const; @@ -486,11 +523,18 @@ class faMesh // Static Functions //- Test if faSchemes/faSolution files are available - static bool hasSystemFiles(const polyMesh& pMesh); - - //- Test if all files needed for read construction are available - static bool hasFiles(const polyMesh& pMesh); + static bool hasSystemFiles + ( + const word& meshName, + const polyMesh& pMesh + ); + //- Test if mesh files needed for read construction are available + static bool hasMeshFiles + ( + const word& meshName, + const polyMesh& pMesh + ); public: @@ -512,8 +556,8 @@ public: //- Runtime type information TypeName("faMesh"); - //- The prefix to local: %finite-area - static const word prefix; + //- The prefix to the parent registry name: %finite-area + static const word& prefix() noexcept; //- The mesh sub-directory name (usually "faMesh") static word meshSubDir; @@ -530,29 +574,27 @@ public: // Constructors - //- Read construct from polyMesh, using its IOobject properties - explicit faMesh(const polyMesh& pMesh, const bool doInit = true); + //- Construct zero-sized from polyMesh + // Boundary is added using addFaPatches() member function + faMesh(const word& meshName, const polyMesh&, Foam::zero); //- Construct zero-sized from polyMesh // Boundary is added using addFaPatches() member function - faMesh(const polyMesh& pMesh, const Foam::zero); + faMesh(const polyMesh&, Foam::zero); - //- Construct as copy (for dictionaries) and zero-sized - //- without boundary. - // Boundary is added using addFaPatches() member function - faMesh(const faMesh& baseMesh, const Foam::zero); + //- Read construct from polyMesh, using its IOobject properties + faMesh(const word& meshName, const polyMesh&, const bool doInit = true); - //- Construct as copy (for dictionaries) and faceLabels - //- without boundary, using read properties from baseMesh. - // Boundary is added using addFaPatches() member function - faMesh(const faMesh& baseMesh, labelList&& faceLabels); + //- Read construct from polyMesh, using its IOobject properties + explicit faMesh(const polyMesh&, const bool doInit = true); - //- Construct as copy (for dictionaries) and faceLabels - //- without boundary, using specified read properties. + //- Construct from components (face labels) without boundary, + //- using specified read properties. // Boundary is added using addFaPatches() member function. faMesh ( - const faMesh& baseMesh, + const word& meshName, + const polyMesh& pMesh, labelList&& faceLabels, IOobjectOption ioOpt ); @@ -560,21 +602,84 @@ public: //- Construct from components (face labels) without boundary, //- using IOobject properties from polyMesh. // Boundary is added using addFaPatches() member function. - faMesh(const polyMesh& pMesh, labelList&& faceLabels); + faMesh(const word& meshName, const polyMesh&, labelList&& faceLabels); //- Construct from components (face labels) without boundary, //- using specified read properties. // Boundary is added using addFaPatches() member function. + faMesh(const polyMesh&, labelList&& faceLabels, IOobjectOption ioOpt); + + //- Construct from components (face labels) without boundary, + //- using IOobject properties from polyMesh. + // Boundary is added using addFaPatches() member function. + faMesh(const polyMesh&, labelList&& faceLabels); + + //- Construct as copy (for dictionaries) and zero-sized + //- without boundary. + // Boundary is added using addFaPatches() member function + faMesh(const word& meshName, const faMesh& baseMesh, Foam::zero); + + //- Construct as copy (for dictionaries) and zero-sized + //- without boundary, using IOobject properties from polyMesh. + // Boundary is added using addFaPatches() member function + faMesh(const faMesh& baseMesh, Foam::zero); + + //- Construct as copy (for dictionaries) and faceLabels + //- without boundary, using specified read properties. + // Boundary is added using addFaPatches() member function faMesh ( - const polyMesh& pMesh, + const word& meshName, + const faMesh& baseMesh, labelList&& faceLabels, IOobjectOption ioOpt ); + //- Construct as copy (for dictionaries) and faceLabels + //- without boundary, using specified read properties. + // Boundary is added using addFaPatches() member function + faMesh + ( + const faMesh& baseMesh, + labelList&& faceLabels, + IOobjectOption ioOpt + ); + + //- Construct as copy (for dictionaries) and faceLabels + //- without boundary, using IOobject properties from polyMesh. + // Boundary is added using addFaPatches() member function + faMesh + ( + const word& meshName, + const faMesh& baseMesh, + labelList&& faceLabels + ); + + //- Construct as copy (for dictionaries) and faceLabels + //- without boundary, using read properties from baseMesh. + // Boundary is added using addFaPatches() member function + faMesh(const faMesh& baseMesh, labelList&& faceLabels); + + //- Construct from single polyPatch + faMesh + ( + const word& meshName, + const polyPatch& pp, + const bool doInit = true + ); + //- Construct from single polyPatch explicit faMesh(const polyPatch& pp, const bool doInit = true); + //- Construct from definition + faMesh + ( + const word& meshName, + const polyMesh& pMesh, + const dictionary& faMeshDefinition, + const bool doInit = true + ); + //- Construct from definition faMesh ( @@ -606,6 +711,13 @@ public: return old; } + //- Read construction from polyMesh if all files are available + static autoPtr TryNew + ( + const word& meshName, + const polyMesh& pMesh + ); + //- Read construction from polyMesh if all files are available static autoPtr TryNew(const polyMesh& pMesh); @@ -646,8 +758,12 @@ public: //- Uses lookupObject semantics - Fatal if non-existent static const faMesh& mesh(const polyMesh& pMesh); + //- The single-region or specified finite-area region on the polyMesh. + //- Uses lookupObject semantics - Fatal if non-existent + static const faMesh& mesh(const polyMesh&, const word& areaRegion); + //- Return access to polyMesh - inline const polyMesh& mesh() const; + const polyMesh& mesh() const; //- Return the local mesh directory (dbDir()/meshSubDir) fileName meshDir() const; @@ -751,22 +867,64 @@ public: // Database - //- Return true if thisDb() is a valid DB - virtual bool hasDb() const; + //- True - thisDb() is a valid registry + virtual bool hasDb() const { return true; } - //- Return reference to the mesh database - virtual const objectRegistry& thisDb() const; + //- Reference to the mesh database + virtual const objectRegistry& thisDb() const + { + return faMeshRegistry::thisDb(); + } + + //- Local directory path of the objectRegistry relative to Time + //- with override for the single-region case + virtual const fileName& dbDir() const + { + return faMeshRegistry::dbDir(); + } //- Name function is needed to disambiguate those inherited //- from base classes const word& name() const { - return thisDb().name(); + return faMeshRegistry::thisDb().name(); } // Regions + //- Local registry directory path (relative to Time) for specified + //- area mesh (of a single-region volume mesh) + static fileName dbDir(const word& areaRegion); + + //- Local registry directory path (relative to Time) for specified + //- volume mesh and area mesh combination + static fileName dbDir(const word& volRegion, const word& areaRegion); + + //- Local registry directory path (relative to Time) for specified + //- volume mesh and area mesh combination + static fileName dbDir + ( + const polyMesh& pMesh, + const word& areaRegion = word::null + ); + + //- The local mesh directory name (eg, "faMesh") for specified + //- area mesh (of a single-region volume mesh) + static fileName meshDir(const word& areaRegion); + + //- The local mesh directory name (eg, "faMesh") for specified + //- volume mesh and area mesh combination + static fileName meshDir(const word& volRegion, const word& areaRegion); + + //- The local mesh directory name (eg, "faMesh") for specified + //- volume mesh and area mesh combination + static fileName meshDir + ( + const polyMesh& pMesh, + const word& areaRegion = word::null + ); + //- The mesh region name or word::null if polyMesh::defaultRegion const word& regionName() const; diff --git a/src/finiteArea/faMesh/faMeshI.H b/src/finiteArea/faMesh/faMeshI.H index c04646d04c..bfa5614d1d 100644 --- a/src/finiteArea/faMesh/faMeshI.H +++ b/src/finiteArea/faMesh/faMeshI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2021-2022 OpenCFD Ltd. + Copyright (C) 2021-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,13 +28,6 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -inline const Foam::polyMesh& Foam::faMesh::mesh() const -{ - return - MeshObject::mesh(); -} - - inline const Foam::faBoundaryMesh& Foam::faMesh::boundary() const noexcept { return boundary_; diff --git a/src/finiteArea/faMesh/faMeshNew.C b/src/finiteArea/faMesh/faMeshNew.C index dcc6c2afec..bbbf40b471 100644 --- a/src/finiteArea/faMesh/faMeshNew.C +++ b/src/finiteArea/faMesh/faMeshNew.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022 OpenCFD Ltd. + Copyright (C) 2022-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,11 +31,34 @@ License // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // -bool Foam::faMesh::hasSystemFiles(const polyMesh& pMesh) +bool Foam::faMesh::hasSystemFiles +( + const word& meshName, + const polyMesh& pMesh +) { // Expect - // - system/faSchemes - // - system/faSolution + // - system/finite-area//faSchemes + // - system/finite-area//faSolution + + // The directory relative to polyMesh (not Time) + const fileName relativeDir + ( + faMesh::prefix() / polyMesh::regionName(meshName) + ); + + DebugInfo<< "check system files: " << relativeDir << nl; + + IOobject systemIOobject + ( + "any-name", + pMesh.time().system(), + relativeDir, + pMesh, + IOobject::MUST_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ); const fileOperation& fp = Foam::fileHandler(); @@ -52,20 +75,14 @@ bool Foam::faMesh::hasSystemFiles(const polyMesh& pMesh) }) ) { + systemIOobject.resetHeader(expect); + fileName found ( fp.filePath ( true, // global - IOobject - ( - expect, - pMesh.time().system(), - pMesh, - IOobject::MUST_READ, - IOobject::NO_WRITE, - IOobject::NO_REGISTER - ), + systemIOobject, expect // typeName (ununsed?) ) ); @@ -83,18 +100,34 @@ bool Foam::faMesh::hasSystemFiles(const polyMesh& pMesh) } -bool Foam::faMesh::hasFiles(const polyMesh& pMesh) +bool Foam::faMesh::hasMeshFiles +( + const word& meshName, + const polyMesh& pMesh +) { - // As well as system/{faSchemes,faSolution} + // As well as system/finite-area/{faSchemes,faSolution} // // expect these: - // - instance/faMesh/faceLabels - // - instance/faMesh/faBoundary + // - instance/finite-area//faMesh/faceLabels + // - instance/finite-area//faMesh/faBoundary - bool looksValid = hasSystemFiles(pMesh); + + // Not required... + // bool looksValid = hasSystemFiles(meshName, pMesh); + + bool looksValid = true; + + // The mesh directory relative to polyMesh (not Time) + const fileName relativeDir + ( + faMesh::meshDir(word::null, meshName) + ); if (looksValid) { + DebugInfo<< "check mesh files: " << relativeDir << nl; + const fileOperation& fp = Foam::fileHandler(); // The geometry instance for faMesh/faceLabels @@ -102,11 +135,23 @@ bool Foam::faMesh::hasFiles(const polyMesh& pMesh) const word instance = pMesh.time().findInstance ( - pMesh.dbDir()/faMesh::meshSubDir, + // Searching from Time, so need polyMesh region too + pMesh.regionName()/relativeDir, "faceLabels", IOobject::READ_IF_PRESENT ); + IOobject meshIOobject + ( + "any-name", + instance, + relativeDir, + pMesh, + IOobject::READ_IF_PRESENT, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ); + for ( const wordPair& expect @@ -120,21 +165,14 @@ bool Foam::faMesh::hasFiles(const polyMesh& pMesh) const word& dataFile = expect.first(); const word& dataClass = expect.second(); + meshIOobject.resetHeader(dataFile); + fileName found ( fp.filePath ( false, // non-global - IOobject - ( - dataFile, - instance, - faMesh::meshSubDir, - pMesh, - IOobject::READ_IF_PRESENT, - IOobject::NO_WRITE, - IOobject::NO_REGISTER - ), + meshIOobject, dataClass // typeName (ununsed?) ) ); @@ -153,15 +191,28 @@ bool Foam::faMesh::hasFiles(const polyMesh& pMesh) } -Foam::autoPtr Foam::faMesh::TryNew(const polyMesh& pMesh) +Foam::autoPtr Foam::faMesh::TryNew +( + const word& meshName, + const polyMesh& pMesh +) { - if (faMesh::hasFiles(pMesh)) + if (faMesh::hasMeshFiles(meshName, pMesh)) { - return autoPtr::New(pMesh); + return autoPtr::New(meshName, pMesh); } return nullptr; } +Foam::autoPtr Foam::faMesh::TryNew +( + const polyMesh& pMesh +) +{ + return TryNew(polyMesh::defaultRegion, pMesh); +} + + // ************************************************************************* // diff --git a/src/finiteArea/faMesh/faMeshRegistry.C b/src/finiteArea/faMesh/faMeshRegistry.C new file mode 100644 index 0000000000..892156f19f --- /dev/null +++ b/src/finiteArea/faMesh/faMeshRegistry.C @@ -0,0 +1,76 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 . + +\*---------------------------------------------------------------------------*/ + +#include "faMesh.H" +#include "faMeshesRegistry.H" +#include "Time.H" +#include "polyMesh.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faMeshRegistry::faMeshRegistry +( + const word& areaRegion, + const polyMesh& mesh +) +: + objectRegistry + ( + IOobject + ( + areaRegion, + faMeshesRegistry::New(mesh).thisDb(), + IOobjectOption::NO_READ, + IOobjectOption::AUTO_WRITE, + IOobjectOption::REGISTER + ) + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::fileName& Foam::faMeshRegistry::dbDir() const +{ + // In the usual case, the objectRegistry::dbDir() will be something + // like finite-area/{region0,film} etc with the "finite-area/" + // prefix coming from the enclosing registry of registries. + // + // So always check the name() portion, not the dbDir() itself + // - either, objectRegistry::dbDir().name() + // - or (same), objectRegistry::name() + + if (objectRegistry::name() == polyMesh::defaultRegion) + { + return objectRegistry::parent().dbDir(); + } + + return objectRegistry::dbDir(); +} + + +// ************************************************************************* // diff --git a/src/finiteArea/faMesh/faMeshTools/faMeshTools.C b/src/finiteArea/faMesh/faMeshTools/faMeshTools.C index 0154e99298..439d24fc31 100644 --- a/src/finiteArea/faMesh/faMeshTools/faMeshTools.C +++ b/src/finiteArea/faMesh/faMeshTools/faMeshTools.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015-2023 OpenCFD Ltd. + Copyright (C) 2015-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -77,12 +77,10 @@ Foam::faMeshTools::newMesh const bool verbose ) { - // Region name - // ~~~~~~~~~~~ - + // The mesh directory (assuming single area region), relative to Time const fileName meshSubDir ( - pMesh.regionName() / faMesh::meshSubDir + faMesh::meshDir(pMesh, word::null) ); @@ -111,7 +109,7 @@ Foam::faMeshTools::newMesh "faBoundary", facesInstance, meshSubDir, - io.db(), + io.time(), IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER @@ -133,15 +131,15 @@ Foam::faMeshTools::newMesh // Dummy meshes // ~~~~~~~~~~~~ - // Set up to read-if-present. Note: does not search for mesh so set - // instance explicitly + // Fake read-if-present behaviour to obtain the faceLabels IOobject meshIO(io); meshIO.instance() = facesInstance; meshIO.readOpt(IOobject::READ_IF_PRESENT); // For mesh components (faceLabels, ...) - IOobject cmptIO(meshIO, "faceLabels", meshSubDir); + IOobject cmptIO(io.time(), "faceLabels", meshSubDir); + cmptIO.instance() = facesInstance; cmptIO.readOpt(IOobject::MUST_READ); cmptIO.writeOpt(IOobject::NO_WRITE); cmptIO.registerObject(IOobject::NO_REGISTER); @@ -261,12 +259,10 @@ Foam::faMeshTools::loadOrCreateMeshImpl const bool verbose ) { - // Region name - // ~~~~~~~~~~~ - + // The mesh directory (assuming single area region), relative to Time const fileName meshSubDir ( - pMesh.regionName() / faMesh::meshSubDir + faMesh::meshDir(pMesh, word::null) ); @@ -288,7 +284,7 @@ Foam::faMeshTools::loadOrCreateMeshImpl "faBoundary", io.instance(), meshSubDir, - io.db(), + io.time(), IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER @@ -359,7 +355,7 @@ Foam::faMeshTools::loadOrCreateMeshImpl new faMesh ( pMesh, - labelList(), + labelList(), // Similar to Foam::zero{} IOobject(io, IOobject::NO_READ, IOobject::AUTO_WRITE) ) ); diff --git a/src/finiteArea/faMesh/faMeshTools/faMeshTools.H b/src/finiteArea/faMesh/faMeshTools/faMeshTools.H index ee63b1b305..148494d2a0 100644 --- a/src/finiteArea/faMesh/faMeshTools/faMeshTools.H +++ b/src/finiteArea/faMesh/faMeshTools/faMeshTools.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022-2023 OpenCFD Ltd. + Copyright (C) 2022-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -99,6 +99,7 @@ public: // if not present static autoPtr newMesh ( + //! The IOobject describes the base polyMesh const IOobject& io, const polyMesh& pMesh, const bool masterOnlyReading, @@ -111,6 +112,7 @@ public: // - io.instance() set to facesInstance static autoPtr loadOrCreateMesh ( + //! The IOobject describes the base polyMesh const IOobject& io, const polyMesh& pMesh, const bool decompose, @@ -123,6 +125,7 @@ public: // - io.instance() set to facesInstance static autoPtr loadOrCreateMesh ( + //! The IOobject describes the base polyMesh const IOobject& io, const polyMesh& pMesh, //! Non-null reference if a mesh exists on given processor diff --git a/src/finiteArea/faMesh/faMeshesRegistry.C b/src/finiteArea/faMesh/faMeshesRegistry.C new file mode 100644 index 0000000000..cfdf7128fd --- /dev/null +++ b/src/finiteArea/faMesh/faMeshesRegistry.C @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023-2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 . + +\*---------------------------------------------------------------------------*/ + +#include "faMeshesRegistry.H" +#include "faMesh.H" +#include "polyMesh.H" +#include "mapPolyMesh.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(faMeshesRegistry, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faMeshesRegistry::faMeshesRegistry(const polyMesh& mesh) +: + MeshObject_type(mesh), + objects_ + ( + IOobject + ( + faMesh::prefix(), + mesh.time().timeName(), + mesh.thisDb(), + IOobjectOption::NO_READ, + IOobjectOption::AUTO_WRITE, + IOobjectOption::REGISTER + ) + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::faMeshesRegistry::movePoints() +{ + for (faMesh& m : objects_.sorted()) + { + m.movePoints(); + } + + return true; +} + + +void Foam::faMeshesRegistry::updateMesh(const mapPolyMesh& mpm) +{ + for (faMesh& m : objects_.sorted()) + { + m.updateMesh(mpm); + } +} + + +bool Foam::faMeshesRegistry::writeObject +( + IOstreamOption streamOpt, + const bool writeOnProc +) const +{ + // for (const faMesh& m : objects_.csorted()) + // { + // m.write(writeOnProc); + // } + // + // return true; + + return objects_.writeObject(streamOpt, writeOnProc); +} + + +// ************************************************************************* // diff --git a/src/finiteArea/faMesh/faMeshesRegistry.H b/src/finiteArea/faMesh/faMeshesRegistry.H new file mode 100644 index 0000000000..e3b78e7b8c --- /dev/null +++ b/src/finiteArea/faMesh/faMeshesRegistry.H @@ -0,0 +1,194 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023-2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 . + +Class + Foam::faMeshesRegistry + +Description + A MeshObject registry on top of a polyMesh that provides + an objectRegistry for holding multiple faMesh objects. + + Directory structure for fields/meshes (default region): + \verbatim + . + |-- constant + | `-- finite-area + | `-- faMesh + | |-- faceLabels + | |-- ... + | `-- faBoundary + |-- system + | `-- finite-area + | |-- faMeshDefiniton + | |-- faSchemes + | `-- faSolution + `-- instance + `-- finite-area + |-- U + |-- p + `-- ... + \endverbatim + + Directory structure for fields/meshes (multi-regions): + \verbatim + . + |-- constant + | `-- finite-area + | |-- regionName1 + | | `-- faMesh + | | `-- ... + | `-- regionNameN + | `-- faMesh + | `-- ... + |-- system + | `-- finite-area + | |-- regionName1 + | | |-- faMeshDefiniton + | | |-- faSchemes + | | `-- faSolution + | `-- regionNameN + | `-- ... + | + `-- instance + `-- finite-area + |-- regionName1 + | `-- ... + `-- regionNameN + `-- ... + \endverbatim + +SourceFiles + faMeshesRegistry.C + +\*---------------------------------------------------------------------------*/ + +#ifndef Foam_faMeshesRegistry_H +#define Foam_faMeshesRegistry_H + +#include "MeshObject.H" +#include "polyMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward Declarations +class faMesh; + +/*---------------------------------------------------------------------------*\ + Class faMeshesRegistry Declaration +\*---------------------------------------------------------------------------*/ + +class faMeshesRegistry +: + public MeshObject +{ + // Data Types + + //- The MeshObject type + typedef MeshObject + < + polyMesh, + UpdateableMeshObject, + faMeshesRegistry + > MeshObject_type; + + + // Private Member Data + + //- The sub-registry of finite-area objects (meshes), + //- anchored on the polyMesh parent. Name: "finite-area", + objectRegistry objects_; + + +public: + + //- Runtime type information. + TypeName("faMeshesRegistry"); + + // Generated Methods + + //- No copy construct + faMeshesRegistry(const faMeshesRegistry&) = delete; + + //- No copy assignment + void operator=(const faMeshesRegistry&) = delete; + + + // Constructors + + //- Construct as singleton on the polyMesh registry + explicit faMeshesRegistry(const polyMesh& mesh); + + + // Database + + //- Return the object registry + const objectRegistry& thisDb() const noexcept + { + return objects_; + } + + //- The polyMesh reference + const polyMesh& mesh() const noexcept + { + return MeshObject_type::mesh(); + } + + + // Topological Change + + //- Is mesh moving - ie, is polyMesh moving + bool moving() const { return MeshObject_type::mesh().moving(); } + + //- Update after mesh motion + virtual bool movePoints(); + + //- Update after topo change + virtual void updateMesh(const mapPolyMesh& mpm); + + + // Write + + //- Write items (eg, faMesh) held in the registry + virtual bool writeObject + ( + IOstreamOption streamOpt, + const bool writeOnProc = true + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/shape/surface/sensitivitySurface.C b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/shape/surface/sensitivitySurface.C index 3d1b1dfd89..94c7b26562 100644 --- a/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/shape/surface/sensitivitySurface.C +++ b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/shape/surface/sensitivitySurface.C @@ -74,55 +74,70 @@ void sensitivitySurface::smoothSensitivities() // Read in parameters const label iters(dict().getOrDefault