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).
This commit is contained in:
Mark Olesen
2024-04-17 14:27:25 +02:00
parent 1d5b95b5fe
commit b5435cc83e
35 changed files with 1812 additions and 350 deletions

View File

@ -0,0 +1,3 @@
Test-faMesh-try.cxx
EXE = $(FOAM_USER_APPBIN)/Test-faMesh-try

View File

@ -0,0 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteArea \
-lmeshTools

View File

@ -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 <http://www.gnu.org/licenses/>.
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<faMesh> aMeshPtr = faMesh::TryNew(areaRegionName, mesh);
Info<< "area-mesh: " << Switch::name(aMeshPtr) << nl;
Info<< "\nEnd\n" << nl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
Test-faMeshesRegistry.cxx
EXE = $(FOAM_USER_APPBIN)/Test-faMeshesRegistry

View File

@ -0,0 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteArea \
-lmeshTools

View File

@ -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 <http://www.gnu.org/licenses/>.
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&>(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;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021-2022 OpenCFD Ltd. Copyright (C) 2021-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -77,6 +77,7 @@ int main(int argc, char *argv[])
); );
#include "addRegionOption.H" #include "addRegionOption.H"
#include "addFaRegionOption.H"
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
#include "createNamedPolyMesh.H" #include "createNamedPolyMesh.H"
@ -90,8 +91,7 @@ int main(int argc, char *argv[])
faMesh::geometryOrder(geometryOrder); faMesh::geometryOrder(geometryOrder);
} }
// Create #include "createNamedFaMesh.H"
faMesh aMesh(mesh);
Info<< "Time = " << runTime.timeName() << nl << endl; Info<< "Time = " << runTime.timeName() << nl << endl;

View File

@ -70,7 +70,13 @@ do
const bool oldParRun = UPstream::parRun(false); 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); UPstream::parRun(oldParRun);
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021-2022 OpenCFD Ltd. Copyright (C) 2021-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -18,7 +18,8 @@ Required Classes
- Foam::IOdictionary - Foam::IOdictionary
Required Variables Required Variables
- regionName [word] - regionName [word] (the polyMesh region)
- areaRegionName [word] (the areaMesh region)
- args [argList] - args [argList]
- runTime [Time] - runTime [Time]
@ -35,6 +36,7 @@ autoPtr<IOdictionary> meshDictPtr;
{ {
fileName dictPath; fileName dictPath;
const word& regionDir = Foam::polyMesh::regionName(regionName); const word& regionDir = Foam::polyMesh::regionName(regionName);
const word& areaRegionDir = Foam::polyMesh::regionName(areaRegionName);
if (args.readIfPresent("dict", dictPath)) if (args.readIfPresent("dict", dictPath))
{ {
@ -47,38 +49,30 @@ autoPtr<IOdictionary> meshDictPtr;
} }
else if else if
( (
// Check global location // Dictionary under system/faMeshDefinition ?
exists // (v2312 and earlier)
areaRegionDir.empty()
&& exists
( (
runTime.path()/runTime.caseConstant() runTime.path()/runTime.caseSystem()
/ regionDir/faMesh::meshSubDir/dictName / regionDir/faMesh::meshSubDir/dictName
) )
) )
{ {
// Dictionary present in constant faMesh directory (old-style) // Dictionary present directly in system/ (v2312 and earlier)
dictPath = dictPath = runTime.system()/regionDir/dictName;
(
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
} }
else 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 IOobject meshDictIO

View File

@ -104,10 +104,13 @@ int main(int argc, char *argv[])
); );
#include "addRegionOption.H" #include "addRegionOption.H"
#include "addFaRegionOption.H"
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
#include "createNamedPolyMesh.H" #include "createNamedPolyMesh.H"
#include "getFaRegionOption.H"
const bool doDecompose = !args.found("no-decompose"); const bool doDecompose = !args.found("no-decompose");
const bool doDecompFields = !args.found("no-fields"); const bool doDecompFields = !args.found("no-fields");
@ -133,8 +136,15 @@ int main(int argc, char *argv[])
// Preliminary checks // Preliminary checks
#include "checkPatchTopology.H" #include "checkPatchTopology.H"
Info << "Create areaMesh";
if (!Foam::polyMesh::regionName(areaRegionName).empty())
{
Foam::Info << ' ' << areaRegionName;
}
Info << " for polyMesh at time = " << runTime.timeName() << nl;
// Create // Create
faMesh aMesh(mesh, meshDefDict); faMesh aMesh(areaRegionName, mesh, meshDefDict);
// Mesh information (less verbose) // Mesh information (less verbose)
faMeshTools::printMeshChecks(aMesh, 0); faMeshTools::printMeshChecks(aMesh, 0);

View File

@ -173,7 +173,7 @@ namespace Foam
// Uses polyMesh/fvMesh meshSubDir by default // Uses polyMesh/fvMesh meshSubDir by default
autoPtr<labelIOList> procAddressing autoPtr<labelIOList> procAddressing
( (
const fvMesh& procMesh, const objectRegistry& procRegistry,
const word& name, const word& name,
const word& instance, const word& instance,
const word& local = fvMesh::meshSubDir const word& local = fvMesh::meshSubDir
@ -186,7 +186,7 @@ autoPtr<labelIOList> procAddressing
name, name,
instance, instance,
local, local,
procMesh, procRegistry,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER
@ -199,13 +199,13 @@ autoPtr<labelIOList> procAddressing
// Uses the finiteArea meshSubDir // Uses the finiteArea meshSubDir
autoPtr<labelIOList> faProcAddressing autoPtr<labelIOList> faProcAddressing
( (
const fvMesh& procMesh, const objectRegistry& procRegistry,
const word& name, const word& name,
const word& instance, const word& instance,
const word& local = faMesh::meshSubDir 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 // Field objects at this time
IOobjectList objects; IOobjectList objects;
IOobjectList faObjects;
if (doDecompFields) if (doDecompFields)
{ {
// List of volume mesh objects for this instance
objects = IOobjectList(mesh, runTime.timeName()); 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) // Ignore generated fields: (cellDist)
objects.remove("cellDist"); objects.remove("cellDist");
} }
@ -810,12 +821,15 @@ int main(int argc, char *argv[])
autoPtr<faMeshDecomposition> faMeshDecompPtr; autoPtr<faMeshDecomposition> faMeshDecompPtr;
if (doFiniteArea) if (doFiniteArea)
{ {
const word boundaryInst =
mesh.time().findInstance(mesh.meshDir(), "boundary");
IOobject io IOobject io
( (
"faBoundary", "faBoundary",
mesh.time().findInstance(mesh.meshDir(), "boundary"), boundaryInst,
faMesh::meshSubDir, faMesh::meshDir(mesh, word::null),
mesh, mesh.time(),
IOobject::READ_IF_PRESENT, IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER
@ -1225,7 +1239,7 @@ int main(int argc, char *argv[])
if (doDecompFields) if (doDecompFields)
{ {
areaFieldCache.readAllFields(aMesh, objects); areaFieldCache.readAllFields(aMesh, faObjects);
} }
const label nAreaFields = areaFieldCache.size(); const label nAreaFields = areaFieldCache.size();
@ -1293,7 +1307,7 @@ int main(int argc, char *argv[])
autoPtr<labelIOList> tfaceProcAddr = autoPtr<labelIOList> tfaceProcAddr =
faProcAddressing faProcAddressing
( (
procFvMesh, procMesh,
"faceProcAddressing", "faceProcAddressing",
runTime.constant() runTime.constant()
); );
@ -1302,7 +1316,7 @@ int main(int argc, char *argv[])
autoPtr<labelIOList> tboundaryProcAddr = autoPtr<labelIOList> tboundaryProcAddr =
faProcAddressing faProcAddressing
( (
procFvMesh, procMesh,
"boundaryProcAddressing", "boundaryProcAddressing",
runTime.constant() runTime.constant()
); );
@ -1311,7 +1325,7 @@ int main(int argc, char *argv[])
autoPtr<labelIOList> tedgeProcAddr = autoPtr<labelIOList> tedgeProcAddr =
faProcAddressing faProcAddressing
( (
procFvMesh, procMesh,
"edgeProcAddressing", "edgeProcAddressing",
runTime.constant() runTime.constant()
); );

View File

@ -382,9 +382,25 @@ int main(int argc, char *argv[])
IOobjectList objects IOobjectList objects
( (
procMeshes.meshes()[0], 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 (doFields)
{ {
// If there are any FV fields, reconstruct them // If there are any FV fields, reconstruct them
@ -545,12 +561,12 @@ int main(int argc, char *argv[])
} }
else if else if
( (
objects.count<areaScalarField>() faObjects.count<areaScalarField>()
|| objects.count<areaVectorField>() || faObjects.count<areaVectorField>()
|| objects.count<areaSphericalTensorField>() || faObjects.count<areaSphericalTensorField>()
|| objects.count<areaSymmTensorField>() || faObjects.count<areaSymmTensorField>()
|| objects.count<areaTensorField>() || faObjects.count<areaTensorField>()
|| objects.count<edgeScalarField>() || faObjects.count<edgeScalarField>()
) )
{ {
Info << "Reconstructing FA fields" << nl << endl; Info << "Reconstructing FA fields" << nl << endl;
@ -568,7 +584,7 @@ int main(int argc, char *argv[])
procFaMeshes.boundaryProcAddressing() procFaMeshes.boundaryProcAddressing()
); );
reconstructor.reconstructAllFields(objects); reconstructor.reconstructAllFields(faObjects);
} }
else else
{ {

View File

@ -102,6 +102,7 @@ Usage
#include "faMeshSubset.H" #include "faMeshSubset.H"
#include "faMeshTools.H" #include "faMeshTools.H"
#include "faMeshDistributor.H" #include "faMeshDistributor.H"
#include "faMeshesRegistry.H"
#include "parFaFieldDistributorCache.H" #include "parFaFieldDistributorCache.H"
#include "redistributeLagrangian.H" #include "redistributeLagrangian.H"
@ -906,12 +907,26 @@ autoPtr<mapDistributePolyMesh> 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> faMeshesRegistry_saved
(
faMeshesRegistry::Release(mesh)
);
// Mesh distribution engine // Mesh distribution engine
fvMeshDistribute distributor(mesh); fvMeshDistribute distributor(mesh);
// Do all the distribution of mesh and fields // Do all the distribution of mesh and fields
autoPtr<mapDistributePolyMesh> distMap = distributor.distribute(decomp); autoPtr<mapDistributePolyMesh> distMap = distributor.distribute(decomp);
// Restore ownership onto the polyMesh
faMeshesRegistry::Store(std::move(faMeshesRegistry_saved));
// Print some statistics // Print some statistics
InfoOrPout<< "After distribution:" << endl; InfoOrPout<< "After distribution:" << endl;
printMeshData(mesh); printMeshData(mesh);
@ -1598,7 +1613,8 @@ int main(int argc, char *argv[])
); );
const fileName areaMeshSubDir const fileName areaMeshSubDir
( (
polyMesh::regionName(regionName) / faMesh::meshSubDir // Assume single-region area mesh
faMesh::meshDir(regionName, word::null)
); );
InfoOrPout InfoOrPout
@ -2501,7 +2517,8 @@ int main(int argc, char *argv[])
); );
const fileName areaMeshSubDir const fileName areaMeshSubDir
( (
polyMesh::regionName(regionName) / faMesh::meshSubDir // Assume single-region area mesh
faMesh::meshDir(regionName, word::null)
); );
InfoOrPout InfoOrPout

View File

@ -21,29 +21,38 @@ Requires
// Initially all possible objects that are available at the final time // Initially all possible objects that are available at the final time
List<wordHashSet> availableRegionObjectNames(meshes.size()); List<wordHashSet> availableRegionObjectNames(meshes.size());
List<wordHashSet> availableFaRegionObjectNames(meshes.size());
forAll(meshes, regioni) forAll(meshes, regioni)
{ {
const auto& mesh = meshes[regioni]; const auto& mesh = meshes[regioni];
IOobjectList objects; IOobjectList objects;
IOobjectList faObjects;
if (doConvertFields && !timeDirs.empty()) if (doConvertFields && !timeDirs.empty())
{ {
// List of volume mesh objects for this instance
objects = IOobjectList(mesh, timeDirs.back().name()); objects = IOobjectList(mesh, timeDirs.back().name());
if (fieldSelector && !fieldSelector().empty()) // List of area mesh objects (assuming single region)
{ faObjects = IOobjectList
objects.filterObjects(fieldSelector()); (
} mesh.time(),
timeDirs.back().name(),
faMesh::dbDir(mesh, word::null),
IOobjectOption::NO_REGISTER
);
if (fieldSelector && !fieldSelector().empty()) if (fieldSelector && !fieldSelector().empty())
{ {
objects.filterObjects(fieldSelector()); objects.filterObjects(fieldSelector());
faObjects.filterObjects(fieldSelector());
} }
// Remove "*_0" restart fields // Remove "*_0" restart fields
objects.prune_0(); objects.prune_0();
faObjects.prune_0();
if (!doPointValues) if (!doPointValues)
{ {
@ -59,12 +68,38 @@ forAll(meshes, regioni)
} }
} }
// Volume fields
if (!objects.empty())
{
wordList objectNames(objects.sortedNames()); wordList objectNames(objects.sortedNames());
// Check availability for all times... // Check availability for all times...
checkData(mesh, timeDirs, objectNames); 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;
}
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later. This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -14,6 +14,8 @@ Description
Code chunk for converting area fields Code chunk for converting area fields
included by foamToEnsight. included by foamToEnsight.
Possible objects to convert are given in faObjects
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -23,7 +25,7 @@ if (doFiniteArea && ensFaCasePtr && ensFaMeshPtr)
{ {
Info<< " area field ("; Info<< " area field (";
writeAllAreaFields(*ensFaCasePtr, *ensFaMeshPtr, objects); writeAllAreaFields(*ensFaCasePtr, *ensFaMeshPtr, faObjects);
Info<< " )" << nl; Info<< " )" << nl;
} }

View File

@ -577,6 +577,20 @@ int main(int argc, char *argv[])
// Volume, internal, point fields // Volume, internal, point fields
#include "convertVolumeFields.H" #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 // The finiteArea fields
#include "convertAreaFields.H" #include "convertAreaFields.H"

View File

@ -55,7 +55,7 @@ label timeIndex = 0;
else else
{ {
goodTimeIndex = false; goodTimeIndex = false;
Info<< "skip ... missing entry " << io.objectPath() << endl; Info<< "skip ... missing file: " << io.objectRelPath() << endl;
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2022 OpenCFD Ltd. Copyright (C) 2018-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,9 +32,10 @@ License
Foam::label Foam::checkData Foam::label Foam::checkData
( (
const fvMesh& mesh, const objectRegistry& obr,
const instantList& timeDirs, const instantList& timeDirs,
wordList& objectNames wordList& objectNames,
const fileName& local
) )
{ {
// Assume prune_0() was used prior to calling this // Assume prune_0() was used prior to calling this
@ -43,6 +44,9 @@ Foam::label Foam::checkData
for (const word& fieldName : objectNames) for (const word& fieldName : objectNames)
{ {
// // If prune_0() not previously used...
// if (objectNames.ends_with("_0")) continue;
bool good = false; bool good = false;
for (const instant& inst : timeDirs) for (const instant& inst : timeDirs)
@ -52,7 +56,8 @@ Foam::label Foam::checkData
( (
fieldName, fieldName,
inst.name(), inst.name(),
mesh, local,
obr,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER

View File

@ -164,9 +164,10 @@ tmp<VolumeField<Type>> makeZeroGradientField
// ignore fields that are not available for all time-steps // ignore fields that are not available for all time-steps
label checkData label checkData
( (
const fvMesh& mesh, const objectRegistry& obr,
const instantList& timeDirs, const instantList& timeDirs,
wordList& objectNames wordList& objectNames,
const fileName& local = fileName::null
); );

View File

@ -29,7 +29,7 @@ if (doFiniteArea)
autoPtr<faMesh> faMeshPtr; autoPtr<faMesh> faMeshPtr;
const label nAreaFields = const label nAreaFields =
objects.count(stringListOps::foundOp<word>(fieldTypes::area)); faObjects.count(stringListOps::foundOp<word>(fieldTypes::area));
if (nAreaFields || withMeshIds) if (nAreaFields || withMeshIds)
{ {
@ -40,7 +40,7 @@ if (doFiniteArea)
{ {
const faMesh& areaMesh = faMeshPtr(); const faMesh& areaMesh = faMeshPtr();
reportFields::area(Info, objects); reportFields::area(Info, faObjects);
const auto& pp = faMeshPtr->patch(); const auto& pp = faMeshPtr->patch();
@ -97,7 +97,7 @@ if (doFiniteArea)
( (
writer, writer,
areaMesh, areaMesh,
objects, faObjects,
true // syncPar true // syncPar
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd. Copyright (C) 2016-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -781,20 +781,33 @@ int main(int argc, char *argv[])
} }
IOobjectList objects; IOobjectList objects;
IOobjectList faObjects;
if (doConvertFields) if (doConvertFields)
{ {
// List of objects for this time // List of volume mesh objects for this instance
objects = objects =
IOobjectList(meshProxy.baseMesh(), runTime.timeName()); 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()) if (fieldSelector && !fieldSelector().empty())
{ {
objects.filterObjects(fieldSelector()); objects.filterObjects(fieldSelector());
faObjects.filterObjects(fieldSelector());
} }
// Remove "*_0" restart fields // Remove "*_0" restart fields
objects.prune_0(); objects.prune_0();
faObjects.prune_0();
if (!doPointValues) if (!doPointValues)
{ {

322
bin/foamUpgradeFiniteArea Executable file
View File

@ -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 <<USAGE
Usage: ${0##*/} [OPTION]
options:
-case=DIR Specify starting directory, default is cwd
-dry-run | -n Test without performing actions
-verbose | -v Additional verbosity
-force (currently ignored)
-link-back Link back from new finite-area/ to old locations
-no-mesh Do not move system/faMeshDefinition
-git Use 'git mv' when making changes
-help Print help and exit
Relocate finite-area files to new sub-directory locations
Equivalent options:
| -case=DIR | -case DIR |
USAGE
exit 0 # A clean exit
}
# Report error and exit
die()
{
exec 1>&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
#------------------------------------------------------------------------------

View File

@ -512,7 +512,7 @@ void Foam::interfaceTrackingFvMesh::makeBulkSurfactConc() const
mesh().time().startTime().value() mesh().time().startTime().value()
), ),
// mesh().time().timeName(), // mesh().time().timeName(),
aMesh().thisDb(), mesh(),
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::AUTO_WRITE IOobject::AUTO_WRITE
), ),

View File

@ -1,4 +1,6 @@
faMesh/faGlobalMeshData/faGlobalMeshData.C faMesh/faGlobalMeshData/faGlobalMeshData.C
faMesh/faMeshesRegistry.C
faMesh/faMeshRegistry.C
faMesh/faMesh.C faMesh/faMesh.C
faMesh/faMeshNew.C faMesh/faMeshNew.C
faMesh/faMeshDemandDrivenData.C faMesh/faMeshDemandDrivenData.C

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2020-2023 OpenCFD Ltd. Copyright (C) 2020-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. 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) const int Foam::faMesh::quadricsFit_ = 0; // Tuning (experimental)
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * 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) const Foam::objectRegistry* Foam::faMesh::registry(const polyMesh& pMesh)
{ {
// This will change in the near future return pMesh.cfindObject<objectRegistry>(faMesh::prefix());
return &static_cast<const objectRegistry&>(pMesh);
} }
// const Foam::objectRegistry* Foam::faMesh::registry(const objectRegistry& obr)
// {
// return obr.cfindObject<objectRegistry>(faMesh::prefix());
// }
const Foam::faMesh& Foam::faMesh::mesh const Foam::faMesh& Foam::faMesh::mesh
( (
const polyMesh& pMesh const polyMesh& pMesh
) )
{ {
// This will change in the near future return faMesh::mesh(pMesh, polyMesh::defaultRegion);
return pMesh.lookupObject<faMesh>("faMesh"); }
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<faMesh>(polyMesh::defaultRegion);
}
return obr->lookupObject<faMesh>(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<IOobjectOption>(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 faMesh
( (
meshName,
baseMesh, baseMesh,
labelList(), std::move(faceLabels),
IOobjectOption(IOobjectOption::NO_READ, IOobjectOption::NO_WRITE) static_cast<IOobjectOption>(baseMesh.thisDb())
)
{}
Foam::faMesh::faMesh
(
const faMesh& baseMesh,
labelList&& faceLabels
)
:
faMesh
(
polyMesh::defaultRegion,
baseMesh,
std::move(faceLabels),
static_cast<IOobjectOption>(baseMesh.thisDb())
) )
{} {}
@ -360,13 +532,78 @@ Foam::faMesh::faMesh(const faMesh& baseMesh, const Foam::zero)
Foam::faMesh::faMesh Foam::faMesh::faMesh
( (
const polyMesh& pMesh, 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 const bool doInit
) )
: :
MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(pMesh), faMesh(polyMesh::defaultRegion, pp, doInit)
faSchemes(mesh()), {}
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), edgeInterpolation(*this),
faSolution(mesh()),
faceLabels_ faceLabels_
( (
IOobject IOobject
@ -418,7 +655,7 @@ Foam::faMesh::faMesh
IOobject rio IOobject rio
( (
"name", "any-name",
time().timeName(), time().timeName(),
faMesh::meshSubDir, faMesh::meshSubDir,
faMesh::thisDb(), faMesh::thisDb(),
@ -444,36 +681,29 @@ Foam::faMesh::faMesh
Foam::faMesh::faMesh Foam::faMesh::faMesh
( (
const word& meshName,
const polyMesh& pMesh, const polyMesh& pMesh,
labelList&& faceLabels labelList&& faceLabels
) )
: :
faMesh faMeshRegistry(meshName, pMesh),
faSchemes
( (
pMesh, faMesh::thisDb(),
std::move(faceLabels), IOobjectOption::MUST_READ
static_cast<IOobjectOption>(pMesh) ),
) faSolution
{} (
faMesh::thisDb(),
IOobjectOption::MUST_READ
Foam::faMesh::faMesh ),
(
const polyMesh& pMesh,
labelList&& faceLabels,
IOobjectOption ioOpt
)
:
MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(pMesh),
faSchemes(mesh(), ioOpt.readOpt()),
edgeInterpolation(*this), edgeInterpolation(*this),
faSolution(mesh(), ioOpt.readOpt()),
faceLabels_ faceLabels_
( (
IOobject IOobject
( (
"faceLabels", "faceLabels",
mesh().facesInstance(), pMesh.facesInstance(),
faMesh::meshSubDir, faMesh::meshSubDir,
faMesh::thisDb(), faMesh::thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
@ -486,14 +716,14 @@ Foam::faMesh::faMesh
IOobject IOobject
( (
"faBoundary", "faBoundary",
mesh().facesInstance(), faceLabels_.instance(),
faMesh::meshSubDir, faMesh::meshSubDir,
faMesh::thisDb(), faMesh::thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
*this, *this,
label(0) Foam::zero{}
), ),
comm_(UPstream::worldComm), comm_(UPstream::worldComm),
curTimeIndex_(time().timeIndex()) curTimeIndex_(time().timeIndex())
@ -503,36 +733,103 @@ Foam::faMesh::faMesh
nEdges_ = 0; nEdges_ = 0;
nInternalEdges_ = 0; nInternalEdges_ = 0;
nFaces_ = faceLabels_.size(); nFaces_ = faceLabels_.size();
}
// TDB: can we make a NO_READ readOption persistent for
// faSchemes/faSolution? Or not needed anymore?
}
Foam::faMesh::faMesh 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, const faMesh& baseMesh,
labelList&& faceLabels, labelList&& faceLabels,
IOobjectOption ioOpt IOobjectOption ioOpt
) )
: :
MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(baseMesh.mesh()), faMeshRegistry(meshName, baseMesh.mesh()),
faSchemes faSchemes
( (
faMesh::thisDb(), faMesh::thisDb(),
ioOpt.readOpt(), ioOpt.readOpt(),
static_cast<const dictionary*>(baseMesh.hasSchemes()) static_cast<const dictionary*>(baseMesh.hasSchemes())
), ),
edgeInterpolation(*this),
faSolution faSolution
( (
faMesh::thisDb(), faMesh::thisDb(),
ioOpt.readOpt(), ioOpt.readOpt(),
static_cast<const dictionary*>(baseMesh.hasSolution()) static_cast<const dictionary*>(baseMesh.hasSolution())
), ),
edgeInterpolation(*this),
faceLabels_ faceLabels_
( (
IOobject IOobject
( (
"faceLabels", "faceLabels",
mesh().facesInstance(), // Topological instance from polyMesh
baseMesh.mesh().facesInstance(),
faMesh::meshSubDir, faMesh::meshSubDir,
faMesh::thisDb(), faMesh::thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
@ -545,14 +842,14 @@ Foam::faMesh::faMesh
IOobject IOobject
( (
"faBoundary", "faBoundary",
mesh().facesInstance(), faceLabels_.instance(),
faMesh::meshSubDir, faMesh::meshSubDir,
faMesh::thisDb(), faMesh::thisDb(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
*this, *this,
label(0) Foam::zero{}
), ),
comm_(UPstream::worldComm), comm_(UPstream::worldComm),
curTimeIndex_(time().timeIndex()) 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 faMesh
( (
meshName,
pp.boundaryMesh().mesh(), pp.boundaryMesh().mesh(),
identity(pp.range()) identity(pp.range())
) )
@ -594,6 +897,7 @@ Foam::faMesh::faMesh(const polyPatch& pp, const bool doInit)
Foam::faMesh::faMesh Foam::faMesh::faMesh
( (
const word& meshName,
const polyMesh& pMesh, const polyMesh& pMesh,
const dictionary& faMeshDefinition, const dictionary& faMeshDefinition,
const bool doInit const bool doInit
@ -601,6 +905,7 @@ Foam::faMesh::faMesh
: :
faMesh faMesh
( (
meshName,
pMesh, pMesh,
selectPatchFaces selectPatchFaces
( (
@ -639,7 +944,7 @@ Foam::faMesh::faMesh
IOobject rio IOobject rio
( (
"name", "any-name",
time().timeName(), time().timeName(),
faMesh::meshSubDir, faMesh::meshSubDir,
faMesh::thisDb(), faMesh::thisDb(),
@ -709,15 +1014,21 @@ Foam::faSolution& Foam::faMesh::solution()
} }
const Foam::polyMesh& Foam::faMesh::mesh() const
{
return refCast<const polyMesh>(faMeshRegistry::parent().parent());
}
Foam::fileName Foam::faMesh::meshDir() const Foam::fileName Foam::faMesh::meshDir() const
{ {
return mesh().dbDir()/faMesh::meshSubDir; return dbDir()/faMesh::meshSubDir;
} }
const Foam::Time& Foam::faMesh::time() const 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 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", "S00",
time().timeName(), time().timeName(),
faMesh::thisDb(), *this,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
@ -1008,7 +1307,7 @@ bool Foam::faMesh::movePoints()
( (
"S0", "S0",
time().timeName(), time().timeName(),
faMesh::thisDb(), *this,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021-2023 OpenCFD Ltd. Copyright (C) 2021-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -56,7 +56,6 @@ Author
#ifndef Foam_faMesh_H #ifndef Foam_faMesh_H
#define Foam_faMesh_H #define Foam_faMesh_H
#include "MeshObject.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "lduMesh.H" #include "lduMesh.H"
#include "faBoundaryMesh.H" #include "faBoundaryMesh.H"
@ -85,17 +84,52 @@ class faMeshLduAddressing;
class faMeshMapper; class faMeshMapper;
class faPatchData; 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 Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class faMesh class faMesh
: :
public MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>, public faMeshRegistry,
public lduMesh, public lduMesh,
public faSchemes, public faSchemes,
public edgeInterpolation, // may need input from faSchemes public faSolution,
public faSolution public edgeInterpolation // may need input from faSchemes
{ {
// Private (internal) classes/structures // Private (internal) classes/structures
@ -327,6 +361,9 @@ class faMesh
// Static Private Data // Static Private Data
//- The prefix to local: %finite-area
static const word prefix_;
//- Quadrics fit for pointAreaNormals (experimental) //- Quadrics fit for pointAreaNormals (experimental)
static const int quadricsFit_; static const int quadricsFit_;
@ -356,7 +393,7 @@ class faMesh
) const; ) const;
// Private member functions to calculate demand driven data // Private Member Functions to calculate demand driven data
//- Calculate ldu addressing //- Calculate ldu addressing
void calcLduAddressing() const; void calcLduAddressing() const;
@ -486,11 +523,18 @@ class faMesh
// Static Functions // Static Functions
//- Test if faSchemes/faSolution files are available //- Test if faSchemes/faSolution files are available
static bool hasSystemFiles(const polyMesh& pMesh); static bool hasSystemFiles
(
//- Test if all files needed for read construction are available const word& meshName,
static bool hasFiles(const polyMesh& pMesh); const polyMesh& pMesh
);
//- Test if mesh files needed for read construction are available
static bool hasMeshFiles
(
const word& meshName,
const polyMesh& pMesh
);
public: public:
@ -512,8 +556,8 @@ public:
//- Runtime type information //- Runtime type information
TypeName("faMesh"); TypeName("faMesh");
//- The prefix to local: %finite-area //- The prefix to the parent registry name: %finite-area
static const word prefix; static const word& prefix() noexcept;
//- The mesh sub-directory name (usually "faMesh") //- The mesh sub-directory name (usually "faMesh")
static word meshSubDir; static word meshSubDir;
@ -530,29 +574,27 @@ public:
// Constructors // Constructors
//- Read construct from polyMesh, using its IOobject properties //- Construct zero-sized from polyMesh
explicit faMesh(const polyMesh& pMesh, const bool doInit = true); // Boundary is added using addFaPatches() member function
faMesh(const word& meshName, const polyMesh&, Foam::zero);
//- Construct zero-sized from polyMesh //- Construct zero-sized from polyMesh
// Boundary is added using addFaPatches() member function // 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 //- Read construct from polyMesh, using its IOobject properties
//- without boundary. faMesh(const word& meshName, const polyMesh&, const bool doInit = true);
// Boundary is added using addFaPatches() member function
faMesh(const faMesh& baseMesh, const Foam::zero);
//- Construct as copy (for dictionaries) and faceLabels //- Read construct from polyMesh, using its IOobject properties
//- without boundary, using read properties from baseMesh. explicit faMesh(const polyMesh&, const bool doInit = true);
// Boundary is added using addFaPatches() member function
faMesh(const faMesh& baseMesh, labelList&& faceLabels);
//- Construct as copy (for dictionaries) and faceLabels //- Construct from components (face labels) without boundary,
//- without boundary, using specified read properties. //- using specified read properties.
// Boundary is added using addFaPatches() member function. // Boundary is added using addFaPatches() member function.
faMesh faMesh
( (
const faMesh& baseMesh, const word& meshName,
const polyMesh& pMesh,
labelList&& faceLabels, labelList&& faceLabels,
IOobjectOption ioOpt IOobjectOption ioOpt
); );
@ -560,21 +602,84 @@ public:
//- Construct from components (face labels) without boundary, //- Construct from components (face labels) without boundary,
//- using IOobject properties from polyMesh. //- using IOobject properties from polyMesh.
// Boundary is added using addFaPatches() member function. // 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, //- Construct from components (face labels) without boundary,
//- using specified read properties. //- using specified read properties.
// Boundary is added using addFaPatches() member function. // 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 faMesh
( (
const polyMesh& pMesh, const word& meshName,
const faMesh& baseMesh,
labelList&& faceLabels, labelList&& faceLabels,
IOobjectOption ioOpt 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 //- Construct from single polyPatch
explicit faMesh(const polyPatch& pp, const bool doInit = true); 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 //- Construct from definition
faMesh faMesh
( (
@ -606,6 +711,13 @@ public:
return old; return old;
} }
//- Read construction from polyMesh if all files are available
static autoPtr<faMesh> TryNew
(
const word& meshName,
const polyMesh& pMesh
);
//- Read construction from polyMesh if all files are available //- Read construction from polyMesh if all files are available
static autoPtr<faMesh> TryNew(const polyMesh& pMesh); static autoPtr<faMesh> TryNew(const polyMesh& pMesh);
@ -646,8 +758,12 @@ public:
//- Uses lookupObject semantics - Fatal if non-existent //- Uses lookupObject semantics - Fatal if non-existent
static const faMesh& mesh(const polyMesh& pMesh); 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 //- Return access to polyMesh
inline const polyMesh& mesh() const; const polyMesh& mesh() const;
//- Return the local mesh directory (dbDir()/meshSubDir) //- Return the local mesh directory (dbDir()/meshSubDir)
fileName meshDir() const; fileName meshDir() const;
@ -751,22 +867,64 @@ public:
// Database // Database
//- Return true if thisDb() is a valid DB //- True - thisDb() is a valid registry
virtual bool hasDb() const; virtual bool hasDb() const { return true; }
//- Return reference to the mesh database //- Reference to the mesh database
virtual const objectRegistry& thisDb() const; 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 //- Name function is needed to disambiguate those inherited
//- from base classes //- from base classes
const word& name() const const word& name() const
{ {
return thisDb().name(); return faMeshRegistry::thisDb().name();
} }
// Regions // 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 //- The mesh region name or word::null if polyMesh::defaultRegion
const word& regionName() const; const word& regionName() const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021-2022 OpenCFD Ltd. Copyright (C) 2021-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,13 +28,6 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::polyMesh& Foam::faMesh::mesh() const
{
return
MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>::mesh();
}
inline const Foam::faBoundaryMesh& Foam::faMesh::boundary() const noexcept inline const Foam::faBoundaryMesh& Foam::faMesh::boundary() const noexcept
{ {
return boundary_; return boundary_;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd. Copyright (C) 2022-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,11 +31,34 @@ License
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
bool Foam::faMesh::hasSystemFiles(const polyMesh& pMesh) bool Foam::faMesh::hasSystemFiles
(
const word& meshName,
const polyMesh& pMesh
)
{ {
// Expect // Expect
// - system/faSchemes // - system/finite-area/<region>/faSchemes
// - system/faSolution // - system/finite-area/<region>/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(); const fileOperation& fp = Foam::fileHandler();
@ -52,20 +75,14 @@ bool Foam::faMesh::hasSystemFiles(const polyMesh& pMesh)
}) })
) )
{ {
systemIOobject.resetHeader(expect);
fileName found fileName found
( (
fp.filePath fp.filePath
( (
true, // global true, // global
IOobject systemIOobject,
(
expect,
pMesh.time().system(),
pMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
expect // typeName (ununsed?) 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: // expect these:
// - instance/faMesh/faceLabels // - instance/finite-area/<region>/faMesh/faceLabels
// - instance/faMesh/faBoundary // - instance/finite-area/<region>/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) if (looksValid)
{ {
DebugInfo<< "check mesh files: " << relativeDir << nl;
const fileOperation& fp = Foam::fileHandler(); const fileOperation& fp = Foam::fileHandler();
// The geometry instance for faMesh/faceLabels // The geometry instance for faMesh/faceLabels
@ -102,11 +135,23 @@ bool Foam::faMesh::hasFiles(const polyMesh& pMesh)
const word instance = pMesh.time().findInstance const word instance = pMesh.time().findInstance
( (
pMesh.dbDir()/faMesh::meshSubDir, // Searching from Time, so need polyMesh region too
pMesh.regionName()/relativeDir,
"faceLabels", "faceLabels",
IOobject::READ_IF_PRESENT IOobject::READ_IF_PRESENT
); );
IOobject meshIOobject
(
"any-name",
instance,
relativeDir,
pMesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
for for
( (
const wordPair& expect const wordPair& expect
@ -120,21 +165,14 @@ bool Foam::faMesh::hasFiles(const polyMesh& pMesh)
const word& dataFile = expect.first(); const word& dataFile = expect.first();
const word& dataClass = expect.second(); const word& dataClass = expect.second();
meshIOobject.resetHeader(dataFile);
fileName found fileName found
( (
fp.filePath fp.filePath
( (
false, // non-global false, // non-global
IOobject meshIOobject,
(
dataFile,
instance,
faMesh::meshSubDir,
pMesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
dataClass // typeName (ununsed?) dataClass // typeName (ununsed?)
) )
); );
@ -153,15 +191,28 @@ bool Foam::faMesh::hasFiles(const polyMesh& pMesh)
} }
Foam::autoPtr<Foam::faMesh> Foam::faMesh::TryNew(const polyMesh& pMesh) Foam::autoPtr<Foam::faMesh> Foam::faMesh::TryNew
(
const word& meshName,
const polyMesh& pMesh
)
{ {
if (faMesh::hasFiles(pMesh)) if (faMesh::hasMeshFiles(meshName, pMesh))
{ {
return autoPtr<faMesh>::New(pMesh); return autoPtr<faMesh>::New(meshName, pMesh);
} }
return nullptr; return nullptr;
} }
Foam::autoPtr<Foam::faMesh> Foam::faMesh::TryNew
(
const polyMesh& pMesh
)
{
return TryNew(polyMesh::defaultRegion, pMesh);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#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();
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd. Copyright (C) 2015-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -77,12 +77,10 @@ Foam::faMeshTools::newMesh
const bool verbose const bool verbose
) )
{ {
// Region name // The mesh directory (assuming single area region), relative to Time
// ~~~~~~~~~~~
const fileName meshSubDir const fileName meshSubDir
( (
pMesh.regionName() / faMesh::meshSubDir faMesh::meshDir(pMesh, word::null)
); );
@ -111,7 +109,7 @@ Foam::faMeshTools::newMesh
"faBoundary", "faBoundary",
facesInstance, facesInstance,
meshSubDir, meshSubDir,
io.db(), io.time(),
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER
@ -133,15 +131,15 @@ Foam::faMeshTools::newMesh
// Dummy meshes // Dummy meshes
// ~~~~~~~~~~~~ // ~~~~~~~~~~~~
// Set up to read-if-present. Note: does not search for mesh so set // Fake read-if-present behaviour to obtain the faceLabels
// instance explicitly
IOobject meshIO(io); IOobject meshIO(io);
meshIO.instance() = facesInstance; meshIO.instance() = facesInstance;
meshIO.readOpt(IOobject::READ_IF_PRESENT); meshIO.readOpt(IOobject::READ_IF_PRESENT);
// For mesh components (faceLabels, ...) // For mesh components (faceLabels, ...)
IOobject cmptIO(meshIO, "faceLabels", meshSubDir); IOobject cmptIO(io.time(), "faceLabels", meshSubDir);
cmptIO.instance() = facesInstance;
cmptIO.readOpt(IOobject::MUST_READ); cmptIO.readOpt(IOobject::MUST_READ);
cmptIO.writeOpt(IOobject::NO_WRITE); cmptIO.writeOpt(IOobject::NO_WRITE);
cmptIO.registerObject(IOobject::NO_REGISTER); cmptIO.registerObject(IOobject::NO_REGISTER);
@ -261,12 +259,10 @@ Foam::faMeshTools::loadOrCreateMeshImpl
const bool verbose const bool verbose
) )
{ {
// Region name // The mesh directory (assuming single area region), relative to Time
// ~~~~~~~~~~~
const fileName meshSubDir const fileName meshSubDir
( (
pMesh.regionName() / faMesh::meshSubDir faMesh::meshDir(pMesh, word::null)
); );
@ -288,7 +284,7 @@ Foam::faMeshTools::loadOrCreateMeshImpl
"faBoundary", "faBoundary",
io.instance(), io.instance(),
meshSubDir, meshSubDir,
io.db(), io.time(),
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER
@ -359,7 +355,7 @@ Foam::faMeshTools::loadOrCreateMeshImpl
new faMesh new faMesh
( (
pMesh, pMesh,
labelList(), labelList(), // Similar to Foam::zero{}
IOobject(io, IOobject::NO_READ, IOobject::AUTO_WRITE) IOobject(io, IOobject::NO_READ, IOobject::AUTO_WRITE)
) )
); );

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022-2023 OpenCFD Ltd. Copyright (C) 2022-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -99,6 +99,7 @@ public:
// if not present // if not present
static autoPtr<faMesh> newMesh static autoPtr<faMesh> newMesh
( (
//! The IOobject describes the base polyMesh
const IOobject& io, const IOobject& io,
const polyMesh& pMesh, const polyMesh& pMesh,
const bool masterOnlyReading, const bool masterOnlyReading,
@ -111,6 +112,7 @@ public:
// - io.instance() set to facesInstance // - io.instance() set to facesInstance
static autoPtr<faMesh> loadOrCreateMesh static autoPtr<faMesh> loadOrCreateMesh
( (
//! The IOobject describes the base polyMesh
const IOobject& io, const IOobject& io,
const polyMesh& pMesh, const polyMesh& pMesh,
const bool decompose, const bool decompose,
@ -123,6 +125,7 @@ public:
// - io.instance() set to facesInstance // - io.instance() set to facesInstance
static autoPtr<faMesh> loadOrCreateMesh static autoPtr<faMesh> loadOrCreateMesh
( (
//! The IOobject describes the base polyMesh
const IOobject& io, const IOobject& io,
const polyMesh& pMesh, const polyMesh& pMesh,
//! Non-null reference if a mesh exists on given processor //! Non-null reference if a mesh exists on given processor

View File

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#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<faMesh>())
{
m.movePoints();
}
return true;
}
void Foam::faMeshesRegistry::updateMesh(const mapPolyMesh& mpm)
{
for (faMesh& m : objects_.sorted<faMesh>())
{
m.updateMesh(mpm);
}
}
bool Foam::faMeshesRegistry::writeObject
(
IOstreamOption streamOpt,
const bool writeOnProc
) const
{
// for (const faMesh& m : objects_.csorted<faMesh>())
// {
// m.write(writeOnProc);
// }
//
// return true;
return objects_.writeObject(streamOpt, writeOnProc);
}
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
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<polyMesh, UpdateableMeshObject, faMeshesRegistry>
{
// 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
// ************************************************************************* //

View File

@ -74,55 +74,70 @@ void sensitivitySurface::smoothSensitivities()
// Read in parameters // Read in parameters
const label iters(dict().getOrDefault<label>("iters", 500)); const label iters(dict().getOrDefault<label>("iters", 500));
const scalar tolerance(dict().getOrDefault<scalar>("tolerance", 1.e-06)); const scalar tolerance(dict().getOrDefault<scalar>("tolerance", 1.e-06));
autoPtr<faMesh> aMeshPtr(nullptr);
IOobject faceLabels autoPtr<faMesh> aMeshPtr = faMesh::TryNew(mesh_);
(
"faceLabels",
mesh_.time().findInstance
(
mesh_.dbDir()/faMesh::meshSubDir,
"faceLabels",
IOobject::READ_IF_PRESENT
),
faMesh::meshSubDir,
mesh_,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
);
// If the faMesh already exists, read it if (aMeshPtr)
if (faceLabels.typeHeaderOk<labelIOList>(false))
{ {
Info<< "Reading the already constructed faMesh" << endl; Info<< "Loaded the existing faMesh" << nl;
aMeshPtr.reset(new faMesh(mesh_));
} }
else else
{ {
// Dictionary used to construct the faMesh // Dictionary used to construct the faMesh
dictionary faMeshDefinition; dictionary faMeshDefinition;
IOobject faMeshDefinitionDict // Check and read system/faMeshDefinition
{
IOobject io
( (
"faMeshDefinition", "faMeshDefinition",
mesh_.time().caseSystem(), mesh_.time().caseSystem(),
mesh_, mesh_,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE IOobject::NO_WRITE,
IOobject::NO_REGISTER
); );
// If the faMeshDefinitionDict exists, use it to construct the mesh if (io.typeHeaderOk<IOdictionary>(false))
if (faMeshDefinitionDict.typeHeaderOk<IOdictionary>(false))
{ {
Info<< "Reading faMeshDefinition from system " << endl; Info<< "Using system/faMeshDefinition" << nl;
faMeshDefinition = IOdictionary(faMeshDefinitionDict); faMeshDefinition = IOdictionary(io);
} }
// Otherwise, faMesh is generated from all patches on which we compute else if (debug)
// sensitivities {
else Info<< "No " << io.name() << " in " << io.path() << nl;
}
}
// Check and read system/finite-area/faMeshDefinition
if (faMeshDefinition.empty())
{
IOobject io
(
"faMeshDefinition",
mesh_.time().caseSystem()/faMesh::prefix(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
if (io.typeHeaderOk<IOdictionary>(false))
{
Info<< "Using system/finite-area/faMeshDefinition" << nl;
faMeshDefinition = IOdictionary(io);
}
else if (debug)
{
Info<< "No " << io.name() << " in " << io.path() << nl;
}
}
// No specified faMeshDefinition?
// - generate faMesh from all patches on which we compute sensitivities
if (faMeshDefinition.empty())
{ {
Info<< "Constructing faMeshDefinition from sensitivity patches"
<< endl;
wordList polyMeshPatches(sensitivityPatchIDs_.size()); wordList polyMeshPatches(sensitivityPatchIDs_.size());
label i(0); label i(0);
for (const label patchID : sensitivityPatchIDs_) for (const label patchID : sensitivityPatchIDs_)
@ -131,13 +146,22 @@ void sensitivitySurface::smoothSensitivities()
} }
faMeshDefinition.add<wordList>("polyMeshPatches", polyMeshPatches); faMeshDefinition.add<wordList>("polyMeshPatches", polyMeshPatches);
(void)faMeshDefinition.subDictOrAdd("boundary"); (void)faMeshDefinition.subDictOrAdd("boundary");
Info<< faMeshDefinition << endl;
// TBD: Place all edges into the "defaultPatch" ?
// faMeshDefinition.subDictOrAdd("defaultPatch")
// .add("name", "undefined");
Info<< "Create faMeshDefinition from sensitivity patches"
<< nl << nl;
faMeshDefinition.writeEntry("faMeshDefinition", Info);
} }
// Construct faMesh // Construct faMesh from faMeshDefinition
aMeshPtr.reset(new faMesh(mesh_, faMeshDefinition)); aMeshPtr.reset(new faMesh(mesh_, faMeshDefinition));
} }
faMesh& aMesh = aMeshPtr.ref(); faMesh& aMesh = *aMeshPtr;
// Physical radius of the smoothing, provided either directly or computed // Physical radius of the smoothing, provided either directly or computed
// based on the average 'length' of boundary faces // based on the average 'length' of boundary faces
@ -154,7 +178,7 @@ void sensitivitySurface::smoothSensitivities()
"RpdeSqr", dimArea, sqr(Rphysical/(2.*::sqrt(3.))) "RpdeSqr", dimArea, sqr(Rphysical/(2.*::sqrt(3.)))
); );
dimensionedScalar one("1", dimless, 1.); dimensionedScalar one(dimless, Foam::one{});
// Mapping engine // Mapping engine
volSurfaceMapping vsm(aMesh); volSurfaceMapping vsm(aMesh);
@ -162,16 +186,9 @@ void sensitivitySurface::smoothSensitivities()
// Source term in faMatrix needs to be an areaField // Source term in faMatrix needs to be an areaField
areaVectorField sens areaVectorField sens
( (
IOobject aMesh.newIOobject("sens"),
(
"sens",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
aMesh, aMesh,
dimensionedVector(dimless, Zero), dimensionedVector(dimless, Foam::zero{}),
faPatchFieldBase::zeroGradientType() faPatchFieldBase::zeroGradientType()
); );
@ -220,14 +237,7 @@ void sensitivitySurface::smoothSensitivities()
// Write normal, regularised sensitivities to file // Write normal, regularised sensitivities to file
volScalarField volSmoothedSens volScalarField volSmoothedSens
( (
IOobject mesh_.newIOobject("smoothedSurfaceSens" + suffix_),
(
"smoothedSurfaceSens" + suffix_,
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_, mesh_,
dimensionedScalar(dimless, Zero) dimensionedScalar(dimless, Zero)
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -129,16 +129,11 @@ tmp<scalarField> curvatureSeparation::calcCosAngle
// checks // checks
if (debug && mesh.time().writeTime()) if (debug && mesh.time().writeTime())
{
{ {
areaScalarField volCosAngle areaScalarField volCosAngle
( (
IOobject mesh.newIOobject("cosAngle"),
(
"cosAngle",
mesh.time().timeName(),
mesh.thisDb(),
IOobject::NO_READ
),
mesh, mesh,
dimensionedScalar(dimless, Zero) dimensionedScalar(dimless, Zero)
); );
@ -146,6 +141,7 @@ tmp<scalarField> curvatureSeparation::calcCosAngle
volCosAngle.correctBoundaryConditions(); volCosAngle.correctBoundaryConditions();
volCosAngle.write(); volCosAngle.write();
} }
}
return clamp(cosAngle, scalarMinMax(-1, 1)); return clamp(cosAngle, scalarMinMax(-1, 1));
} }
@ -248,67 +244,51 @@ void curvatureSeparation::correct
addToInjectedMass(sum(massToInject)); addToInjectedMass(sum(massToInject));
if (debug && mesh.time().writeTime()) if (debug && mesh.time().writeTime())
{
{ {
areaScalarField volFnet areaScalarField volFnet
( (
IOobject mesh.newIOobject("Fnet"),
(
"Fnet",
mesh.time().timeName(),
mesh.thisDb(),
IOobject::NO_READ
),
mesh, mesh,
dimensionedScalar(dimForce, Zero) dimensionedScalar(dimForce, Zero)
); );
volFnet.primitiveFieldRef() = Fnet; volFnet.primitiveFieldRef() = Fnet;
volFnet.write(); volFnet.write();
}
{
areaScalarField areaSeparated areaScalarField areaSeparated
( (
IOobject mesh.newIOobject("separated"),
(
"separated",
mesh.time().timeName(),
mesh.thisDb(),
IOobject::NO_READ
),
mesh, mesh,
dimensionedScalar(dimMass, Zero) dimensionedScalar(dimMass, Zero)
); );
areaSeparated.primitiveFieldRef() = separated; areaSeparated.primitiveFieldRef() = separated;
areaSeparated.write(); areaSeparated.write();
}
{
areaScalarField areaMassToInject areaScalarField areaMassToInject
( (
IOobject mesh.newIOobject("massToInject"),
(
"massToInject",
mesh.time().timeName(),
mesh.thisDb(),
IOobject::NO_READ
),
mesh, mesh,
dimensionedScalar(dimMass, Zero) dimensionedScalar(dimMass, Zero)
); );
areaMassToInject.primitiveFieldRef() = massToInject; areaMassToInject.primitiveFieldRef() = massToInject;
areaMassToInject.write(); areaMassToInject.write();
}
{
areaScalarField areaInvR1 areaScalarField areaInvR1
( (
IOobject mesh.newIOobject("InvR1"),
(
"InvR1",
mesh.time().timeName(),
mesh.thisDb(),
IOobject::NO_READ
),
mesh, mesh,
dimensionedScalar(inv(dimLength), Zero) dimensionedScalar(inv(dimLength), Zero)
); );
areaInvR1.primitiveFieldRef() = invR1; areaInvR1.primitiveFieldRef() = invR1;
areaInvR1.write(); areaInvR1.write();
} }
}
injectionModel::correct(); injectionModel::correct();
} }