Compare commits
3 Commits
multi-fini
...
feature-pr
| Author | SHA1 | Date | |
|---|---|---|---|
| 460f1478be | |||
| 29813b0e96 | |||
| 6cadf3116f |
@ -49,7 +49,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "mesh 0: " << mesh.sortedNames() << nl;
|
||||
|
||||
auto& reg = const_cast<faMeshesRegistry&>(faMeshesRegistry::New(mesh));
|
||||
faMeshesRegistry& reg =
|
||||
const_cast<faMeshesRegistry&>(faMeshesRegistry::New(mesh));
|
||||
|
||||
// faMeshesRegistry faReg = faMeshesRegistry(mesh);
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
foamToEnsight-check.cxx
|
||||
foamToEnsight-check.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/foamToEnsight-check
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -203,7 +203,6 @@ int main(int argc, char *argv[])
|
||||
argList::addVerboseOption();
|
||||
|
||||
#include "addAllRegionOptions.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -252,14 +251,6 @@ int main(int argc, char *argv[])
|
||||
// Handle -allRegions, -regions, -region
|
||||
#include "getAllRegionOptions.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
#include "createNamedMeshes.H"
|
||||
@ -268,8 +259,8 @@ int main(int argc, char *argv[])
|
||||
/// #include "createMeshAccounting.H"
|
||||
|
||||
PtrList<ensightMesh> ensightMeshes(regionNames.size());
|
||||
List<PtrList<faMesh>> meshesFa(regionNames.size());
|
||||
List<PtrList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
||||
PtrList<faMesh> meshesFa(regionNames.size());
|
||||
PtrList<ensightFaMesh> ensightMeshesFa(regionNames.size());
|
||||
|
||||
forAll(regionNames, regioni)
|
||||
{
|
||||
@ -282,32 +273,21 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
ensightMeshes[regioni].verbose(optVerbose);
|
||||
|
||||
if (!doFiniteArea)
|
||||
|
||||
if (doFiniteArea)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
meshesFa[regioni].resize_null(areaRegionNames.size());
|
||||
ensightMeshesFa[regioni].resize_null(areaRegionNames.size());
|
||||
|
||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
|
||||
|
||||
forAll(areaRegionNames, areai)
|
||||
{
|
||||
const word& areaName = areaRegionNames[areai];
|
||||
|
||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(areaName, mesh));
|
||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
|
||||
|
||||
if (faMeshPtr)
|
||||
{
|
||||
meshesFa[regioni].set(areai, std::move(faMeshPtr));
|
||||
meshesFa.set(regioni, std::move(faMeshPtr));
|
||||
|
||||
ensightMeshesFa[regioni].set
|
||||
ensightMeshesFa.set
|
||||
(
|
||||
areai,
|
||||
new ensightFaMesh(meshesFa[regioni][areai])
|
||||
regioni,
|
||||
new ensightFaMesh(meshesFa[regioni])
|
||||
);
|
||||
ensightMeshesFa[regioni][areai].verbose(optVerbose);
|
||||
ensightMeshesFa[regioni].verbose(optVerbose);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -315,7 +295,7 @@ int main(int argc, char *argv[])
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
if (UPstream::master())
|
||||
if (Pstream::master())
|
||||
{
|
||||
Info<< "Checking " << timeDirs.size() << " time steps" << nl;
|
||||
}
|
||||
@ -337,20 +317,17 @@ int main(int argc, char *argv[])
|
||||
auto& ensMesh = ensightMeshes[regioni];
|
||||
|
||||
// Finite-area (can be missing)
|
||||
auto& ensFaMeshes = ensightMeshesFa[regioni];
|
||||
auto* ensFaMeshPtr = ensightMeshesFa.get(regioni);
|
||||
|
||||
if (moving)
|
||||
{
|
||||
ensMesh.expire();
|
||||
ensMesh.correct();
|
||||
|
||||
forAll(areaRegionNames, areai)
|
||||
if (ensFaMeshPtr)
|
||||
{
|
||||
if (auto* ensFaMeshPtr = ensFaMeshes.get(areai))
|
||||
{
|
||||
ensFaMeshPtr->expire();
|
||||
ensFaMeshPtr->correct();
|
||||
}
|
||||
ensFaMeshPtr->expire();
|
||||
ensFaMeshPtr->correct();
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,15 +340,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
printInfo(ensMesh, optVerbose);
|
||||
|
||||
// finite-area
|
||||
forAll(areaRegionNames, areai)
|
||||
if (ensFaMeshPtr)
|
||||
{
|
||||
auto* ensFaMeshPtr = ensFaMeshes.get(areai);
|
||||
|
||||
if (ensFaMeshPtr)
|
||||
{
|
||||
printInfo(*ensFaMeshPtr, optVerbose);
|
||||
}
|
||||
printInfo(*ensFaMeshPtr, optVerbose);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2017 Wikki Ltd
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,7 +28,7 @@ Application
|
||||
makeFaMesh
|
||||
|
||||
Description
|
||||
Check a finite-area mesh
|
||||
Check a finiteArea mesh
|
||||
|
||||
Original Authors
|
||||
Zeljko Tukovic, FAMENA
|
||||
@ -39,7 +39,6 @@ Original Authors
|
||||
#include "Time.H"
|
||||
#include "argList.H"
|
||||
#include "faMesh.H"
|
||||
#include "faMeshTools.H"
|
||||
#include "polyMesh.H"
|
||||
#include "areaFaMesh.H"
|
||||
#include "edgeFaMesh.H"
|
||||
@ -48,7 +47,7 @@ Original Authors
|
||||
#include "processorFaPatch.H"
|
||||
#include "foamVtkIndPatchWriter.H"
|
||||
#include "foamVtkLineWriter.H"
|
||||
#include "regionProperties.H"
|
||||
#include "faMeshTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -60,7 +59,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"Check a finite-area mesh"
|
||||
"Check a finiteArea mesh"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
@ -78,15 +77,9 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
#include "addRegionOption.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
#include "addFaRegionOption.H"
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
#include "createNamedPolyMesh.H"
|
||||
|
||||
int geometryOrder(1);
|
||||
@ -98,41 +91,16 @@ int main(int argc, char *argv[])
|
||||
faMesh::geometryOrder(geometryOrder);
|
||||
}
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
#include "createNamedFaMesh.H"
|
||||
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
// Mesh information (verbose)
|
||||
faMeshTools::printMeshChecks(aMesh);
|
||||
|
||||
if (args.found("write-vtk"))
|
||||
{
|
||||
Info<< "Create faMesh";
|
||||
if (!polyMesh::regionName(areaName).empty())
|
||||
{
|
||||
Info<< " [" << areaName << "]";
|
||||
}
|
||||
Info<< " for time = " << runTime.timeName() << nl;
|
||||
|
||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(areaName, mesh));
|
||||
|
||||
if (!faMeshPtr)
|
||||
{
|
||||
Info<< " ...failed to create area-mesh";
|
||||
if (!polyMesh::regionName(areaName).empty())
|
||||
{
|
||||
Info<< " [" << areaName << "]";
|
||||
}
|
||||
Info<< endl;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
const auto& aMesh = faMeshPtr();
|
||||
|
||||
// Mesh information (verbose)
|
||||
faMeshTools::printMeshChecks(aMesh);
|
||||
|
||||
if (args.found("write-vtk"))
|
||||
{
|
||||
#include "faMeshWriteVTK.H"
|
||||
}
|
||||
#include "faMeshWriteVTK.H"
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
@ -15,16 +15,6 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// The base name for output files
|
||||
word vtkBaseFileName(aMesh.regionName());
|
||||
if (polyMesh::regionName(vtkBaseFileName).empty())
|
||||
{
|
||||
vtkBaseFileName = "finiteArea";
|
||||
}
|
||||
|
||||
Info<< nl;
|
||||
Info<< "Write faMesh in vtk format:" << nl;
|
||||
|
||||
{
|
||||
// finiteArea - faces
|
||||
vtk::uindirectPatchWriter writer
|
||||
@ -33,7 +23,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
// vtk::formatType::INLINE_ASCII,
|
||||
fileName
|
||||
(
|
||||
aMesh.time().globalPath() / vtkBaseFileName
|
||||
aMesh.time().globalPath() / "finiteArea"
|
||||
)
|
||||
);
|
||||
|
||||
@ -42,7 +32,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
globalIndex procAddr(aMesh.nFaces());
|
||||
labelList cellIDs;
|
||||
|
||||
if (UPstream::master())
|
||||
if (Pstream::master())
|
||||
{
|
||||
cellIDs.resize(procAddr.totalSize());
|
||||
for (const labelRange& range : procAddr.ranges())
|
||||
@ -63,7 +53,8 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
writer.beginPointData(1);
|
||||
writer.write("normal", aMesh.pointAreaNormals());
|
||||
|
||||
Info<< " " << writer.output().name() << nl;
|
||||
Info<< nl
|
||||
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
|
||||
}
|
||||
|
||||
{
|
||||
@ -75,7 +66,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
// vtk::formatType::INLINE_ASCII,
|
||||
fileName
|
||||
(
|
||||
aMesh.time().globalPath() / (vtkBaseFileName + "-edges")
|
||||
aMesh.time().globalPath() / "finiteArea-edges"
|
||||
)
|
||||
);
|
||||
|
||||
@ -97,7 +88,8 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
writer.beginPointData(1);
|
||||
writer.write("normal", aMesh.pointAreaNormals());
|
||||
|
||||
Info<< " " << writer.output().name() << nl;
|
||||
Info<< nl
|
||||
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
|
||||
}
|
||||
|
||||
{
|
||||
@ -116,7 +108,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
// vtk::formatType::INLINE_ASCII,
|
||||
fileName
|
||||
(
|
||||
aMesh.time().globalPath() / (vtkBaseFileName + "-edgesCentres")
|
||||
aMesh.time().globalPath() / "finiteArea-edgesCentres"
|
||||
)
|
||||
);
|
||||
|
||||
@ -142,7 +134,8 @@ Info<< "Write faMesh in vtk format:" << nl;
|
||||
writer.write("normal", fld);
|
||||
}
|
||||
|
||||
Info<< " " << writer.output().name() << nl;
|
||||
Info<< nl
|
||||
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
@ -15,7 +15,7 @@ Description
|
||||
|
||||
Input
|
||||
mesh (polyMesh)
|
||||
meshDefDict (system/finite-area/faMeshDefinition)
|
||||
meshDefDict (system/faMeshDefintion)
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -25,16 +25,13 @@ Input
|
||||
|
||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||
|
||||
labelList patchIDs;
|
||||
wordRes polyPatchNames;
|
||||
meshDefDict.readIfPresent("polyMeshPatches", polyPatchNames);
|
||||
|
||||
if
|
||||
const labelList patchIDs
|
||||
(
|
||||
wordRes select;
|
||||
meshDefDict.readIfPresent("polyMeshPatches", select)
|
||||
)
|
||||
{
|
||||
patchIDs = pbm.indices(select, true); // useGroups
|
||||
}
|
||||
pbm.indices(polyPatchNames, true) // useGroups
|
||||
);
|
||||
|
||||
label nFaceLabels = 0;
|
||||
for (const label patchi : patchIDs)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
@ -13,18 +13,6 @@ License
|
||||
Description
|
||||
Search for the appropriate faMeshDefinition dictionary...
|
||||
|
||||
Expects to find a faMeshDefinition file in a location specified
|
||||
by the command-line option, or one of the standard locations.
|
||||
|
||||
For default area region (region0):
|
||||
(1) system/finite-area/faMeshDefinition
|
||||
(2) system/faMeshDefinition [legacy location - v2312 and earlier]
|
||||
|
||||
For a named area region:
|
||||
(1) system/finite-area/<area-name>/faMeshDefinition
|
||||
(2) system/finite-area/faMeshDefinition.<area-name>
|
||||
[symmetric with faOptions]
|
||||
|
||||
Required Classes
|
||||
- Foam::polyMesh
|
||||
- Foam::IOdictionary
|
||||
@ -36,185 +24,81 @@ Required Variables
|
||||
- runTime [Time]
|
||||
|
||||
Provided Variables
|
||||
- faMeshDefinitionPtr [autoPtr<IOdictionary>]
|
||||
|
||||
If the dictionary cannot be found, exits with an error message or
|
||||
reports a warning (dry-run mode)
|
||||
- meshDefDict [IOdictionary]
|
||||
- meshDictPtr [autoPtr<IOdictionary>]
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
const word dictName("faMeshDefinition");
|
||||
|
||||
autoPtr<IOdictionary> faMeshDefinitionPtr;
|
||||
autoPtr<IOdictionary> meshDictPtr;
|
||||
|
||||
{
|
||||
// Exit unless dry-run?
|
||||
const bool exitOnFailure = (!args.dryRun());
|
||||
fileName dictPath;
|
||||
const word& regionDir = Foam::polyMesh::regionName(regionName);
|
||||
const word& areaRegionDir = Foam::polyMesh::regionName(areaRegionName);
|
||||
|
||||
const word& regionDir = polyMesh::regionName(regionName);
|
||||
const word& areaRegionDir = polyMesh::regionName(areaRegionName);
|
||||
|
||||
// Canonical location
|
||||
fileName dictPath
|
||||
(
|
||||
runTime.system()/regionDir
|
||||
/ faMesh::prefix()/areaRegionDir/dictName
|
||||
);
|
||||
|
||||
|
||||
// Dictionary specified on the command-line ...
|
||||
const bool specified = args.readIfPresent("dict", dictPath);
|
||||
|
||||
if (specified)
|
||||
if (args.readIfPresent("dict", dictPath))
|
||||
{
|
||||
// Dictionary specified on the command-line ...
|
||||
|
||||
if (isDir(dictPath))
|
||||
{
|
||||
dictPath /= dictName;
|
||||
}
|
||||
}
|
||||
else if
|
||||
(
|
||||
// Dictionary under system/faMeshDefinition ?
|
||||
// (v2312 and earlier)
|
||||
|
||||
areaRegionDir.empty()
|
||||
&& exists
|
||||
(
|
||||
runTime.path()/runTime.caseSystem()
|
||||
/ regionDir/faMesh::meshSubDir/dictName
|
||||
)
|
||||
)
|
||||
{
|
||||
// Dictionary present directly in system/ (v2312 and earlier)
|
||||
|
||||
dictPath = runTime.system()/regionDir/dictName;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use system/finite-area/ directory, with region qualifications
|
||||
|
||||
dictPath =
|
||||
(
|
||||
runTime.system()/regionDir
|
||||
/ faMesh::prefix()/areaRegionDir/dictName
|
||||
);
|
||||
}
|
||||
|
||||
IOobject meshDictIO
|
||||
(
|
||||
dictPath,
|
||||
runTime,
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER,
|
||||
true // is globalObject
|
||||
);
|
||||
|
||||
refPtr<IOobject> meshDictIOPtr;
|
||||
|
||||
bool foundIOobject = meshDictIO.typeHeaderOk<IOdictionary>(true);
|
||||
|
||||
// For reporting any alternative locations
|
||||
dictPath.clear();
|
||||
|
||||
if (!foundIOobject && !specified)
|
||||
if (!meshDictIO.typeHeaderOk<IOdictionary>(true))
|
||||
{
|
||||
if (!areaRegionDir.empty())
|
||||
{
|
||||
// Alternative location
|
||||
// - system/finite-area/faMeshDefinition.<area-name>
|
||||
|
||||
dictPath =
|
||||
(
|
||||
runTime.system()/regionDir
|
||||
/ faMesh::prefix()/IOobject::groupName(dictName, areaRegionDir)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// legacy location (v2312 and earlier)
|
||||
// - system/faMeshDefinition
|
||||
|
||||
dictPath = runTime.system()/regionDir/dictName;
|
||||
}
|
||||
|
||||
if (!dictPath.empty())
|
||||
{
|
||||
auto ioptr = autoPtr<IOobject>::New
|
||||
(
|
||||
dictPath,
|
||||
runTime,
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER,
|
||||
true // is globalObject
|
||||
);
|
||||
|
||||
foundIOobject =
|
||||
(
|
||||
ioptr && ioptr->typeHeaderOk<IOdictionary>(true)
|
||||
);
|
||||
|
||||
if (foundIOobject)
|
||||
{
|
||||
// Use if found
|
||||
meshDictIOPtr = std::move(ioptr);
|
||||
}
|
||||
|
||||
// Generally retain dictPath for error messages,
|
||||
// but don't mention the really old legacy location
|
||||
if (areaRegionDir.empty())
|
||||
{
|
||||
dictPath.clear();
|
||||
}
|
||||
}
|
||||
FatalErrorInFunction
|
||||
<< meshDictIO.objectPath() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Alternative location or regular location?
|
||||
if (!meshDictIOPtr)
|
||||
{
|
||||
meshDictIOPtr.cref(meshDictIO);
|
||||
}
|
||||
const auto& io = meshDictIOPtr();
|
||||
Info<< "Creating faMesh from definition: "
|
||||
<< meshDictIO.objectRelPath() << endl;
|
||||
|
||||
|
||||
// Handle final success or failure
|
||||
if (foundIOobject)
|
||||
{
|
||||
Info<< "----------------" << nl
|
||||
<< "Using area-mesh definition";
|
||||
if (!areaRegionDir.empty())
|
||||
{
|
||||
Info<< " [" << areaRegionName << "]";
|
||||
}
|
||||
|
||||
Info<< nl
|
||||
<< " " << io.objectRelPath() << nl << endl;
|
||||
|
||||
faMeshDefinitionPtr = autoPtr<IOdictionary>::New(io);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failure
|
||||
|
||||
if (exitOnFailure)
|
||||
{
|
||||
auto& err =
|
||||
FatalErrorInFunction
|
||||
<< "Did not find area-mesh definition";
|
||||
|
||||
if (!areaRegionDir.empty())
|
||||
{
|
||||
err<< " [" << areaRegionName << "]";
|
||||
}
|
||||
|
||||
err << nl
|
||||
<< " " << io.objectRelPath() << nl;
|
||||
|
||||
if (!dictPath.empty())
|
||||
{
|
||||
err << " " << dictPath << nl;
|
||||
}
|
||||
|
||||
FatalError<< exit(FatalError);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dry-run: warning
|
||||
auto& err =
|
||||
Warning << nl
|
||||
<< "----------------" << nl
|
||||
<< "Did not find area-mesh definition";
|
||||
|
||||
if (!areaRegionDir.empty())
|
||||
{
|
||||
err << " [" << areaRegionName << "]";
|
||||
}
|
||||
|
||||
err << nl
|
||||
<< " " << io.objectRelPath() << nl;
|
||||
|
||||
if (!dictPath.empty())
|
||||
{
|
||||
err << " " << dictPath << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
meshDictPtr = autoPtr<IOdictionary>::New(meshDictIO);
|
||||
}
|
||||
|
||||
IOdictionary& meshDefDict = *meshDictPtr;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2017 Wikki Ltd
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,6 +40,7 @@ Original Authors
|
||||
|
||||
#include "Time.H"
|
||||
#include "argList.H"
|
||||
#include "OSspecific.H"
|
||||
#include "faMesh.H"
|
||||
#include "faMeshTools.H"
|
||||
#include "IOdictionary.H"
|
||||
@ -52,7 +53,6 @@ Original Authors
|
||||
#include "PtrListOps.H"
|
||||
#include "foamVtkLineWriter.H"
|
||||
#include "foamVtkIndPatchWriter.H"
|
||||
#include "regionProperties.H"
|
||||
#include "syncTools.H"
|
||||
#include "OBJstream.H"
|
||||
|
||||
@ -104,14 +104,12 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
#include "addRegionOption.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
#include "addFaRegionOption.H"
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createNamedPolyMesh.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
#include "getFaRegionOption.H"
|
||||
|
||||
const bool doDecompose = !args.found("no-decompose");
|
||||
const bool doDecompFields = !args.found("no-fields");
|
||||
@ -125,83 +123,56 @@ int main(int argc, char *argv[])
|
||||
Info<< "Skip decompose of finiteArea fields" << nl;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Reading faMeshDefinition dictionary
|
||||
#include "findMeshDefinitionDict.H"
|
||||
|
||||
for (const word& areaRegionName : areaRegionNames)
|
||||
// Inject/overwrite name for optional 'empty' patch
|
||||
word patchName;
|
||||
if (args.readIfPresent("empty-patch", patchName))
|
||||
{
|
||||
// Reading faMeshDefinition dictionary
|
||||
#include "findMeshDefinitionDict.H"
|
||||
meshDefDict.add("emptyPatch", patchName, true);
|
||||
}
|
||||
|
||||
if (!faMeshDefinitionPtr)
|
||||
{
|
||||
if (args.dryRun())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Did not find area-mesh definition"<< nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
// Preliminary checks
|
||||
#include "checkPatchTopology.H"
|
||||
|
||||
auto& meshDefDict = (*faMeshDefinitionPtr);
|
||||
Info << "Create areaMesh";
|
||||
if (!Foam::polyMesh::regionName(areaRegionName).empty())
|
||||
{
|
||||
Foam::Info << ' ' << areaRegionName;
|
||||
}
|
||||
Info << " for polyMesh at time = " << runTime.timeName() << nl;
|
||||
|
||||
// Create
|
||||
faMesh aMesh(areaRegionName, mesh, meshDefDict);
|
||||
|
||||
// Inject/overwrite name for optional 'empty' patch
|
||||
if (word name; args.readIfPresent("empty-patch", name))
|
||||
{
|
||||
meshDefDict.add("emptyPatch", name, true);
|
||||
}
|
||||
// Mesh information (less verbose)
|
||||
faMeshTools::printMeshChecks(aMesh, 0);
|
||||
|
||||
// Preliminary checks
|
||||
#include "checkPatchTopology.H"
|
||||
if (args.found("write-edges-obj"))
|
||||
{
|
||||
#include "faMeshWriteEdgesOBJ.H"
|
||||
}
|
||||
|
||||
Info<< "Create area-mesh";
|
||||
if (!polyMesh::regionName(areaRegionName).empty())
|
||||
{
|
||||
Info<< " [" << areaRegionName << "]";
|
||||
}
|
||||
Info<< " with polyMesh at time = " << runTime.timeName() << nl;
|
||||
if (args.found("write-vtk"))
|
||||
{
|
||||
#include "faMeshWriteVTK.H"
|
||||
}
|
||||
|
||||
// Create
|
||||
faMesh aMesh(areaRegionName, mesh, meshDefDict);
|
||||
if (args.dryRun())
|
||||
{
|
||||
Info<< "\ndry-run: not writing mesh or decomposing fields\n" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// More precision (for points data)
|
||||
IOstream::minPrecision(10);
|
||||
|
||||
// Mesh information (less verbose)
|
||||
faMeshTools::printMeshChecks(aMesh, 0);
|
||||
Info<< nl << "Write finite area mesh." << nl;
|
||||
aMesh.write();
|
||||
|
||||
if (args.found("write-edges-obj"))
|
||||
{
|
||||
#include "faMeshWriteEdgesOBJ.H"
|
||||
}
|
||||
|
||||
if (args.found("write-vtk"))
|
||||
{
|
||||
#include "faMeshWriteVTK.H"
|
||||
}
|
||||
|
||||
if (args.dryRun())
|
||||
{
|
||||
Info<< "\ndry-run: not writing mesh or decomposing fields\n" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// More precision (for points data)
|
||||
IOstream::minPrecision(10);
|
||||
|
||||
Info<< nl << "Write finite area mesh";
|
||||
if (const word& name = aMesh.regionName(); !name.empty())
|
||||
{
|
||||
Info<< " [" << name << "]";
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
aMesh.write();
|
||||
|
||||
Info<< endl;
|
||||
#include "decomposeFaFields.H"
|
||||
}
|
||||
Info<< endl;
|
||||
#include "decomposeFaFields.H"
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
@ -334,7 +334,6 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
#include "addAllRegionOptions.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
argList::addDryRunOption
|
||||
(
|
||||
@ -443,6 +442,7 @@ int main(int argc, char *argv[])
|
||||
bool decomposeFieldsOnly = args.found("fields");
|
||||
bool forceOverwrite = args.found("force");
|
||||
|
||||
|
||||
// Set time from database
|
||||
#include "createTime.H"
|
||||
|
||||
@ -491,17 +491,9 @@ int main(int argc, char *argv[])
|
||||
decompDictFile = runTime.globalPath()/decompDictFile;
|
||||
}
|
||||
|
||||
// Handle -allRegions, -regions, -region
|
||||
// Get region names
|
||||
#include "getAllRegionOptions.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
}
|
||||
|
||||
const bool optRegions =
|
||||
(regionNames.size() != 1 || regionNames[0] != polyMesh::defaultRegion);
|
||||
|
||||
@ -821,76 +813,56 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Field objects at this time
|
||||
IOobjectList objects;
|
||||
|
||||
// faMesh fields - can have multiple finite-area per volume
|
||||
HashTable<IOobjectList> faObjects;
|
||||
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");
|
||||
|
||||
// Lists of finite-area fields
|
||||
faObjects.reserve(areaRegionNames.size());
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
// The finite-area objects for this area region
|
||||
IOobjectList objs
|
||||
(
|
||||
faMesh::Registry(mesh),
|
||||
runTime.timeName(),
|
||||
polyMesh::regionName(areaName),
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
if (!objs.empty())
|
||||
{
|
||||
faObjects.emplace_set(areaName, std::move(objs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finite area handling
|
||||
// - all area regions use the same volume decomposition
|
||||
|
||||
HashPtrTable<faMeshDecomposition> faMeshDecompHashes;
|
||||
autoPtr<faMeshDecomposition> faMeshDecompPtr;
|
||||
if (doFiniteArea)
|
||||
{
|
||||
const word boundaryInst =
|
||||
mesh.time().findInstance(mesh.meshDir(), "boundary");
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"faBoundary",
|
||||
boundaryInst,
|
||||
faMesh::meshDir(mesh, areaName),
|
||||
mesh.time(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
);
|
||||
IOobject io
|
||||
(
|
||||
"faBoundary",
|
||||
boundaryInst,
|
||||
faMesh::meshDir(mesh, word::null),
|
||||
mesh.time(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
);
|
||||
|
||||
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
||||
{
|
||||
// Always based on the volume decomposition!
|
||||
faMeshDecompHashes.set
|
||||
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
||||
{
|
||||
// Always based on the volume decomposition!
|
||||
faMeshDecompPtr.reset
|
||||
(
|
||||
new faMeshDecomposition
|
||||
(
|
||||
areaName,
|
||||
autoPtr<faMeshDecomposition>::New
|
||||
(
|
||||
areaName,
|
||||
mesh,
|
||||
mesh.nProcs(),
|
||||
mesh.model()
|
||||
)
|
||||
);
|
||||
}
|
||||
mesh,
|
||||
mesh.nProcs(),
|
||||
mesh.model()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1094,7 +1066,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
processorDb.setTime(runTime);
|
||||
|
||||
// Read the mesh
|
||||
// read the mesh
|
||||
if (!procMeshList.set(proci))
|
||||
{
|
||||
procMeshList.set
|
||||
@ -1301,15 +1273,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
// Finite-area mesh and field decomposition
|
||||
for (auto& iter : faMeshDecompHashes.sorted())
|
||||
// Finite area mesh and field decomposition
|
||||
if (faMeshDecompPtr)
|
||||
{
|
||||
const word& areaName = iter.key();
|
||||
Info<< "\nFinite area mesh decomposition" << endl;
|
||||
|
||||
faMeshDecomposition& aMesh = *(iter.val());
|
||||
|
||||
Info<< "\nFinite area mesh decomposition: "
|
||||
<< areaName << endl;
|
||||
faMeshDecomposition& aMesh = faMeshDecompPtr();
|
||||
|
||||
aMesh.decomposeMesh();
|
||||
aMesh.writeDecomposition();
|
||||
@ -1320,13 +1289,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
faFieldDecomposer::fieldsCache areaFieldCache;
|
||||
|
||||
if
|
||||
(
|
||||
const auto objs = faObjects.cfind(areaName);
|
||||
doDecompFields && objs.good()
|
||||
)
|
||||
if (doDecompFields)
|
||||
{
|
||||
areaFieldCache.readAllFields(aMesh, objs.val());
|
||||
areaFieldCache.readAllFields(aMesh, faObjects);
|
||||
}
|
||||
|
||||
const label nAreaFields = areaFieldCache.size();
|
||||
@ -1357,7 +1322,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
processorDb.setTime(runTime);
|
||||
|
||||
// Read the volume mesh
|
||||
// Read the mesh
|
||||
fvMesh procFvMesh
|
||||
(
|
||||
IOobject
|
||||
@ -1368,7 +1333,7 @@ int main(int argc, char *argv[])
|
||||
)
|
||||
);
|
||||
|
||||
faMesh procMesh(areaName, procFvMesh);
|
||||
faMesh procMesh(procFvMesh);
|
||||
|
||||
// // Does not work. HJ, 15/Aug/2017
|
||||
// const labelIOList& faceProcAddressing =
|
||||
@ -1427,11 +1392,7 @@ int main(int argc, char *argv[])
|
||||
boundaryProcAddressing
|
||||
);
|
||||
|
||||
areaFieldCache.decomposeAllFields
|
||||
(
|
||||
fieldDecomposer,
|
||||
args.verbose() // report
|
||||
);
|
||||
areaFieldCache.decomposeAllFields(fieldDecomposer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -91,7 +91,6 @@ int main(int argc, char *argv[])
|
||||
argList::noParallel();
|
||||
|
||||
#include "addAllRegionOptions.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
argList::addVerboseOption();
|
||||
argList::addOption
|
||||
@ -202,17 +201,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
const bool newTimes = args.found("newTimes");
|
||||
|
||||
// Handle -allRegions, -regions, -region
|
||||
// Get region names
|
||||
#include "getAllRegionOptions.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
}
|
||||
|
||||
// Determine the processor count
|
||||
label nProcs{0};
|
||||
|
||||
@ -400,30 +391,19 @@ int main(int argc, char *argv[])
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
// The finite-area fields (multiple finite-area per volume)
|
||||
HashTable<IOobjectList> faObjects;
|
||||
IOobjectList faObjects;
|
||||
|
||||
if (doFiniteArea && doFields)
|
||||
{
|
||||
// Lists of finite-area fields - scan on processor0
|
||||
faObjects.reserve(areaRegionNames.size());
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
// The finite-area objects for this area region
|
||||
IOobjectList objs
|
||||
(
|
||||
procMeshes.meshes()[0],
|
||||
databases[0].timeName(),
|
||||
faMesh::dbDir(areaName), // local relative to mesh
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
if (!objs.empty())
|
||||
{
|
||||
faObjects.emplace_set(areaName, std::move(objs));
|
||||
}
|
||||
}
|
||||
// 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)
|
||||
@ -573,60 +553,42 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
// Reconstruct any finite-area fields
|
||||
if (doFiniteArea)
|
||||
// If there are any FA fields, reconstruct them
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
bool hadFaFields = false;
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
const auto objs = faObjects.cfind(areaName);
|
||||
if (!objs.good())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& faObjs = objs.val();
|
||||
|
||||
if
|
||||
(
|
||||
!faObjs.count(fieldTypes::is_area)
|
||||
&& !faObjs.count<edgeScalarField>()
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hadFaFields = true;
|
||||
|
||||
Info<< "Reconstructing finite-area fields ["
|
||||
<< polyMesh::regionName(areaName)
|
||||
<< "]" << nl << endl;
|
||||
|
||||
const faMesh aMesh(areaName, mesh);
|
||||
|
||||
processorFaMeshes procFaMeshes
|
||||
(
|
||||
procMeshes.meshes(),
|
||||
areaName
|
||||
);
|
||||
|
||||
faFieldReconstructor reconstructor
|
||||
(
|
||||
aMesh,
|
||||
procFaMeshes.meshes(),
|
||||
procFaMeshes.edgeProcAddressing(),
|
||||
procFaMeshes.faceProcAddressing(),
|
||||
procFaMeshes.boundaryProcAddressing()
|
||||
);
|
||||
|
||||
reconstructor.reconstructAllFields(faObjs);
|
||||
}
|
||||
|
||||
if (!hadFaFields)
|
||||
{
|
||||
Info << "No finite-area fields" << nl << endl;
|
||||
}
|
||||
}
|
||||
else if
|
||||
(
|
||||
faObjects.count<areaScalarField>()
|
||||
|| faObjects.count<areaVectorField>()
|
||||
|| faObjects.count<areaSphericalTensorField>()
|
||||
|| faObjects.count<areaSymmTensorField>()
|
||||
|| faObjects.count<areaTensorField>()
|
||||
|| faObjects.count<edgeScalarField>()
|
||||
)
|
||||
{
|
||||
Info << "Reconstructing FA fields" << nl << endl;
|
||||
|
||||
faMesh aMesh(mesh);
|
||||
|
||||
processorFaMeshes procFaMeshes(procMeshes.meshes());
|
||||
|
||||
faFieldReconstructor reconstructor
|
||||
(
|
||||
aMesh,
|
||||
procFaMeshes.meshes(),
|
||||
procFaMeshes.edgeProcAddressing(),
|
||||
procFaMeshes.faceProcAddressing(),
|
||||
procFaMeshes.boundaryProcAddressing()
|
||||
);
|
||||
|
||||
reconstructor.reconstructAllFields(faObjects);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info << "No FA fields" << nl << endl;
|
||||
}
|
||||
|
||||
if (doReconstructSets)
|
||||
{
|
||||
|
||||
@ -119,10 +119,17 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
||||
const polyBoundaryMesh& masterPatches = masterMesh.boundaryMesh();
|
||||
|
||||
|
||||
DynamicList<label> masterFaces(masterMesh.nBoundaryFaces());
|
||||
DynamicList<label> masterFaces
|
||||
(
|
||||
masterMesh.nFaces()
|
||||
- masterMesh.nInternalFaces()
|
||||
);
|
||||
|
||||
for (const polyPatch& pp : masterPatches)
|
||||
|
||||
forAll(masterPatches, patchi)
|
||||
{
|
||||
const polyPatch& pp = masterPatches[patchi];
|
||||
|
||||
if (isA<processorPolyPatch>(pp))
|
||||
{
|
||||
for
|
||||
@ -132,8 +139,11 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
||||
proci++
|
||||
)
|
||||
{
|
||||
const string toProcString("to" + Foam::name(proci));
|
||||
if (pp.name().ends_with(toProcString))
|
||||
const string toProcString("to" + name(proci));
|
||||
if (
|
||||
pp.name().rfind(toProcString)
|
||||
== (pp.name().size()-toProcString.size())
|
||||
)
|
||||
{
|
||||
label meshFacei = pp.start();
|
||||
forAll(pp, i)
|
||||
@ -146,6 +156,7 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
||||
|
||||
}
|
||||
}
|
||||
masterFaces.shrink();
|
||||
|
||||
|
||||
// Pick up all patches on meshToAdd ending in "procBoundaryDDDtoYYY"
|
||||
@ -153,10 +164,16 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
||||
|
||||
const polyBoundaryMesh& addPatches = meshToAdd.boundaryMesh();
|
||||
|
||||
DynamicList<label> addFaces(meshToAdd.nBoundaryFaces());
|
||||
DynamicList<label> addFaces
|
||||
(
|
||||
meshToAdd.nFaces()
|
||||
- meshToAdd.nInternalFaces()
|
||||
);
|
||||
|
||||
for (const polyPatch& pp : addPatches)
|
||||
forAll(addPatches, patchi)
|
||||
{
|
||||
const polyPatch& pp = addPatches[patchi];
|
||||
|
||||
if (isA<processorPolyPatch>(pp))
|
||||
{
|
||||
bool isConnected = false;
|
||||
@ -198,6 +215,7 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
||||
}
|
||||
}
|
||||
}
|
||||
addFaces.shrink();
|
||||
|
||||
return autoPtr<faceCoupleInfo>::New
|
||||
(
|
||||
@ -484,14 +502,15 @@ void writeMaps
|
||||
|
||||
Info<< " pointProcAddressing" << endl;
|
||||
ioAddr.rename("pointProcAddressing");
|
||||
labelIOList::writeContents(ioAddr, pointProcAddressing);
|
||||
IOList<label>::writeContents(ioAddr, pointProcAddressing);
|
||||
|
||||
// From processor face to reconstructed mesh face
|
||||
// - add turning index to faceProcAddressing.
|
||||
// See reconstructPar for meaning of turning index.
|
||||
|
||||
labelList faceProcAddr(faceProcAddressing);
|
||||
Info<< " faceProcAddressing" << endl;
|
||||
ioAddr.rename("faceProcAddressing");
|
||||
labelIOList faceProcAddr(ioAddr, faceProcAddressing);
|
||||
|
||||
// Now add turning index to faceProcAddressing.
|
||||
// See reconstructPar for meaning of turning index.
|
||||
forAll(faceProcAddr, procFacei)
|
||||
{
|
||||
const label masterFacei = faceProcAddr[procFacei];
|
||||
@ -526,21 +545,19 @@ void writeMaps
|
||||
}
|
||||
}
|
||||
|
||||
Info<< " faceProcAddressing" << endl;
|
||||
ioAddr.rename("faceProcAddressing");
|
||||
labelIOList::writeContents(ioAddr, faceProcAddr);
|
||||
faceProcAddr.clear();
|
||||
faceProcAddr.write();
|
||||
|
||||
|
||||
// From processor cell to reconstructed mesh cell
|
||||
Info<< " cellProcAddressing" << endl;
|
||||
ioAddr.rename("cellProcAddressing");
|
||||
labelIOList::writeContents(ioAddr, cellProcAddressing);
|
||||
IOList<label>::writeContents(ioAddr, cellProcAddressing);
|
||||
|
||||
|
||||
// From processor patch to reconstructed mesh patch
|
||||
Info<< " boundaryProcAddressing" << endl;
|
||||
ioAddr.rename("boundaryProcAddressing");
|
||||
labelIOList::writeContents(ioAddr, boundProcAddressing);
|
||||
IOList<label>::writeContents(ioAddr, boundProcAddressing);
|
||||
|
||||
Info<< endl;
|
||||
}
|
||||
@ -628,8 +645,7 @@ void sortFaEdgeMapping
|
||||
{
|
||||
// From faMeshReconstructor.C - edge shuffling on patches
|
||||
|
||||
Map<label> remapGlobal;
|
||||
remapGlobal.reserve(onePatch.nEdges());
|
||||
Map<label> remapGlobal(2*onePatch.nEdges());
|
||||
for (label edgei = 0; edgei < onePatch.nInternalEdges(); ++edgei)
|
||||
{
|
||||
remapGlobal.insert(edgei, remapGlobal.size());
|
||||
@ -763,11 +779,6 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
#include "addAllRegionOptions.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
// Prevent volume fields [with regionFaModels] from incidental
|
||||
// triggering finite-area
|
||||
regionModels::allowFaModels(false);
|
||||
|
||||
// Prevent volume BCs from triggering finite-area
|
||||
regionModels::allowFaModels(false);
|
||||
@ -830,17 +841,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
// Handle -allRegions, -regions, -region
|
||||
// Get region names
|
||||
#include "getAllRegionOptions.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
}
|
||||
|
||||
// Determine the processor count
|
||||
label nProcs{0};
|
||||
|
||||
@ -932,8 +935,7 @@ int main(int argc, char *argv[])
|
||||
polyMesh::meshDir(regionName),
|
||||
databases[0],
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
// Problem: faceCompactIOList recognises both 'faceList' and
|
||||
@ -1403,12 +1405,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
// Read finite-area
|
||||
// For each named area region that exists create a HashTable
|
||||
// entry that will contain the PtrList for all processors
|
||||
|
||||
PtrList<faMesh> procFaMeshes(databases.size());
|
||||
PtrList<polyMesh> procMeshes(databases.size());
|
||||
HashTable<PtrList<faMesh>> procAreaRegionMeshes;
|
||||
procAreaRegionMeshes.reserve(areaRegionNames.size());
|
||||
|
||||
forAll(databases, proci)
|
||||
{
|
||||
@ -1416,16 +1414,20 @@ int main(int argc, char *argv[])
|
||||
<< "Read processor mesh: "
|
||||
<< (databases[proci].caseName()/regionDir) << endl;
|
||||
|
||||
const polyMesh& procMesh = procMeshes.emplace
|
||||
procMeshes.set
|
||||
(
|
||||
proci,
|
||||
IOobject
|
||||
new polyMesh
|
||||
(
|
||||
regionName,
|
||||
databases[proci].timeName(),
|
||||
databases[proci]
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
databases[proci].timeName(),
|
||||
databases[proci]
|
||||
)
|
||||
)
|
||||
);
|
||||
const polyMesh& procMesh = procMeshes[proci];
|
||||
|
||||
writeMaps
|
||||
(
|
||||
@ -1448,67 +1450,38 @@ int main(int argc, char *argv[])
|
||||
"boundary"
|
||||
);
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
IOobject io
|
||||
(
|
||||
"faBoundary",
|
||||
boundaryInst,
|
||||
faMesh::meshDir(procMesh, word::null),
|
||||
procMesh.time(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
);
|
||||
|
||||
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"faBoundary",
|
||||
boundaryInst,
|
||||
faMesh::meshDir(procMesh, areaName),
|
||||
procMesh.time(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
);
|
||||
|
||||
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
||||
{
|
||||
// Always based on the volume decomposition!
|
||||
auto& procFaMeshes = procAreaRegionMeshes(areaName);
|
||||
procFaMeshes.resize(databases.size());
|
||||
|
||||
procFaMeshes.set
|
||||
(
|
||||
proci,
|
||||
new faMesh(areaName, procMesh)
|
||||
);
|
||||
}
|
||||
// Always based on the volume decomposition!
|
||||
procFaMeshes.set(proci, new faMesh(procMesh));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A finite-area mapping exists if procFaMeshes was filled
|
||||
|
||||
// Re-read reconstructed polyMesh. Note: could probably be avoided
|
||||
// by merging into loops above.
|
||||
refPtr<polyMesh> masterPolyMeshPtr;
|
||||
|
||||
if (!procAreaRegionMeshes.empty())
|
||||
// Finite-area mapping
|
||||
doFiniteArea = false;
|
||||
forAll(procFaMeshes, proci)
|
||||
{
|
||||
masterPolyMeshPtr.reset
|
||||
(
|
||||
new polyMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
runTime.timeName(),
|
||||
runTime
|
||||
),
|
||||
true
|
||||
)
|
||||
);
|
||||
if (procFaMeshes.set(proci))
|
||||
{
|
||||
doFiniteArea = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Process any finite-area meshes
|
||||
for (const auto& iter : procAreaRegionMeshes.csorted())
|
||||
if (doFiniteArea)
|
||||
{
|
||||
const auto& areaName = iter.key();
|
||||
const auto& procFaMeshes = iter.val();
|
||||
|
||||
const polyMesh& masterMesh = masterPolyMeshPtr();
|
||||
|
||||
// Addressing from processor to reconstructed case
|
||||
labelListList faFaceProcAddressing(nProcs);
|
||||
labelListList faEdgeProcAddressing(nProcs);
|
||||
@ -1526,10 +1499,32 @@ int main(int argc, char *argv[])
|
||||
|
||||
faBoundProcAddressing[proci] = identity(bm.size());
|
||||
// Mark processor patches
|
||||
faBoundProcAddressing[proci].slice(bm.nNonProcessor()) = -1;
|
||||
for
|
||||
(
|
||||
label patchi = bm.nNonProcessor();
|
||||
patchi < bm.size();
|
||||
++patchi
|
||||
)
|
||||
{
|
||||
faBoundProcAddressing[proci][patchi] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Re-read reconstructed polyMesh. Note: could probably be avoided
|
||||
// by merging into loops above.
|
||||
const polyMesh masterMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
runTime.timeName(),
|
||||
runTime
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
// faceProcAddressing
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -1564,13 +1559,13 @@ int main(int argc, char *argv[])
|
||||
// Construct without patches
|
||||
faMesh masterFaMesh
|
||||
(
|
||||
areaName,
|
||||
masterMesh,
|
||||
std::move(masterFaceLabels),
|
||||
io
|
||||
);
|
||||
|
||||
const auto& masterPatch = masterFaMesh.patch();
|
||||
const uindirectPrimitivePatch& masterPatch =
|
||||
masterFaMesh.patch();
|
||||
|
||||
|
||||
// pointProcAddressing
|
||||
@ -1582,7 +1577,7 @@ int main(int argc, char *argv[])
|
||||
const auto& procPatch = procFaMeshes[proci].patch();
|
||||
const auto& mp = procPatch.meshPoints();
|
||||
|
||||
auto& pointAddr = faPointProcAddressing[proci];
|
||||
labelList& pointAddr = faPointProcAddressing[proci];
|
||||
pointAddr.resize_nocopy(mp.size());
|
||||
|
||||
forAll(mp, i)
|
||||
@ -1631,7 +1626,8 @@ int main(int argc, char *argv[])
|
||||
label nPatches = 0;
|
||||
forAll(completePatches, patchi)
|
||||
{
|
||||
const auto& patchEdgeLabels = singlePatchEdgeLabels[patchi];
|
||||
const labelList& patchEdgeLabels =
|
||||
singlePatchEdgeLabels[patchi];
|
||||
|
||||
const faPatch& fap = procMesh0.boundary()[patchi];
|
||||
|
||||
@ -1662,11 +1658,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Serial mesh - no parallel communication
|
||||
|
||||
const bool oldParRun = UPstream::parRun(false);
|
||||
const bool oldParRun = Pstream::parRun(false);
|
||||
|
||||
masterFaMesh.addFaPatches(completePatches);
|
||||
|
||||
UPstream::parRun(oldParRun); // Restore parallel state
|
||||
Pstream::parRun(oldParRun); // Restore parallel state
|
||||
|
||||
|
||||
// Write mesh & individual addressing
|
||||
|
||||
@ -33,266 +33,99 @@ License
|
||||
#include "decomposedBlockData.H"
|
||||
#include "IFstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Trimmed-down version of lookupAndCacheProcessorsPath
|
||||
// with Foam::exists() check. No caching.
|
||||
|
||||
// Check for two conditions:
|
||||
// - file has to exist
|
||||
// - if collated the entry has to exist inside the file
|
||||
|
||||
// Note: bypass fileOperation::filePath(IOobject&) since has problems
|
||||
// with going to a different number of processors
|
||||
// (in collated format). Use file-based searching instead
|
||||
|
||||
namespace Foam
|
||||
bool Foam::checkFileExistence(const fileName& fName)
|
||||
{
|
||||
// Trimmed-down version of lookupAndCacheProcessorsPath
|
||||
// with Foam::exists() check. No caching.
|
||||
|
||||
// If indeed collated format:
|
||||
// Collect block-number in individual filenames
|
||||
// (might differ on different processors)
|
||||
static bool checkFileExistenceCollated
|
||||
(
|
||||
const Foam::fileOperation& handler,
|
||||
const Foam::fileName& fName
|
||||
)
|
||||
{
|
||||
// using namespace Foam;
|
||||
// Check for two conditions:
|
||||
// - file has to exist
|
||||
// - if collated the entry has to exist inside the file
|
||||
|
||||
// Note: bypass fileOperation::filePath(IOobject&) since has problems
|
||||
// with going to a different number of processors
|
||||
// (in collated format). Use file-based searching instead
|
||||
|
||||
const auto& handler = Foam::fileHandler();
|
||||
typedef fileOperation::procRangeType procRangeType;
|
||||
|
||||
fileName path, pDir, local;
|
||||
procRangeType group;
|
||||
label numProcs;
|
||||
const label proci =
|
||||
fileOperation::splitProcessorPath
|
||||
(fName, path, pDir, local, group, numProcs);
|
||||
|
||||
bool found = false;
|
||||
|
||||
if (proci != -1)
|
||||
{
|
||||
const label handlerComm = handler.comm();
|
||||
// Read all directories to see any beginning with processor
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const label globalProci = UPstream::myProcNo(UPstream::worldComm);
|
||||
const label handlerProci = UPstream::myProcNo(handlerComm);
|
||||
const label nHandlerProcs = UPstream::nProcs(handlerComm);
|
||||
|
||||
// Determine my local block number
|
||||
label myBlockNumber = -1;
|
||||
{
|
||||
fileOperation::procRangeType group;
|
||||
label proci = fileOperation::detectProcessorPath(fName, group);
|
||||
|
||||
if (proci == -1 && group.empty())
|
||||
{
|
||||
// 'processorsXXX' format so contains all ranks
|
||||
// according to worldComm
|
||||
myBlockNumber = globalProci;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 'processorsXXX_n-m' format so check for relative rank
|
||||
myBlockNumber = handlerProci;
|
||||
}
|
||||
}
|
||||
|
||||
// Since we are streaming anyhow, could also pack as tuple:
|
||||
// Tuple2<fileName, label>
|
||||
|
||||
|
||||
// Collect file names on master of local communicator
|
||||
const fileNameList fNames
|
||||
const fileNameList dirEntries
|
||||
(
|
||||
Pstream::listGatherValues
|
||||
(
|
||||
fName,
|
||||
handlerComm,
|
||||
UPstream::msgType()
|
||||
)
|
||||
handler.readDir(path, fileName::Type::DIRECTORY)
|
||||
);
|
||||
|
||||
// Collect block numbers on master of local communicator
|
||||
const labelList myBlockNumbers
|
||||
(
|
||||
Pstream::listGatherValues
|
||||
(
|
||||
myBlockNumber,
|
||||
handlerComm,
|
||||
UPstream::msgType()
|
||||
)
|
||||
);
|
||||
// Extract info from processorN or processorsNN
|
||||
// - highest processor number
|
||||
// - directory+offset containing data for proci
|
||||
|
||||
// Determine for all whether the filename exists in the collated file.
|
||||
boolList allFound;
|
||||
|
||||
if (UPstream::master(handlerComm))
|
||||
// label nProcs = 0;
|
||||
for (const fileName& dirN : dirEntries)
|
||||
{
|
||||
allFound.resize(nHandlerProcs, false);
|
||||
// Analyse directory name
|
||||
label rNum(-1);
|
||||
const label readProci =
|
||||
fileOperation::detectProcessorPath(dirN, group, &rNum);
|
||||
|
||||
// Store nBlocks and index of file that was used for nBlocks
|
||||
label nBlocks = -1;
|
||||
label blockRanki = -1;
|
||||
forAll(fNames, ranki)
|
||||
if (proci == readProci)
|
||||
{
|
||||
if
|
||||
(
|
||||
blockRanki == -1
|
||||
|| (fNames[ranki] != fNames[blockRanki])
|
||||
)
|
||||
// Found "processorN"
|
||||
if (Foam::exists(path/dirN/local))
|
||||
{
|
||||
blockRanki = ranki;
|
||||
IFstream is(fNames[ranki]);
|
||||
nBlocks = decomposedBlockData::getNumBlocks(is);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (rNum != -1)
|
||||
{
|
||||
// "processorsNN" or "processorsNN_start-end"
|
||||
if (group.empty())
|
||||
{
|
||||
// "processorsNN"
|
||||
if (proci < rNum && Foam::exists(path/dirN/local))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (group.contains(proci))
|
||||
{
|
||||
// "processorsNN_start-end"
|
||||
// - save the local proc offset
|
||||
|
||||
allFound[ranki] = (myBlockNumbers[ranki] < nBlocks);
|
||||
if (Foam::exists(path/dirN/local))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scatter using the handler communicator
|
||||
found = Pstream::listScatterValues
|
||||
(
|
||||
allFound,
|
||||
handlerComm,
|
||||
UPstream::msgType()
|
||||
);
|
||||
if (!found)
|
||||
{
|
||||
found = Foam::exists(fName);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
} // End namespace
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::bitSet Foam::haveProcessorFile
|
||||
(
|
||||
const word& name, // eg "faces"
|
||||
const fileName& instance, // eg "constant"
|
||||
const fileName& local, // eg, polyMesh
|
||||
const Time& runTime,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
const auto& handler = Foam::fileHandler();
|
||||
|
||||
const fileName fName
|
||||
(
|
||||
handler.filePath(runTime.path()/instance/local/name)
|
||||
);
|
||||
|
||||
bool found = handler.isFile(fName);
|
||||
|
||||
// Assume non-collated (as fallback value).
|
||||
// If everyone claims to have the file, use master to verify if
|
||||
// collated is involved.
|
||||
|
||||
bool isCollated = false;
|
||||
|
||||
if (returnReduceAnd(found, UPstream::worldComm))
|
||||
{
|
||||
// Test for collated format.
|
||||
// Note: can test only world-master. Since even host-collated will have
|
||||
// same file format type for all processors
|
||||
if (UPstream::master(UPstream::worldComm))
|
||||
{
|
||||
const bool oldParRun = UPstream::parRun(false);
|
||||
|
||||
if (IFstream is(fName); is.good())
|
||||
{
|
||||
IOobject io(name, instance, local, runTime);
|
||||
io.readHeader(is);
|
||||
|
||||
isCollated = decomposedBlockData::isCollatedType(io);
|
||||
}
|
||||
|
||||
UPstream::parRun(oldParRun);
|
||||
}
|
||||
Pstream::broadcast(isCollated, UPstream::worldComm);
|
||||
}
|
||||
|
||||
// For collated, check that the corresponding blocks exist
|
||||
if (isCollated)
|
||||
{
|
||||
found = checkFileExistenceCollated(handler, fName);
|
||||
}
|
||||
|
||||
|
||||
// Globally consistent information about who has the file
|
||||
bitSet haveFileOnProc = bitSet::allGather(found, UPstream::worldComm);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "Per processor availability of \""
|
||||
<< name << "\" file in " << instance/local << nl
|
||||
<< " " << flatOutput(haveFileOnProc) << nl << endl;
|
||||
}
|
||||
|
||||
return haveFileOnProc;
|
||||
}
|
||||
|
||||
|
||||
Foam::boolList Foam::haveMeshFile
|
||||
(
|
||||
const word& name, // eg "faces"
|
||||
const fileName& instance, // eg "constant"
|
||||
const fileName& local, // eg, polyMesh
|
||||
const Time& runTime,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
const auto& handler = Foam::fileHandler();
|
||||
|
||||
const fileName fName
|
||||
(
|
||||
handler.filePath(runTime.path()/instance/local/name)
|
||||
);
|
||||
|
||||
bool found = handler.isFile(fName);
|
||||
|
||||
// Assume non-collated (as fallback value).
|
||||
// If everyone claims to have the file, use master to verify if
|
||||
// collated is involved.
|
||||
|
||||
bool isCollated = false;
|
||||
|
||||
if (returnReduceAnd(found, UPstream::worldComm))
|
||||
{
|
||||
// Test for collated format.
|
||||
// Note: can test only world-master. Since even host-collated will have
|
||||
// same file format type for all processors
|
||||
if (UPstream::master(UPstream::worldComm))
|
||||
{
|
||||
const bool oldParRun = UPstream::parRun(false);
|
||||
|
||||
if (IFstream is(fName); is.good())
|
||||
{
|
||||
IOobject io(name, instance, local, runTime);
|
||||
io.readHeader(is);
|
||||
|
||||
isCollated = decomposedBlockData::isCollatedType(io);
|
||||
}
|
||||
|
||||
UPstream::parRun(oldParRun);
|
||||
}
|
||||
Pstream::broadcast(isCollated, UPstream::worldComm);
|
||||
}
|
||||
|
||||
// For collated, check that the corresponding blocks exist
|
||||
if (isCollated)
|
||||
{
|
||||
found = checkFileExistenceCollated(handler, fName);
|
||||
}
|
||||
|
||||
|
||||
// Globally consistent information about who has a mesh
|
||||
boolList haveFileOnProc
|
||||
(
|
||||
UPstream::allGatherValues<bool>(found, UPstream::worldComm)
|
||||
);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "Per processor availability of \""
|
||||
<< name << "\" file in " << instance/local << nl
|
||||
<< " " << flatOutput(haveFileOnProc) << nl << endl;
|
||||
}
|
||||
|
||||
return haveFileOnProc;
|
||||
}
|
||||
|
||||
|
||||
Foam::boolList Foam::haveMeshFile
|
||||
(
|
||||
@ -302,49 +135,143 @@ Foam::boolList Foam::haveMeshFile
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
|
||||
// Simple directory scanning - too fragile
|
||||
bool found = checkFileExistence(runTime.path()/meshPath/meshFile);
|
||||
|
||||
#else
|
||||
|
||||
// Trimmed-down version of lookupAndCacheProcessorsPath
|
||||
// with Foam::exists() check. No caching.
|
||||
|
||||
// Check for two conditions:
|
||||
// - file has to exist
|
||||
// - if collated the entry has to exist inside the file
|
||||
|
||||
// Note: bypass fileOperation::filePath(IOobject&) since has problems
|
||||
// with going to a different number of processors
|
||||
// (in collated format). Use file-based searching instead
|
||||
|
||||
const auto& handler = Foam::fileHandler();
|
||||
typedef fileOperation::procRangeType procRangeType;
|
||||
|
||||
const fileName fName
|
||||
(
|
||||
handler.filePath(runTime.path()/meshPath/meshFile)
|
||||
);
|
||||
|
||||
bool found = handler.isFile(fName);
|
||||
|
||||
// Assume non-collated (as fallback value).
|
||||
// If everyone claims to have the file, use master to verify if
|
||||
// collated is involved.
|
||||
|
||||
bool isCollated = false;
|
||||
|
||||
if (returnReduceAnd(found, UPstream::worldComm))
|
||||
if (returnReduceAnd(found)) // worldComm
|
||||
{
|
||||
// Test for collated format.
|
||||
// Bit tricky: avoid having all slaves open file since this involves
|
||||
// reading it on master and broadcasting it. This fails if file > 2G.
|
||||
// So instead only read on master
|
||||
|
||||
bool isCollated = false;
|
||||
|
||||
// Note: can test only world-master. Since even host-collated will have
|
||||
// same file format type for all processors
|
||||
if (UPstream::master(UPstream::worldComm))
|
||||
{
|
||||
const bool oldParRun = UPstream::parRun(false);
|
||||
|
||||
if (IFstream is(fName); is.good())
|
||||
IFstream is(fName);
|
||||
if (is.good())
|
||||
{
|
||||
IOobject io(meshFile, meshPath, runTime);
|
||||
io.readHeader(is);
|
||||
|
||||
isCollated = decomposedBlockData::isCollatedType(io);
|
||||
}
|
||||
|
||||
UPstream::parRun(oldParRun);
|
||||
}
|
||||
Pstream::broadcast(isCollated, UPstream::worldComm);
|
||||
}
|
||||
Pstream::broadcast(isCollated); //UPstream::worldComm
|
||||
|
||||
// For collated, check that the corresponding blocks exist
|
||||
if (isCollated)
|
||||
{
|
||||
found = checkFileExistenceCollated(handler, fName);
|
||||
}
|
||||
|
||||
// Collect block-number in individual filenames (might differ
|
||||
// on different processors)
|
||||
if (isCollated)
|
||||
{
|
||||
const label nProcs = UPstream::nProcs(fileHandler().comm());
|
||||
const label myProcNo = UPstream::myProcNo(fileHandler().comm());
|
||||
|
||||
// Collect file names on master of local communicator
|
||||
const fileNameList fNames
|
||||
(
|
||||
Pstream::listGatherValues
|
||||
(
|
||||
fName,
|
||||
fileHandler().comm(),
|
||||
UPstream::msgType()
|
||||
)
|
||||
);
|
||||
|
||||
// Collect local block number
|
||||
label myBlockNumber = -1;
|
||||
{
|
||||
procRangeType group;
|
||||
label proci = fileOperation::detectProcessorPath(fName, group);
|
||||
|
||||
if (proci == -1 && group.empty())
|
||||
{
|
||||
// 'processorsXXX' format so contains all ranks
|
||||
// according to worldComm
|
||||
myBlockNumber = UPstream::myProcNo(UPstream::worldComm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 'processorsXXX_n-m' format so check for the
|
||||
// relative rank
|
||||
myBlockNumber = myProcNo;
|
||||
}
|
||||
}
|
||||
const labelList myBlockNumbers
|
||||
(
|
||||
Pstream::listGatherValues
|
||||
(
|
||||
myBlockNumber,
|
||||
fileHandler().comm(),
|
||||
UPstream::msgType()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Determine for all whether the filename exists in the collated
|
||||
// file.
|
||||
boolList allFound(nProcs, false);
|
||||
|
||||
if (UPstream::master(fileHandler().comm()))
|
||||
{
|
||||
// Store nBlocks and index of file that was used for nBlocks
|
||||
label nBlocks = -1;
|
||||
label blockRanki = -1;
|
||||
forAll(fNames, ranki)
|
||||
{
|
||||
if
|
||||
(
|
||||
blockRanki == -1
|
||||
|| (fNames[ranki] != fNames[blockRanki])
|
||||
)
|
||||
{
|
||||
blockRanki = ranki;
|
||||
IFstream is(fNames[ranki]);
|
||||
nBlocks = decomposedBlockData::getNumBlocks(is);
|
||||
}
|
||||
|
||||
allFound[ranki] = (myBlockNumbers[ranki] < nBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
found = Pstream::listScatterValues
|
||||
(
|
||||
allFound,
|
||||
fileHandler().comm(),
|
||||
UPstream::msgType()
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Globally consistent information about who has a mesh
|
||||
boolList haveFileOnProc
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2012 OpenFOAM Foundation
|
||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -48,32 +48,15 @@ namespace Foam
|
||||
// Forward Declarations
|
||||
class faMesh;
|
||||
|
||||
//- Check for availability of specified file (on all ranks)
|
||||
bitSet haveProcessorFile
|
||||
(
|
||||
const word& name, // eg, "faces"
|
||||
const fileName& instance, // eg, "constant"
|
||||
const fileName& local, // eg, "polyMesh"
|
||||
const Time& runTime,
|
||||
const bool verbose = true
|
||||
);
|
||||
//- Check for availability of given file
|
||||
bool checkFileExistence(const fileName& fName);
|
||||
|
||||
//- Check for availability of specified file (on all ranks)
|
||||
boolList haveMeshFile
|
||||
(
|
||||
const word& name, // eg, "faces"
|
||||
const fileName& instance, // eg, "constant"
|
||||
const fileName& local, // eg, "polyMesh"
|
||||
const Time& runTime,
|
||||
const bool verbose = true
|
||||
);
|
||||
|
||||
//- Check for availability of specified mesh file
|
||||
//- Check for availability of specified mesh file (default: "faces")
|
||||
boolList haveMeshFile
|
||||
(
|
||||
const Time& runTime,
|
||||
const fileName& meshPath,
|
||||
const word& meshFile,
|
||||
const word& meshFile = "faces",
|
||||
const bool verbose = true
|
||||
);
|
||||
|
||||
@ -92,7 +75,7 @@ void masterMeshInstance
|
||||
fileName& pointsInstance
|
||||
);
|
||||
|
||||
} // End namespace Foam
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -21,59 +21,44 @@ Requires
|
||||
|
||||
// Initially all possible objects that are available at the final time
|
||||
List<wordHashSet> availableRegionObjectNames(meshes.size());
|
||||
List<HashTable<wordHashSet>> availableFaRegionObjectNames(meshes.size());
|
||||
List<wordHashSet> availableFaRegionObjectNames(meshes.size());
|
||||
|
||||
forAll(meshes, regioni)
|
||||
{
|
||||
const auto& mesh = meshes[regioni];
|
||||
|
||||
IOobjectList objects;
|
||||
HashTable<IOobjectList> faObjects;
|
||||
IOobjectList faObjects;
|
||||
|
||||
if (doConvertFields && !timeDirs.empty())
|
||||
{
|
||||
// const word& checkTimeDir = timeDirs.back().name();
|
||||
|
||||
// List of volume mesh objects for this instance
|
||||
objects = IOobjectList(mesh, timeDirs.back().name());
|
||||
|
||||
// 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)
|
||||
{
|
||||
objects.filterObjects(fieldSelector);
|
||||
faObjects.filterObjects(fieldSelector);
|
||||
}
|
||||
|
||||
// Remove "*_0" restart fields
|
||||
objects.prune_0();
|
||||
faObjects.prune_0();
|
||||
|
||||
if (!doPointValues)
|
||||
{
|
||||
// Prune point fields if disabled
|
||||
objects.filterClasses(Foam::fieldTypes::is_point, true);
|
||||
}
|
||||
|
||||
|
||||
// The finite-area regions and their fields for this volume region
|
||||
// and instance
|
||||
faObjects.reserve(areaRegionNames.size());
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
IOobjectList objs
|
||||
(
|
||||
faMesh::Registry(mesh),
|
||||
timeDirs.back().name(),
|
||||
polyMesh::regionName(areaName),
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
if (fieldSelector)
|
||||
{
|
||||
objs.filterObjects(fieldSelector);
|
||||
}
|
||||
|
||||
// Remove "*_0" restart fields
|
||||
objs.prune_0();
|
||||
faObjects(areaName) = std::move(objs);
|
||||
}
|
||||
}
|
||||
|
||||
// Volume fields
|
||||
@ -93,29 +78,20 @@ forAll(meshes, regioni)
|
||||
}
|
||||
|
||||
// Area fields
|
||||
for (const word& areaName : areaRegionNames)
|
||||
if (!faObjects.empty())
|
||||
{
|
||||
wordList objectNames;
|
||||
wordList objectNames(faObjects.sortedNames());
|
||||
|
||||
if (const auto iter = faObjects.cfind(areaName); iter.good())
|
||||
{
|
||||
objectNames = iter.val().sortedNames();
|
||||
|
||||
// Check availability for all times...
|
||||
checkData
|
||||
(
|
||||
faMesh::Registry(mesh),
|
||||
timeDirs,
|
||||
objectNames,
|
||||
polyMesh::regionName(areaName)
|
||||
);
|
||||
}
|
||||
|
||||
availableFaRegionObjectNames[regioni].emplace_set
|
||||
// Check availability for all times... (assuming single region)
|
||||
checkData
|
||||
(
|
||||
areaName,
|
||||
std::move(objectNames)
|
||||
mesh.time(),
|
||||
timeDirs,
|
||||
objectNames,
|
||||
faMesh::dbDir(mesh, word::null)
|
||||
);
|
||||
|
||||
availableFaRegionObjectNames[regioni] = objectNames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
@ -15,14 +15,12 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// Cases and meshes per volume region
|
||||
PtrList<ensightCase> ensightCases(regionNames.size());
|
||||
PtrList<ensightMesh> ensightMeshes(regionNames.size());
|
||||
|
||||
// Per volume region can have multiple finite-area regions
|
||||
List<PtrDynList<faMesh>> meshesFa(regionNames.size());
|
||||
List<PtrDynList<ensightCase>> ensightCasesFa(regionNames.size());
|
||||
List<PtrDynList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
||||
PtrList<faMesh> meshesFa(regionNames.size());
|
||||
PtrList<ensightCase> ensightCasesFa(regionNames.size());
|
||||
PtrList<ensightFaMesh> ensightMeshesFa(regionNames.size());
|
||||
|
||||
{
|
||||
forAll(regionNames, regioni)
|
||||
@ -47,7 +45,6 @@ List<PtrDynList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
||||
}
|
||||
}
|
||||
|
||||
// Volume mesh
|
||||
ensightMeshes.set
|
||||
(
|
||||
regioni,
|
||||
@ -62,59 +59,32 @@ List<PtrDynList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
||||
new ensightCase(ensCasePath, ensCaseName, caseOpts)
|
||||
);
|
||||
|
||||
if (!doFiniteArea)
|
||||
if (doFiniteArea)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Note: not every volume region is guaranteed to have
|
||||
// any or all area region(s)
|
||||
|
||||
meshesFa[regioni].reserve_exact(areaRegionNames.size());
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
auto faMeshPtr = faMesh::TryNew(areaName, mesh);
|
||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
|
||||
|
||||
if (faMeshPtr)
|
||||
{
|
||||
meshesFa[regioni].push_back(std::move(faMeshPtr));
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the ensight components
|
||||
const label nAreas = meshesFa[regioni].size();
|
||||
ensightCasesFa[regioni].reserve_exact(nAreas);
|
||||
ensightMeshesFa[regioni].reserve_exact(nAreas);
|
||||
|
||||
for (const faMesh& areaMesh : meshesFa[regioni])
|
||||
{
|
||||
// Use regionName() - automatically filters for defaultRegion
|
||||
const word& areaName = areaMesh.regionName();
|
||||
|
||||
if (areaName.empty())
|
||||
{
|
||||
// single-region
|
||||
ensightCasesFa[regioni].emplace_back
|
||||
ensightCasesFa.set
|
||||
(
|
||||
ensCasePath/"finite-area",
|
||||
"finite-area",
|
||||
caseOpts
|
||||
regioni,
|
||||
new ensightCase
|
||||
(
|
||||
ensCasePath/"finite-area",
|
||||
"finite-area",
|
||||
caseOpts
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// multi-region
|
||||
ensightCasesFa[regioni].emplace_back
|
||||
(
|
||||
ensCasePath/"finite-area"/areaName,
|
||||
areaName,
|
||||
caseOpts
|
||||
);
|
||||
}
|
||||
|
||||
auto& ensFaMesh = ensightMeshesFa[regioni].emplace_back(areaMesh);
|
||||
ensFaMesh.verbose(optVerbose);
|
||||
meshesFa.set(regioni, std::move(faMeshPtr));
|
||||
|
||||
ensightMeshesFa.set
|
||||
(
|
||||
regioni,
|
||||
new ensightFaMesh(meshesFa[regioni])
|
||||
);
|
||||
ensightMeshesFa[regioni].verbose(optVerbose);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,7 +124,6 @@ Usage
|
||||
#include "OFstream.H"
|
||||
#include "Pstream.H"
|
||||
#include "HashOps.H"
|
||||
#include "PtrDynList.H"
|
||||
#include "regionProperties.H"
|
||||
|
||||
#include "fvc.H"
|
||||
@ -173,7 +172,6 @@ int main(int argc, char *argv[])
|
||||
argList::addVerboseOption();
|
||||
|
||||
#include "addAllRegionOptions.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -441,14 +439,6 @@ int main(int argc, char *argv[])
|
||||
// Handle -allRegions, -regions, -region
|
||||
#include "getAllRegionOptions.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Directory management
|
||||
|
||||
@ -528,32 +518,29 @@ int main(int argc, char *argv[])
|
||||
polyMesh::readUpdateState meshState = mesh.readUpdate();
|
||||
const bool moving = (meshState != polyMesh::UNCHANGED);
|
||||
|
||||
// Ensight (fvMesh)
|
||||
// Ensight
|
||||
auto& ensCase = ensightCases[regioni];
|
||||
auto& ensMesh = ensightMeshes[regioni];
|
||||
|
||||
// Finite-area (can be missing)
|
||||
auto* ensFaCasePtr = ensightCasesFa.get(regioni);
|
||||
auto* ensFaMeshPtr = ensightMeshesFa.get(regioni);
|
||||
|
||||
ensCase.setTime(timeDirs[timei], timeIndex);
|
||||
|
||||
// Finite-area (optional)
|
||||
// Accounting exists for each volume region but may be empty
|
||||
auto& ensFaCases = ensightCasesFa[regioni];
|
||||
auto& ensFaMeshes = ensightMeshesFa[regioni];
|
||||
|
||||
for (auto& ensFaCase : ensFaCases)
|
||||
if (ensFaCasePtr)
|
||||
{
|
||||
ensFaCase.setTime(timeDirs[timei], timeIndex);
|
||||
ensFaCasePtr->setTime(timeDirs[timei], timeIndex);
|
||||
}
|
||||
|
||||
// Movement
|
||||
if (moving)
|
||||
{
|
||||
ensMesh.expire();
|
||||
ensMesh.correct();
|
||||
|
||||
for (auto& ensFaMesh : ensFaMeshes)
|
||||
if (ensFaMeshPtr)
|
||||
{
|
||||
ensFaMesh.expire();
|
||||
ensFaMesh.correct();
|
||||
ensFaMeshPtr->expire();
|
||||
ensFaMeshPtr->correct();
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,19 +555,15 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// finite-area
|
||||
forAll(ensFaMeshes, areai)
|
||||
if (ensFaCasePtr && ensFaMeshPtr)
|
||||
{
|
||||
const auto& ensFaCase = ensFaCases[areai];
|
||||
const auto& ensFaMesh = ensFaMeshes[areai];
|
||||
|
||||
autoPtr<ensightGeoFile> os =
|
||||
ensFaCase.newGeometry(hasMovingMesh);
|
||||
ensFaCasePtr->newGeometry(hasMovingMesh);
|
||||
|
||||
ensFaMesh.write(os.ref());
|
||||
ensFaMeshPtr->write(os.ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Objects at this time
|
||||
IOobjectList objects(mesh, runTime.timeName());
|
||||
|
||||
@ -592,37 +575,23 @@ int main(int argc, char *argv[])
|
||||
// Volume, internal, point fields
|
||||
#include "convertVolumeFields.H"
|
||||
|
||||
// finite-area
|
||||
forAll(ensFaMeshes, areai)
|
||||
// The finite-area objects at this time
|
||||
IOobjectList faObjects;
|
||||
|
||||
if (ensFaMeshPtr)
|
||||
{
|
||||
auto* ensFaCasePtr = ensFaCases.get(areai);
|
||||
auto* ensFaMeshPtr = ensFaMeshes.get(areai);
|
||||
faObjects =
|
||||
IOobjectList(ensFaMeshPtr->mesh(), runTime.timeName());
|
||||
|
||||
// The finite-area region objects at this time
|
||||
IOobjectList faObjects;
|
||||
|
||||
if (ensFaMeshPtr)
|
||||
{
|
||||
const word& areaName = ensFaMeshPtr->mesh().name();
|
||||
|
||||
faObjects = IOobjectList
|
||||
(
|
||||
faMesh::Registry(mesh),
|
||||
runTime.timeName(),
|
||||
polyMesh::regionName(areaName),
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
faObjects.filterObjects
|
||||
(
|
||||
availableFaRegionObjectNames[regioni](areaName)
|
||||
);
|
||||
}
|
||||
|
||||
// The finiteArea fields
|
||||
#include "convertAreaFields.H"
|
||||
faObjects.filterObjects
|
||||
(
|
||||
availableFaRegionObjectNames[regioni]
|
||||
);
|
||||
}
|
||||
|
||||
// The finiteArea fields
|
||||
#include "convertAreaFields.H"
|
||||
|
||||
// Lagrangian fields
|
||||
#include "convertLagrangian.H"
|
||||
}
|
||||
@ -635,13 +604,14 @@ int main(int argc, char *argv[])
|
||||
// Write cases
|
||||
forAll(ensightCases, regioni)
|
||||
{
|
||||
// finite-volume
|
||||
ensightCases[regioni].write();
|
||||
}
|
||||
|
||||
// Finite-area (if any)
|
||||
for (const auto& ensFaCase : ensightCasesFa[regioni])
|
||||
forAll(ensightCasesFa, regioni)
|
||||
{
|
||||
if (ensightCasesFa.set(regioni))
|
||||
{
|
||||
ensFaCase.write();
|
||||
ensightCasesFa[regioni].write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,6 +26,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "readFields.H"
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
@ -41,30 +42,26 @@ Foam::label Foam::checkData
|
||||
|
||||
wordHashSet goodFields;
|
||||
|
||||
IOobject io
|
||||
(
|
||||
"any-name", // placeholder
|
||||
"constant", // placeholder
|
||||
local,
|
||||
obr,
|
||||
IOobjectOption::NO_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
for (const word& fieldName : objectNames)
|
||||
{
|
||||
// In case prune_0() not previously used...
|
||||
if (fieldName.ends_with("_0")) continue;
|
||||
// // If prune_0() not previously used...
|
||||
// if (objectNames.ends_with("_0")) continue;
|
||||
|
||||
bool good = false;
|
||||
|
||||
for (const instant& inst : timeDirs)
|
||||
{
|
||||
io.resetHeader(fieldName);
|
||||
io.instance() = inst.name();
|
||||
|
||||
good = io.typeHeaderOk<regIOobject>(false, false);
|
||||
good =
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
inst.name(),
|
||||
local,
|
||||
obr,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
).typeHeaderOk<volScalarField>(false, false);
|
||||
|
||||
if (!good)
|
||||
{
|
||||
|
||||
@ -22,66 +22,24 @@ Description
|
||||
//
|
||||
|
||||
// No subsetting!
|
||||
if (doFiniteArea && !areaRegionNames.empty())
|
||||
if (doFiniteArea)
|
||||
{
|
||||
using reportFields = foamToVtkReportFields;
|
||||
|
||||
// The (region) polyMesh being used. No subsetting possible
|
||||
const auto& basePolyMesh = meshProxy.baseMesh();
|
||||
autoPtr<faMesh> faMeshPtr;
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
const label nAreaFields = faObjects.count(Foam::fieldTypes::is_area);
|
||||
|
||||
if (nAreaFields || withMeshIds)
|
||||
{
|
||||
const bool isDefaultRegion(polyMesh::regionName(areaName).empty());
|
||||
faMeshPtr = faMesh::TryNew(meshProxy.baseMesh());
|
||||
}
|
||||
|
||||
// CAUTION
|
||||
// If we want to have constant access to the HashTable:
|
||||
//
|
||||
// (SEGFAULT)
|
||||
// const auto& faObjs = faObjects.lookup(areaName, IOobjectList());
|
||||
//
|
||||
// Use an empty fallback to avoid binding to a temporary:
|
||||
//
|
||||
// const IOobjectList emptyObjectList;
|
||||
// const auto& faObjs = faObjects.lookup(areaName, emptyObjectList);
|
||||
if (faMeshPtr && (nAreaFields || withMeshIds))
|
||||
{
|
||||
const faMesh& areaMesh = faMeshPtr();
|
||||
|
||||
// Since we do not need the area fields afterwards,
|
||||
// just move them out from the HashTable
|
||||
|
||||
IOobjectList faObjs;
|
||||
if (auto iter = faObjects.find(areaName); iter.good())
|
||||
{
|
||||
faObjs = std::move(iter.val());
|
||||
}
|
||||
|
||||
const label nAreaFields = faObjs.count(Foam::fieldTypes::is_area);
|
||||
|
||||
autoPtr<faMesh> faMeshPtr;
|
||||
|
||||
if (nAreaFields || withMeshIds)
|
||||
{
|
||||
faMeshPtr = faMesh::TryNew(areaName, basePolyMesh);
|
||||
}
|
||||
|
||||
if (!faMeshPtr)
|
||||
{
|
||||
if (!isDefaultRegion)
|
||||
{
|
||||
// Report any area region specified but missing
|
||||
// - silently ignore region0
|
||||
Info<< "No area-mesh [" << polyMesh::regionName(areaName)
|
||||
<< "] on volume-region ["
|
||||
<< basePolyMesh.regionName() << "]" << endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const auto& areaMesh = faMeshPtr();
|
||||
|
||||
Info<< "Using area-mesh [" << polyMesh::regionName(areaName)
|
||||
<< "] on volume-region ["
|
||||
<< basePolyMesh.regionName() << "]" << endl;
|
||||
|
||||
|
||||
reportFields::area(Info, faObjs);
|
||||
reportFields::area(Info, faObjects);
|
||||
|
||||
const auto& pp = faMeshPtr->patch();
|
||||
|
||||
@ -91,12 +49,7 @@ if (doFiniteArea && !areaRegionNames.empty())
|
||||
writeOpts,
|
||||
(
|
||||
outputDir/regionDir/"finite-area"
|
||||
/ (
|
||||
isDefaultRegion
|
||||
? fileName("finiteArea")
|
||||
: fileName(areaName/areaName)
|
||||
)
|
||||
+ timeDesc
|
||||
/ "finiteArea" + timeDesc
|
||||
),
|
||||
UPstream::parRun()
|
||||
);
|
||||
@ -143,7 +96,7 @@ if (doFiniteArea && !areaRegionNames.empty())
|
||||
(
|
||||
writer,
|
||||
areaMesh,
|
||||
faObjs,
|
||||
faObjects,
|
||||
true // syncPar
|
||||
);
|
||||
|
||||
|
||||
@ -135,13 +135,13 @@ Note
|
||||
#include "emptyPolyPatch.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "faceZoneMesh.H"
|
||||
#include "faMesh.H"
|
||||
#include "areaFields.H"
|
||||
#include "fvMeshSubsetProxy.H"
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
#include "HashOps.H"
|
||||
#include "regionProperties.H"
|
||||
#include "stringListOps.H" // For stringListOps::findMatching()
|
||||
|
||||
#include "Cloud.H"
|
||||
#include "readFields.H"
|
||||
@ -434,7 +434,6 @@ int main(int argc, char *argv[])
|
||||
argList::addOptionCompat("one-boundary", {"allPatches", 1806});
|
||||
|
||||
#include "addAllRegionOptions.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
@ -631,16 +630,6 @@ int main(int argc, char *argv[])
|
||||
// Handle -allRegions, -regions, -region
|
||||
#include "getAllRegionOptions.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
|
||||
if (!doFiniteArea)
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Names for sets and zones
|
||||
word cellSelectionName;
|
||||
word faceSetName;
|
||||
@ -788,11 +777,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
// fvMesh fields
|
||||
IOobjectList objects;
|
||||
|
||||
// faMesh fields (multiple finite-area regions per volume region)
|
||||
HashTable<IOobjectList> faObjects;
|
||||
IOobjectList faObjects;
|
||||
|
||||
if (doConvertFields)
|
||||
{
|
||||
@ -800,51 +786,33 @@ int main(int argc, char *argv[])
|
||||
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)
|
||||
{
|
||||
objects.filterObjects(fieldSelector);
|
||||
faObjects.filterObjects(fieldSelector);
|
||||
}
|
||||
|
||||
// Remove "*_0" restart fields
|
||||
objects.prune_0();
|
||||
faObjects.prune_0();
|
||||
|
||||
if (!doPointValues)
|
||||
{
|
||||
// Prune point fields if disabled
|
||||
objects.filterClasses(Foam::fieldTypes::is_point, true);
|
||||
}
|
||||
|
||||
|
||||
// Lists of finite-area fields
|
||||
faObjects.reserve(areaRegionNames.size());
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
// The finite-area objects for given area region.
|
||||
// Add as method to faMeshesRegistry?
|
||||
|
||||
IOobjectList objs
|
||||
(
|
||||
faMesh::Registry(meshProxy.baseMesh()),
|
||||
runTime.timeName(),
|
||||
polyMesh::regionName(areaName),
|
||||
IOobjectOption::NO_REGISTER
|
||||
);
|
||||
|
||||
if (fieldSelector)
|
||||
{
|
||||
objs.filterObjects(fieldSelector);
|
||||
}
|
||||
// Remove "*_0" restart fields
|
||||
objs.prune_0();
|
||||
|
||||
if (!objs.empty())
|
||||
{
|
||||
faObjects.emplace_set(areaName, std::move(objs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (processorFieldsOnly)
|
||||
{
|
||||
// Processor-patches only and continue
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/finiteArea/lnInclude
|
||||
-I$(LIB_SRC)/finiteArea/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume \
|
||||
-lfiniteArea \
|
||||
-lmeshTools \
|
||||
-lgenericPatchFields
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2022-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,7 +47,6 @@ Description
|
||||
#include "areaFields.H"
|
||||
#include "coupledFvPatch.H"
|
||||
#include "coupledFaPatch.H"
|
||||
#include "regionProperties.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -87,18 +86,17 @@ bool consumeUnusedType(const fieldDescription& fieldDesc, Istream& is)
|
||||
//? typedef GeometricField<Type, faePatchField, areaMesh> fieldType3;
|
||||
//? typedef GeometricField<Type, fvsPatchField, volMesh> fieldType4;
|
||||
|
||||
const bool isExpectedType
|
||||
if
|
||||
(
|
||||
fieldDesc.type() == fieldType1::typeName
|
||||
|| fieldDesc.type() == fieldType2::typeName
|
||||
);
|
||||
|
||||
if (isExpectedType)
|
||||
)
|
||||
{
|
||||
(void) pTraits<Type>(is);
|
||||
return true;
|
||||
}
|
||||
|
||||
return isExpectedType;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -124,18 +122,13 @@ bool setCellFieldType
|
||||
(
|
||||
const fieldDescription& fieldDesc,
|
||||
const fvMesh& mesh,
|
||||
const labelUList& selectedCells,
|
||||
const labelList& selectedCells,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
const bool isExpectedType
|
||||
(
|
||||
fieldDesc.type() == fieldType::typeName
|
||||
);
|
||||
|
||||
if (!isExpectedType)
|
||||
if (fieldDesc.type() != fieldType::typeName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -150,9 +143,7 @@ bool setCellFieldType
|
||||
fieldDesc.name(),
|
||||
mesh.thisDb().time().timeName(),
|
||||
mesh.thisDb(),
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||
@ -160,8 +151,13 @@ bool setCellFieldType
|
||||
if (!found)
|
||||
{
|
||||
// Fallback to "constant" directory
|
||||
fieldHeader.resetHeader();
|
||||
fieldHeader.instance() = mesh.thisDb().time().constant();
|
||||
fieldHeader = IOobject
|
||||
(
|
||||
fieldDesc.name(),
|
||||
mesh.thisDb().time().constant(),
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||
}
|
||||
|
||||
@ -175,7 +171,7 @@ bool setCellFieldType
|
||||
|
||||
fieldType field(fieldHeader, mesh, false);
|
||||
|
||||
if (isNull(selectedCells) || (selectedCells.size() == field.size()))
|
||||
if (isNull(selectedCells) || selectedCells.size() == field.size())
|
||||
{
|
||||
field.primitiveFieldRef() = fieldValue;
|
||||
}
|
||||
@ -208,7 +204,7 @@ bool setCellFieldType
|
||||
<< "Field " << fieldDesc.name() << " not found" << endl;
|
||||
}
|
||||
|
||||
return isExpectedType;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -220,18 +216,13 @@ bool setAreaFieldType
|
||||
(
|
||||
const fieldDescription& fieldDesc,
|
||||
const faMesh& mesh,
|
||||
const labelUList& selectedFaces,
|
||||
const labelList& selectedFaces,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
|
||||
|
||||
const bool isExpectedType
|
||||
(
|
||||
fieldDesc.type() == fieldType::typeName
|
||||
);
|
||||
|
||||
if (!isExpectedType)
|
||||
if (fieldDesc.type() != fieldType::typeName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -246,9 +237,7 @@ bool setAreaFieldType
|
||||
fieldDesc.name(),
|
||||
mesh.thisDb().time().timeName(),
|
||||
mesh.thisDb(),
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||
@ -256,8 +245,13 @@ bool setAreaFieldType
|
||||
if (!found)
|
||||
{
|
||||
// Fallback to "constant" directory
|
||||
fieldHeader.resetHeader();
|
||||
fieldHeader.instance() = mesh.thisDb().time().constant(),
|
||||
fieldHeader = IOobject
|
||||
(
|
||||
fieldDesc.name(),
|
||||
mesh.thisDb().time().constant(),
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||
}
|
||||
|
||||
@ -298,7 +292,7 @@ bool setAreaFieldType
|
||||
<< "Field " << fieldDesc.name() << " not found" << endl;
|
||||
}
|
||||
|
||||
return isExpectedType;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -310,18 +304,13 @@ bool setFaceFieldType
|
||||
(
|
||||
const fieldDescription& fieldDesc,
|
||||
const fvMesh& mesh,
|
||||
const labelUList& selectedFaces,
|
||||
const labelList& selectedFaces,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
const bool isExpectedType
|
||||
(
|
||||
fieldDesc.type() == fieldType::typeName
|
||||
);
|
||||
|
||||
if (!isExpectedType)
|
||||
if (fieldDesc.type() != fieldType::typeName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -336,9 +325,7 @@ bool setFaceFieldType
|
||||
fieldDesc.name(),
|
||||
mesh.thisDb().time().timeName(),
|
||||
mesh.thisDb(),
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||
@ -346,8 +333,13 @@ bool setFaceFieldType
|
||||
if (!found)
|
||||
{
|
||||
// Fallback to "constant" directory
|
||||
fieldHeader.resetHeader();
|
||||
fieldHeader.instance() = mesh.thisDb().time().constant();
|
||||
fieldHeader = IOobject
|
||||
(
|
||||
fieldDesc.name(),
|
||||
mesh.thisDb().time().constant(),
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||
}
|
||||
|
||||
@ -363,14 +355,15 @@ bool setFaceFieldType
|
||||
|
||||
// Create flat list of selected faces and their value.
|
||||
Field<Type> allBoundaryValues(mesh.nBoundaryFaces());
|
||||
for (const auto& pfld : field.boundaryField())
|
||||
forAll(field.boundaryField(), patchi)
|
||||
{
|
||||
SubField<Type>
|
||||
(
|
||||
allBoundaryValues,
|
||||
pfld.size(),
|
||||
pfld.patch().offset()
|
||||
) = pfld;
|
||||
field.boundaryField()[patchi].size(),
|
||||
field.boundaryField()[patchi].patch().start()
|
||||
- mesh.nInternalFaces()
|
||||
) = field.boundaryField()[patchi];
|
||||
}
|
||||
|
||||
// Override
|
||||
@ -431,7 +424,8 @@ bool setFaceFieldType
|
||||
(
|
||||
allBoundaryValues,
|
||||
fieldBf[patchi].size(),
|
||||
fieldBf[patchi].patch().offset()
|
||||
fieldBf[patchi].patch().start()
|
||||
- mesh.nInternalFaces()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -451,7 +445,7 @@ bool setFaceFieldType
|
||||
<< "Field " << fieldDesc.name() << " not found" << endl;
|
||||
}
|
||||
|
||||
return isExpectedType;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -466,7 +460,7 @@ struct setCellField
|
||||
(
|
||||
const fieldDescription& fieldDesc,
|
||||
const fvMesh& m,
|
||||
const labelUList& selectedCells,
|
||||
const labelList& selectedCells,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
@ -483,11 +477,11 @@ struct setCellField
|
||||
class iNew
|
||||
{
|
||||
const fvMesh& mesh_;
|
||||
const labelUList& selected_;
|
||||
const labelList& selected_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const fvMesh& mesh, const labelUList& selectedCells) noexcept
|
||||
iNew(const fvMesh& mesh, const labelList& selectedCells)
|
||||
:
|
||||
mesh_(mesh),
|
||||
selected_(selectedCells)
|
||||
@ -534,7 +528,7 @@ struct setFaceField
|
||||
(
|
||||
const fieldDescription& fieldDesc,
|
||||
const fvMesh& m,
|
||||
const labelUList& selectedFaces,
|
||||
const labelList& selectedFaces,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
@ -551,11 +545,11 @@ struct setFaceField
|
||||
class iNew
|
||||
{
|
||||
const fvMesh& mesh_;
|
||||
const labelUList& selected_;
|
||||
const labelList& selected_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const fvMesh& mesh, const labelUList& selectedFaces) noexcept
|
||||
iNew(const fvMesh& mesh, const labelList& selectedFaces)
|
||||
:
|
||||
mesh_(mesh),
|
||||
selected_(selectedFaces)
|
||||
@ -602,7 +596,7 @@ struct setAreaField
|
||||
(
|
||||
const fieldDescription& fieldDesc,
|
||||
const faMesh& m,
|
||||
const labelUList& selectedFaces,
|
||||
const labelList& selectedFaces,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
@ -619,11 +613,11 @@ struct setAreaField
|
||||
class iNew
|
||||
{
|
||||
const faMesh& mesh_;
|
||||
const labelUList& selected_;
|
||||
const labelList& selected_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const faMesh& mesh, const labelUList& selectedFaces) noexcept
|
||||
iNew(const faMesh& mesh, const labelList& selectedFaces)
|
||||
:
|
||||
mesh_(mesh),
|
||||
selected_(selectedFaces)
|
||||
@ -681,7 +675,6 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
#include "addRegionOption.H"
|
||||
#include "addAllFaRegionOptions.H"
|
||||
|
||||
// -------------------------
|
||||
|
||||
@ -693,59 +686,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
// Handle -all-area-regions, -area-regions, -area-region
|
||||
#include "getAllFaRegionOptions.H"
|
||||
autoPtr<faMesh> faMeshPtr;
|
||||
|
||||
if (args.found("no-finite-area"))
|
||||
if (!args.found("no-finite-area"))
|
||||
{
|
||||
areaRegionNames.clear(); // For consistency
|
||||
faMeshPtr = faMesh::TryNew(mesh);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
PtrList<faMesh> faMeshes;
|
||||
|
||||
// Setup all area meshes on this region
|
||||
if (!areaRegionNames.empty()) // ie, !args.found("no-finite-area")
|
||||
if (faMeshPtr)
|
||||
{
|
||||
faMeshes.resize(areaRegionNames.size());
|
||||
|
||||
label nGoodRegions(0);
|
||||
|
||||
for (const word& areaName : areaRegionNames)
|
||||
{
|
||||
autoPtr<faMesh> faMeshPtr = faMesh::TryNew(areaName, mesh);
|
||||
|
||||
if (faMeshPtr)
|
||||
{
|
||||
faMeshes.set(nGoodRegions++, std::move(faMeshPtr));
|
||||
}
|
||||
}
|
||||
|
||||
faMeshes.resize(nGoodRegions);
|
||||
}
|
||||
|
||||
if (faMeshes.size() == 1)
|
||||
{
|
||||
Info<< "Using finite-area mesh";
|
||||
if
|
||||
(
|
||||
const word& name = polyMesh::regionName(faMeshes[0].name());
|
||||
!name.empty()
|
||||
)
|
||||
{
|
||||
Info<< " [" << name << "]";
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
else if (faMeshes.size() > 1)
|
||||
{
|
||||
Info<< "Detected finite-area meshes:";
|
||||
for (const faMesh& areaMesh : faMeshes)
|
||||
{
|
||||
Info<< " [" << areaMesh.name() << "]";
|
||||
}
|
||||
Info<< nl;
|
||||
Info<< "Detected finite-area mesh" << nl;
|
||||
}
|
||||
|
||||
const word dictName("setFieldsDict");
|
||||
@ -763,45 +712,37 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
// Default field values
|
||||
if
|
||||
(
|
||||
const auto* eptr
|
||||
= setFieldsDict.findEntry("defaultFieldValues", keyType::LITERAL)
|
||||
)
|
||||
{
|
||||
ITstream& is = eptr->stream();
|
||||
const entry* eptr =
|
||||
setFieldsDict.findEntry("defaultFieldValues", keyType::LITERAL);
|
||||
|
||||
Info<< "Setting volume field default values" << endl;
|
||||
|
||||
PtrList<setCellField> defaultFieldValues
|
||||
(
|
||||
is,
|
||||
setCellField::iNew(mesh, labelList::null())
|
||||
);
|
||||
|
||||
for (const faMesh& areaMesh : faMeshes)
|
||||
if (eptr)
|
||||
{
|
||||
Info<< "Setting area field default values";
|
||||
ITstream& is = eptr->stream();
|
||||
|
||||
if
|
||||
(
|
||||
const word& name = polyMesh::regionName(areaMesh.name());
|
||||
!name.empty()
|
||||
)
|
||||
{
|
||||
Info<< " [" << name << "]";
|
||||
}
|
||||
Info<< endl;
|
||||
Info<< "Setting volume field default values" << endl;
|
||||
|
||||
is.rewind();
|
||||
|
||||
PtrList<setAreaField> defaultAreaFieldValues
|
||||
PtrList<setCellField> defaultFieldValues
|
||||
(
|
||||
is,
|
||||
setAreaField::iNew(areaMesh, labelList::null())
|
||||
setCellField::iNew(mesh, labelList::null())
|
||||
);
|
||||
|
||||
if (faMeshPtr)
|
||||
{
|
||||
const faMesh& areaMesh = faMeshPtr();
|
||||
is.rewind();
|
||||
|
||||
Info<< "Setting area field default values" << endl;
|
||||
|
||||
PtrList<setAreaField> defaultFieldValues
|
||||
(
|
||||
is,
|
||||
setAreaField::iNew(areaMesh, labelList::null())
|
||||
);
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
@ -827,15 +768,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
labelList selectedCells(subset.sortedToc());
|
||||
|
||||
{
|
||||
FixedList<label, 2> stats;
|
||||
stats[0] = selectedCells.size();
|
||||
stats[1] = mesh.nCells();
|
||||
reduce(stats, sumOp<label>());
|
||||
|
||||
Info<< " Selected " << stats[0] << '/' << stats[1]
|
||||
<< " cells" << nl;
|
||||
}
|
||||
Info<< " Selected "
|
||||
<< returnReduce(selectedCells.size(), sumOp<label>())
|
||||
<< '/'
|
||||
<< returnReduce(mesh.nCells(), sumOp<label>())
|
||||
<< " cells" << nl;
|
||||
|
||||
ITstream& is = region.dict().lookup("fieldValues");
|
||||
|
||||
@ -869,8 +806,10 @@ int main(int argc, char *argv[])
|
||||
setFaceField::iNew(mesh, selectedFaces)
|
||||
);
|
||||
|
||||
for (const faMesh& areaMesh : faMeshes)
|
||||
if (faMeshPtr)
|
||||
{
|
||||
const faMesh& areaMesh = faMeshPtr();
|
||||
|
||||
const labelUList& faceLabels = areaMesh.faceLabels();
|
||||
|
||||
// Transcribe from mesh faces to finite-area addressing
|
||||
@ -889,15 +828,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
areaFaces.resize(nUsed);
|
||||
|
||||
{
|
||||
FixedList<label, 2> stats;
|
||||
stats[0] = areaFaces.size();
|
||||
stats[1] = faceLabels.size();
|
||||
reduce(stats, sumOp<label>());
|
||||
|
||||
Info<< " Selected " << stats[0] << '/' << stats[1]
|
||||
<< " area faces for " << areaMesh.name() << endl;
|
||||
}
|
||||
Info<< " Selected "
|
||||
<< returnReduce(areaFaces.size(), sumOp<label>())
|
||||
<< '/'
|
||||
<< returnReduce(faceLabels.size(), sumOp<label>())
|
||||
<< " area faces" << nl;
|
||||
|
||||
is.rewind();
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ faceSetOption/faceSetOption.C
|
||||
derivedSources=sources/derived
|
||||
|
||||
$(derivedSources)/externalHeatFluxSource/externalHeatFluxSource.C
|
||||
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.cxx
|
||||
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.C
|
||||
$(derivedSources)/contactHeatFluxSource/contactHeatFluxSource.C
|
||||
$(derivedSources)/externalFileSource/externalFileSource.C
|
||||
|
||||
|
||||
@ -81,33 +81,6 @@ Foam::fa::option::option
|
||||
active_(dict.getOrDefault("active", true)),
|
||||
log(true)
|
||||
{
|
||||
// Suffix hint for variable names
|
||||
if
|
||||
(
|
||||
coeffs_.readIfPresent("suffixing", suffixHint_)
|
||||
|| dict.readIfPresent("suffixing", suffixHint_)
|
||||
)
|
||||
{
|
||||
Switch sw = Switch::find(suffixHint_);
|
||||
|
||||
if (sw.good())
|
||||
{
|
||||
if (!sw) // No suffix
|
||||
{
|
||||
suffixHint_.clear();
|
||||
}
|
||||
}
|
||||
else if (suffixHint_ == "default")
|
||||
{
|
||||
sw = true;
|
||||
}
|
||||
|
||||
if (sw) // Default suffix
|
||||
{
|
||||
suffixHint_ = '_' + regionName_;
|
||||
}
|
||||
}
|
||||
|
||||
if (dict.readIfPresent("area", areaName_))
|
||||
{
|
||||
if (!sameRegionNames(areaName_, defaultAreaName))
|
||||
@ -122,14 +95,9 @@ Foam::fa::option::option
|
||||
}
|
||||
}
|
||||
|
||||
Log << incrIndent << indent << "Source: " << name_;
|
||||
|
||||
if (!polyMesh::regionName(areaName_).empty())
|
||||
{
|
||||
Log<< " [" << areaName_ << ']';
|
||||
}
|
||||
|
||||
Info<< decrIndent << endl;
|
||||
Log << incrIndent << indent << "Source: " << name_
|
||||
<< " [" << polyMesh::regionName(areaName_) << ']' << endl
|
||||
<< decrIndent;
|
||||
}
|
||||
|
||||
|
||||
@ -149,20 +117,13 @@ Foam::autoPtr<Foam::fa::option> Foam::fa::option::New
|
||||
coeffs.readIfPresent("area", areaName);
|
||||
|
||||
Info<< indent
|
||||
<< "Selecting finite-area option, type " << modelType;
|
||||
<< "Selecting finite-area option, type " << modelType
|
||||
<< " [" << polyMesh::regionName(areaName) << ']';
|
||||
|
||||
if (sameRegionNames(areaName, defaultAreaName))
|
||||
if (!sameRegionNames(areaName, defaultAreaName))
|
||||
{
|
||||
if (!polyMesh::regionName(areaName).empty())
|
||||
{
|
||||
Info<< " [" << areaName << ']';
|
||||
}
|
||||
Info<< " != " << defaultAreaName << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " [" << areaName << "] != [" << defaultAreaName << ']';
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
|
||||
mesh.time().libs().open
|
||||
|
||||
@ -65,13 +65,10 @@ Usage
|
||||
--> the selected faOption settings | dictionary | no | -
|
||||
active | Flag to (de)activate faOption | bool | no | true
|
||||
log | Flag to log faOption-related info | bool | no | true
|
||||
suffixing | Suffix hint for option variables | word | no | -
|
||||
\endtable
|
||||
|
||||
Note
|
||||
- Source/sink options are to be added to the right-hand side of equations.
|
||||
- Suffixing (true|false|none|default|...) currently selects between
|
||||
no suffix and ('_'+region).
|
||||
|
||||
SourceFiles
|
||||
faOption.C
|
||||
@ -139,9 +136,6 @@ protected:
|
||||
//- The model region name (finite-area)
|
||||
word regionName_;
|
||||
|
||||
//- Suffix hint for variable names (default: "")
|
||||
word suffixHint_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
@ -279,7 +273,7 @@ public:
|
||||
//- The source name
|
||||
const word& name() const noexcept { return name_; }
|
||||
|
||||
//- Return const access to the volume mesh
|
||||
//- Return const access to the mesh database
|
||||
const fvMesh& mesh() const noexcept { return mesh_; }
|
||||
|
||||
//- Return dictionary
|
||||
@ -310,18 +304,6 @@ public:
|
||||
inline bool active(bool on) noexcept;
|
||||
|
||||
|
||||
// Helper Functions
|
||||
|
||||
//- The suffix hint when generating variable names
|
||||
const word& suffixHint() const noexcept { return suffixHint_; }
|
||||
|
||||
//- Return the concatenation of \p base and the suffix hint
|
||||
inline word suffixed(const char* base) const;
|
||||
|
||||
//- Return the concatenation of \p base and the suffix hint
|
||||
inline word suffixed(const std::string& base) const;
|
||||
|
||||
|
||||
// Checks
|
||||
|
||||
//- Is the source active?
|
||||
|
||||
@ -61,18 +61,4 @@ inline const Foam::volSurfaceMapping& Foam::fa::option::vsm() const
|
||||
}
|
||||
|
||||
|
||||
inline Foam::word
|
||||
Foam::fa::option::suffixed(const char* base) const
|
||||
{
|
||||
return word(base + suffixHint_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::word
|
||||
Foam::fa::option::suffixed(const std::string& base) const
|
||||
{
|
||||
return word(base + suffixHint_);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -27,6 +27,7 @@ License
|
||||
|
||||
#include "faOptions.H"
|
||||
#include "faMesh.H"
|
||||
#include "faMeshesRegistry.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -67,7 +68,7 @@ Foam::IOobject createIOobject
|
||||
lookupName,
|
||||
mesh.time().constant(),
|
||||
// located under finite-area
|
||||
faMesh::Registry(mesh),
|
||||
faMeshesRegistry::New(mesh).thisDb(),
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::REGISTER
|
||||
@ -187,7 +188,11 @@ Foam::fa::options& Foam::fa::options::New
|
||||
);
|
||||
|
||||
// Registered under finite-area?
|
||||
auto* ptr = faMesh::Registry(mesh).getObjectPtr<fa::options>(lookupName);
|
||||
auto* ptr =
|
||||
faMeshesRegistry::New(mesh).thisDb().getObjectPtr<fa::options>
|
||||
(
|
||||
lookupName
|
||||
);
|
||||
|
||||
if (!ptr && polyMesh::regionName(defaultAreaName).empty())
|
||||
{
|
||||
|
||||
@ -30,6 +30,7 @@ License
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "volFields.H"
|
||||
#include "famSup.H"
|
||||
#include "zeroGradientFaPatchFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
@ -56,10 +57,13 @@ Foam::fa::contactHeatFluxSource::contactHeatFluxSource
|
||||
:
|
||||
fa::faceSetOption(sourceName, modelType, dict, mesh, defaultAreaName),
|
||||
TName_(dict.getOrDefault<word>("T", "T")),
|
||||
TprimaryName_(dict.getOrDefault<word>("Tprimary", "T")),
|
||||
TprimaryName_(dict.get<word>("Tprimary")),
|
||||
Tprimary_(mesh_.lookupObject<volScalarField>(TprimaryName_)),
|
||||
thicknessLayers_(),
|
||||
kappaLayers_(),
|
||||
contactRes_(0),
|
||||
curTimeIndex_(-1)
|
||||
curTimeIndex_(-1),
|
||||
coupling_()
|
||||
{
|
||||
fieldNames_.resize(1, TName_);
|
||||
|
||||
@ -127,30 +131,30 @@ void Foam::fa::contactHeatFluxSource::addSup
|
||||
const label fieldi
|
||||
)
|
||||
{
|
||||
if (!isActive())
|
||||
if (isActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
DebugInfo
|
||||
<< name() << ": applying source to "
|
||||
<< eqn.psi().name() << endl;
|
||||
|
||||
DebugInfo<< name() << ": applying source to " << eqn.psi().name() << endl;
|
||||
if (curTimeIndex_ != mesh().time().timeIndex())
|
||||
{
|
||||
tmp<DimensionedField<scalar, areaMesh>> htcw(htc());
|
||||
|
||||
if (curTimeIndex_ != mesh().time().timeIndex())
|
||||
{
|
||||
tmp<DimensionedField<scalar, areaMesh>> htcw(htc());
|
||||
// Wall temperature - mapped from primary field to finite-area
|
||||
auto Twall = DimensionedField<scalar, areaMesh>::New
|
||||
(
|
||||
"Tw_" + option::name(),
|
||||
regionMesh(),
|
||||
dimensionedScalar(dimTemperature, Zero)
|
||||
);
|
||||
|
||||
// Wall temperature - mapped from primary field to finite-area
|
||||
auto Twall = DimensionedField<scalar, areaMesh>::New
|
||||
(
|
||||
"Tw_" + option::name(),
|
||||
regionMesh(),
|
||||
dimensionedScalar(dimTemperature, Zero)
|
||||
);
|
||||
vsm().mapInternalToSurface<scalar>(Tprimary_, Twall.ref().field());
|
||||
|
||||
vsm().mapInternalToSurface<scalar>(Tprimary_, Twall.ref().field());
|
||||
eqn += -fam::Sp(htcw(), eqn.psi()) + htcw()*Twall;
|
||||
|
||||
eqn += -fam::Sp(htcw(), eqn.psi()) + htcw()*Twall;
|
||||
|
||||
curTimeIndex_ = mesh().time().timeIndex();
|
||||
curTimeIndex_ = mesh().time().timeIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,14 +190,8 @@ bool Foam::fa::contactHeatFluxSource::read(const dictionary& dict)
|
||||
|
||||
const labelList& patches = regionMesh().whichPolyPatches();
|
||||
|
||||
if (patches.empty())
|
||||
{
|
||||
coupling_.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
coupling_.resize_null(patches.back()+1);
|
||||
}
|
||||
coupling_.clear();
|
||||
coupling_.resize(patches.empty() ? 0 : (patches.last()+1));
|
||||
|
||||
for (const label patchi : patches)
|
||||
{
|
||||
|
||||
@ -40,8 +40,6 @@ Usage
|
||||
{
|
||||
// Mandatory entries (unmodifiable)
|
||||
type contactHeatFluxSource;
|
||||
|
||||
// Optional entries (unmodifiable)
|
||||
Tprimary <TprimaryFieldName>;
|
||||
|
||||
// Optional entries (runtime modifiable)
|
||||
@ -62,19 +60,12 @@ Usage
|
||||
\table
|
||||
Property | Description | Type | Reqd | Dflt
|
||||
type | Type name: contactHeatFluxSource | word | yes | -
|
||||
Tprimary | Name of primary temperature field | word | yes | -
|
||||
T | Name of operand temperature field | word | no | T
|
||||
Tprimary | Name of primary temperature field | word | no | T
|
||||
thicknessLayers | List of thicknesses of layers | scalarList | no | -
|
||||
kappaLayers | List of conductivities of layers | scalarList | cndtnl | -
|
||||
\endtable
|
||||
|
||||
Fields/variables used:
|
||||
\table
|
||||
Property | Description | Type | Deflt
|
||||
T | Temperature | shell | T
|
||||
Tprimary | Temperature | volume | T
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link faOption.H \endlink
|
||||
- \link faceSetOption.H \endlink
|
||||
@ -133,13 +124,13 @@ class contactHeatFluxSource
|
||||
|
||||
// Private Data
|
||||
|
||||
//- Name of shell temperature field (default: "T")
|
||||
//- Name of temperature field
|
||||
word TName_;
|
||||
|
||||
//- Name of volume temperature field (default: "T")
|
||||
const word TprimaryName_;
|
||||
//- Name of primary temperature field
|
||||
word TprimaryName_;
|
||||
|
||||
//- Primary (volume) region temperature
|
||||
//- Primary region temperature
|
||||
const volScalarField& Tprimary_;
|
||||
|
||||
//- Thickness of layers
|
||||
|
||||
@ -72,6 +72,10 @@ Foam::fa::externalHeatFluxSource::externalHeatFluxSource
|
||||
fa::faceSetOption(sourceName, modelType, dict, m, defaultAreaName),
|
||||
mode_(operationModeNames.get("mode", dict)),
|
||||
TName_(dict.getOrDefault<word>("T", "T")),
|
||||
Q_(nullptr),
|
||||
q_(nullptr),
|
||||
h_(nullptr),
|
||||
Ta_(nullptr),
|
||||
emissivity_(dict.getOrDefault<scalar>("emissivity", 0))
|
||||
{
|
||||
fieldNames_.resize(1, TName_);
|
||||
@ -201,11 +205,6 @@ bool Foam::fa::externalHeatFluxSource::read(const dictionary& dict)
|
||||
|
||||
mode_ = operationModeNames.get("mode", dict);
|
||||
|
||||
Q_.reset(nullptr);
|
||||
q_.reset(nullptr);
|
||||
h_.reset(nullptr);
|
||||
Ta_.reset(nullptr);
|
||||
|
||||
switch (mode_)
|
||||
{
|
||||
case fixedPower:
|
||||
|
||||
@ -103,7 +103,7 @@ Usage
|
||||
\verbatim
|
||||
power | Use fixed power (supply Q)
|
||||
flux | Use fixed heat flux (supply q)
|
||||
coefficient | Use fixes heat transfer coefficient (supply h and Ta)
|
||||
coefficient | Use fixes heat transfer coefficient (supply h and T)
|
||||
\endverbatim
|
||||
|
||||
See also
|
||||
@ -159,7 +159,7 @@ private:
|
||||
//- Operation mode
|
||||
operationMode mode_;
|
||||
|
||||
//- Name of shell temperature field (default: "T")
|
||||
//- Name of temperature field
|
||||
word TName_;
|
||||
|
||||
//- Heat power [W]
|
||||
@ -174,7 +174,7 @@ private:
|
||||
//- Ambient temperature [K]
|
||||
autoPtr<Function1<scalar>> Ta_;
|
||||
|
||||
//- Surface emissivity for radiative transfer to ambient (default: 0)
|
||||
//- Optional surface emissivity for radiative transfer to ambient
|
||||
scalar emissivity_;
|
||||
|
||||
|
||||
|
||||
@ -42,12 +42,6 @@ namespace fa
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Implementation
|
||||
#include "jouleHeatingSourceImpl.cxx"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fa::jouleHeatingSource::jouleHeatingSource
|
||||
@ -65,7 +59,7 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed(IOobject::scopedName(typeName, "V")),
|
||||
IOobject::scopedName(typeName, "V_" + regionName_),
|
||||
regionMesh().thisDb().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
@ -74,6 +68,8 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
||||
),
|
||||
regionMesh()
|
||||
),
|
||||
scalarSigmaVsTPtr_(nullptr),
|
||||
tensorSigmaVsTPtr_(nullptr),
|
||||
curTimeIndex_(-1),
|
||||
nIter_(1),
|
||||
anisotropicElectricalConductivity_(false)
|
||||
@ -82,8 +78,6 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
||||
|
||||
fa::option::resetApplied();
|
||||
|
||||
read(dict);
|
||||
|
||||
if (anisotropicElectricalConductivity_)
|
||||
{
|
||||
Info<< " Using tensor electrical conductivity" << endl;
|
||||
@ -96,6 +90,8 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
||||
|
||||
initialiseSigma(coeffs_, scalarSigmaVsTPtr_);
|
||||
}
|
||||
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
@ -109,14 +105,12 @@ void Foam::fa::jouleHeatingSource::addSup
|
||||
const label fieldi
|
||||
)
|
||||
{
|
||||
if (!isActive())
|
||||
if (isActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
DebugInfo
|
||||
<< name() << ": applying source to "
|
||||
<< eqn.psi().name() << endl;
|
||||
|
||||
DebugInfo<< name() << ": applying source to " << eqn.psi().name() << endl;
|
||||
|
||||
{
|
||||
if (curTimeIndex_ != mesh().time().timeIndex())
|
||||
{
|
||||
for (label i = 0; i < nIter_; ++i)
|
||||
@ -124,7 +118,8 @@ void Foam::fa::jouleHeatingSource::addSup
|
||||
if (anisotropicElectricalConductivity_)
|
||||
{
|
||||
// Update sigma as a function of T if required
|
||||
const auto& sigma = updateSigma(tensorSigmaVsTPtr_);
|
||||
const areaTensorField& sigma =
|
||||
updateSigma(tensorSigmaVsTPtr_);
|
||||
|
||||
// Solve the electrical potential equation
|
||||
faScalarMatrix VEqn(fam::laplacian(h*sigma, V_));
|
||||
@ -134,7 +129,8 @@ void Foam::fa::jouleHeatingSource::addSup
|
||||
else
|
||||
{
|
||||
// Update sigma as a function of T if required
|
||||
const auto& sigma = updateSigma(scalarSigmaVsTPtr_);
|
||||
const areaScalarField& sigma =
|
||||
updateSigma(scalarSigmaVsTPtr_);
|
||||
|
||||
// Solve the electrical potential equation
|
||||
faScalarMatrix VEqn(fam::laplacian(h*sigma, V_));
|
||||
@ -149,7 +145,7 @@ void Foam::fa::jouleHeatingSource::addSup
|
||||
// Add the Joule heating contribution
|
||||
const word sigmaName
|
||||
(
|
||||
IOobject::scopedName(typeName, "sigma") + suffixHint()
|
||||
IOobject::scopedName(typeName, "sigma_" + regionName_)
|
||||
);
|
||||
|
||||
areaVectorField gradV("gradV", fac::grad(V_));
|
||||
@ -166,13 +162,15 @@ void Foam::fa::jouleHeatingSource::addSup
|
||||
|
||||
if (anisotropicElectricalConductivity_)
|
||||
{
|
||||
const auto& sigma = obr.lookupObject<areaTensorField>(sigmaName);
|
||||
const auto& sigma =
|
||||
obr.lookupObject<areaTensorField>(sigmaName);
|
||||
|
||||
tsource = (h*sigma & gradV) & gradV;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& sigma = obr.lookupObject<areaScalarField>(sigmaName);
|
||||
const auto& sigma =
|
||||
obr.lookupObject<areaScalarField>(sigmaName);
|
||||
|
||||
tsource = (h*sigma*gradV) & gradV;
|
||||
}
|
||||
@ -115,30 +115,23 @@ Usage
|
||||
- \link faceSetOption.H \endlink
|
||||
|
||||
Note
|
||||
If the \c sigma entry is present, the electrical conductivity is specified
|
||||
as a function of temperature using a \c Function1 type, otherwise
|
||||
the \c sigma field will be read from file.
|
||||
When the \c anisotropicElectricalConductivity flag is set to \c true,
|
||||
\c sigma should be specified as a \em tensor quantity instead of as
|
||||
an isotropic \em scalar quantity.
|
||||
|
||||
BREAKING Naming changes from 2056 and earlier for the fields:
|
||||
\table
|
||||
Field | Scoped names | Scoped names (old)
|
||||
V | \<scope\>:V (suffix) | \<scope\>:V_ + regionName
|
||||
sigma | \<scope\>:sigma (suffix) | \<scope\>:sigma_ + regionName
|
||||
\endtable
|
||||
|
||||
It is possible to replicate the older naming by specifying
|
||||
the \c suffixing to ('_' + regionName).
|
||||
- \c anisotropicElectricalConductivity=true enables
|
||||
anisotropic (tensorial) electrical conductivity.
|
||||
- \c anisotropicElectricalConductivity=false enables
|
||||
isotropic (scalar) electrical conductivity.
|
||||
- The electrical conductivity can be specified using either:
|
||||
- If the \c sigma entry is present the electrical conductivity is specified
|
||||
as a function of temperature using a \c Function1 type.
|
||||
- If not present the \c sigma field will be read from file.
|
||||
- If the \c anisotropicElectricalConductivity flag is set to \c true,
|
||||
\c sigma should be specified as a tensor quantity.
|
||||
|
||||
See also
|
||||
- Foam::Function1
|
||||
- Foam::fv::jouleHeatingSource
|
||||
|
||||
SourceFiles
|
||||
jouleHeatingSource.cxx
|
||||
jouleHeatingSourceImpl.cxx
|
||||
jouleHeatingSource.C
|
||||
jouleHeatingSourceTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -195,13 +188,13 @@ class jouleHeatingSource
|
||||
void initialiseSigma
|
||||
(
|
||||
const dictionary& dict,
|
||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
||||
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||
);
|
||||
|
||||
//- Update the electrical conductivity field
|
||||
template<class Type>
|
||||
const GeometricField<Type, faPatchField, areaMesh>&
|
||||
updateSigma(const autoPtr<Function1<Type>>& sigmaFunctionPtr) const;
|
||||
updateSigma(const autoPtr<Function1<Type>>& sigmaVsTPtr) const;
|
||||
|
||||
|
||||
public:
|
||||
@ -236,22 +229,22 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Evaluation
|
||||
// Evaluation
|
||||
|
||||
//- Add explicit contribution to energy equation
|
||||
virtual void addSup
|
||||
(
|
||||
const areaScalarField& h,
|
||||
const areaScalarField& rho,
|
||||
faMatrix<scalar>& eqn,
|
||||
const label fieldi
|
||||
);
|
||||
//- Add explicit contribution to compressible momentum equation
|
||||
virtual void addSup
|
||||
(
|
||||
const areaScalarField& h,
|
||||
const areaScalarField& rho,
|
||||
faMatrix<scalar>& eqn,
|
||||
const label fieldi
|
||||
);
|
||||
|
||||
|
||||
// IO
|
||||
// IO
|
||||
|
||||
//- Read source dictionary
|
||||
virtual bool read(const dictionary& dict);
|
||||
//- Read source dictionary
|
||||
virtual bool read(const dictionary& dict);
|
||||
};
|
||||
|
||||
|
||||
@ -262,6 +255,12 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "jouleHeatingSourceTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -33,21 +33,16 @@ template<class Type>
|
||||
void Foam::fa::jouleHeatingSource::initialiseSigma
|
||||
(
|
||||
const dictionary& dict,
|
||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
||||
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
|
||||
|
||||
const word sigmaName
|
||||
(
|
||||
IOobject::scopedName(typeName, "sigma") + suffixHint()
|
||||
);
|
||||
|
||||
auto& obr = regionMesh().thisDb();
|
||||
|
||||
IOobject io
|
||||
(
|
||||
sigmaName,
|
||||
IOobject::scopedName(typeName, "sigma_" + regionName_),
|
||||
obr.time().timeName(),
|
||||
obr,
|
||||
IOobject::NO_READ,
|
||||
@ -57,11 +52,11 @@ void Foam::fa::jouleHeatingSource::initialiseSigma
|
||||
|
||||
autoPtr<FieldType> tsigma;
|
||||
|
||||
// Is sigma defined using a Function1 type?
|
||||
sigmaFunctionPtr = Function1<Type>::NewIfPresent("sigma", dict, &mesh_);
|
||||
|
||||
if (sigmaFunctionPtr)
|
||||
if (dict.found("sigma"))
|
||||
{
|
||||
// Sigma to be defined using a Function1 type
|
||||
sigmaVsTPtr = Function1<Type>::New("sigma", dict, &mesh_);
|
||||
|
||||
tsigma.reset
|
||||
(
|
||||
new FieldType
|
||||
@ -94,34 +89,31 @@ template<class Type>
|
||||
const Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>&
|
||||
Foam::fa::jouleHeatingSource::updateSigma
|
||||
(
|
||||
const autoPtr<Function1<Type>>& sigmaFunctionPtr
|
||||
const autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||
) const
|
||||
{
|
||||
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
|
||||
|
||||
const word sigmaName
|
||||
(
|
||||
IOobject::scopedName(typeName, "sigma") + suffixHint()
|
||||
);
|
||||
|
||||
const auto& obr = regionMesh().thisDb();
|
||||
|
||||
auto& sigma = obr.lookupObjectRef<FieldType>(sigmaName);
|
||||
auto& sigma =
|
||||
obr.lookupObjectRef<FieldType>
|
||||
(
|
||||
IOobject::scopedName(typeName, "sigma_" + regionName_)
|
||||
);
|
||||
|
||||
if (!sigmaFunctionPtr)
|
||||
if (!sigmaVsTPtr)
|
||||
{
|
||||
// Electrical conductivity field, sigma, was specified by the user
|
||||
return sigma;
|
||||
}
|
||||
|
||||
const auto& sigmaFunction = sigmaFunctionPtr();
|
||||
|
||||
const auto& T = obr.lookupObject<areaScalarField>(TName_);
|
||||
|
||||
// Internal field
|
||||
forAll(sigma, i)
|
||||
{
|
||||
sigma[i] = sigmaFunction.value(T[i]);
|
||||
sigma[i] = sigmaVsTPtr->value(T[i]);
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +127,7 @@ Foam::fa::jouleHeatingSource::updateSigma
|
||||
const scalarField& Tbf = T.boundaryField()[patchi];
|
||||
forAll(pf, facei)
|
||||
{
|
||||
pf[facei] = sigmaFunction.value(Tbf[facei]);
|
||||
pf[facei] = sigmaVsTPtr->value(Tbf[facei]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28,7 +28,6 @@ License
|
||||
|
||||
#include "faMesh.H"
|
||||
#include "faMeshBoundaryHalo.H"
|
||||
#include "faMeshesRegistry.H"
|
||||
#include "faGlobalMeshData.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
@ -160,12 +159,6 @@ const Foam::objectRegistry* Foam::faMesh::registry(const polyMesh& pMesh)
|
||||
// return obr.cfindObject<objectRegistry>(faMesh::prefix());
|
||||
// }
|
||||
|
||||
// Forwarding
|
||||
const Foam::objectRegistry& Foam::faMesh::Registry(const polyMesh& pMesh)
|
||||
{
|
||||
return faMeshesRegistry::Registry(pMesh);
|
||||
}
|
||||
|
||||
|
||||
const Foam::faMesh& Foam::faMesh::mesh
|
||||
(
|
||||
|
||||
@ -751,14 +751,10 @@ public:
|
||||
|
||||
// Database
|
||||
|
||||
//- Find the singleton parent registry (on the polyMesh)
|
||||
//- that contains all objects related to finite-area.
|
||||
//- The parent registry containing all finite-area meshes
|
||||
//- on the polyMesh.
|
||||
static const objectRegistry* registry(const polyMesh& pMesh);
|
||||
|
||||
//- Return the singleton parent registry (on the polyMesh)
|
||||
//- that contains all objects related to finite-area.
|
||||
static const objectRegistry& Registry(const polyMesh& pMesh);
|
||||
|
||||
//- The single-region finite-area region on the polyMesh.
|
||||
//- Uses lookupObject semantics - Fatal if non-existent
|
||||
static const faMesh& mesh(const polyMesh& pMesh);
|
||||
|
||||
@ -27,8 +27,8 @@ License
|
||||
|
||||
#include "faMesh.H"
|
||||
#include "faMeshesRegistry.H"
|
||||
#include "polyMesh.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
@ -43,7 +43,6 @@ Foam::faMeshRegistry::faMeshRegistry
|
||||
IOobject
|
||||
(
|
||||
(areaName.empty() ? polyMesh::defaultRegion : areaName),
|
||||
mesh.thisDb().time().timeName(),
|
||||
faMeshesRegistry::New(mesh).thisDb(),
|
||||
IOobjectOption::NO_READ,
|
||||
IOobjectOption::AUTO_WRITE,
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2023-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -86,8 +86,6 @@ bool Foam::faMeshesRegistry::writeObject
|
||||
const bool writeOnProc
|
||||
) const
|
||||
{
|
||||
// Could also restrict to faMesh only...
|
||||
//
|
||||
// for (const faMesh& m : objects_.csorted<faMesh>())
|
||||
// {
|
||||
// m.write(writeOnProc);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2023-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -144,34 +144,14 @@ public:
|
||||
explicit faMeshesRegistry(const polyMesh& mesh);
|
||||
|
||||
|
||||
// Factory Methods
|
||||
|
||||
//- Return the registry of objects on the singleton.
|
||||
// Same as New(mesh).thisDb()
|
||||
FOAM_NO_DANGLING_REFERENCE //< Reference stored in registry
|
||||
static const objectRegistry& Registry(const polyMesh& mesh)
|
||||
{
|
||||
return MeshObject_type::New(mesh).thisDb();
|
||||
}
|
||||
|
||||
|
||||
// Database
|
||||
|
||||
// It redirects to the private objects but uses some
|
||||
// objectRegistry method naming
|
||||
|
||||
//- The registry of the objects
|
||||
//- Return the object registry
|
||||
const objectRegistry& thisDb() const noexcept
|
||||
{
|
||||
return objects_;
|
||||
}
|
||||
|
||||
//- Local relative to time
|
||||
const fileName& dbDir() const
|
||||
{
|
||||
return objects_.dbDir();
|
||||
}
|
||||
|
||||
//- The polyMesh reference
|
||||
const polyMesh& mesh() const noexcept
|
||||
{
|
||||
|
||||
@ -57,6 +57,7 @@ writeDictionary/writeDictionary.C
|
||||
writeObjects/writeObjects.C
|
||||
|
||||
thermoCoupleProbes/thermoCoupleProbes.C
|
||||
radiometerProbes/radiometerProbes.C
|
||||
|
||||
syncObjects/syncObjects.C
|
||||
|
||||
|
||||
@ -9,7 +9,9 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/ODE/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||
-I$(LIB_SRC)/transportModels/compressible/lnInclude
|
||||
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
|
||||
-I$(LIB_SRC)/parallel/distributed/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-lfiniteVolume \
|
||||
@ -22,4 +24,6 @@ LIB_LIBS = \
|
||||
-lsampling \
|
||||
-lODE \
|
||||
-lfluidThermophysicalModels \
|
||||
-lcompressibleTransportModels
|
||||
-lcompressibleTransportModels \
|
||||
-lradiationModels \
|
||||
-ldistributed
|
||||
|
||||
@ -0,0 +1,260 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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 "radiometerProbes.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace functionObjects
|
||||
{
|
||||
defineTypeNameAndDebug(radiometerProbes, 0);
|
||||
addToRunTimeSelectionTable(functionObject, radiometerProbes, dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::functionObjects::radiometerProbes::writeFileHeader(Ostream& os)
|
||||
{
|
||||
const pointField& locs = probeLocations();
|
||||
|
||||
writeCommented(os, "Probe,Location,Normal");
|
||||
|
||||
os << nl;
|
||||
for (label i = 0; i < szProbes_; ++i)
|
||||
{
|
||||
const vector& loc = locs[i];
|
||||
const vector& n = n_[i];
|
||||
|
||||
os << '#' << ' ' << i
|
||||
<< ',' << loc.x() << ',' << loc.y() << ',' << loc.z()
|
||||
<< ',' << n.x() << ',' << n.y() << ',' << n.z()
|
||||
<< nl;
|
||||
}
|
||||
|
||||
os << "# Time";
|
||||
for (int i = 0; i < szProbes_; ++i)
|
||||
{
|
||||
os << ',' << i;
|
||||
}
|
||||
os << endl;
|
||||
|
||||
writtenHeader_ = true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::radiometerProbes::radiometerProbes
|
||||
(
|
||||
const word& name,
|
||||
const Time& runTime,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
regionFunctionObject(name, runTime, dict),
|
||||
internalProber(mesh_, dict),
|
||||
writeFile(mesh_, name, typeName, dict),
|
||||
dom_(mesh_.lookupObject<radiation::fvDOM>("radiationProperties")),
|
||||
firstIter_(true)
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::functionObjects::radiometerProbes::read(const dictionary& dict)
|
||||
{
|
||||
if
|
||||
(
|
||||
!(
|
||||
regionFunctionObject::read(dict)
|
||||
&& internalProber::read(dict)
|
||||
&& writeFile::read(dict)
|
||||
)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Skip if the radiation model is inactive
|
||||
if (!dom_.radiation())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "The radiation model is inactive."
|
||||
<< "Skipping the function object " << type() << ' ' << name()
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Log << type() << ':' << name() << ": read" << nl << nl;
|
||||
|
||||
|
||||
// Probe locations are read by 'internalProber'
|
||||
szProbes_ = this->size();
|
||||
|
||||
// If/when fvDOM is updated, the 'read' func is assumed to be executed to
|
||||
// update the fvDOM properties
|
||||
nRay_ = dom_.nRay();
|
||||
|
||||
if (!szProbes_ || !nRay_)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "size(probe locations): " << szProbes_ << nl
|
||||
<< "size(rays): " << nRay_ << nl
|
||||
<< "The input size of probe locations and rays cannot be zero."
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Read and check size consistency of probe normals with probe locations
|
||||
dict.readEntry("probeNormals", n_);
|
||||
if (n_.size() != szProbes_)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "size(probe locations): " << szProbes_ << nl
|
||||
<< "size(probe normals): " << n_.size() << nl
|
||||
<< "The input size of probe locations and normals must match."
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
n_.normalise();
|
||||
|
||||
|
||||
// Pre-compute and cache inner product of 'n_' and 'dAve_', and 'C_'
|
||||
// This simplification of calculation is valid only if I is non-negative
|
||||
n_dAve_.resize(nRay_);
|
||||
C_.resize(nRay_);
|
||||
|
||||
for (label rayi = 0; rayi < nRay_; ++rayi)
|
||||
{
|
||||
const vector& dAvei = dom_.IRay(rayi).dAve();
|
||||
|
||||
scalarList& n_dAveRay = n_dAve_[rayi];
|
||||
boolList& Cray = C_[rayi];
|
||||
|
||||
n_dAveRay.resize(szProbes_, Zero);
|
||||
Cray.resize(szProbes_, false);
|
||||
|
||||
for (label pi = 0; pi < szProbes_; ++pi)
|
||||
{
|
||||
n_dAveRay[pi] = n_[pi] & dAvei;
|
||||
|
||||
if (n_dAveRay[pi] < 0) // ray entering the probe
|
||||
{
|
||||
Cray[pi] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qin_.resize(szProbes_);
|
||||
|
||||
|
||||
if (writeFile::canResetFile())
|
||||
{
|
||||
writeFile::resetFile(typeName);
|
||||
}
|
||||
|
||||
if (writeFile::canWriteHeader())
|
||||
{
|
||||
writeFileHeader(file());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::radiometerProbes::execute()
|
||||
{
|
||||
// Skip if there is no probe to sample, or the radiation model is inactive
|
||||
if (!szProbes_ || !dom_.radiation() || !shouldCalcThisStep())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Log << type() << ' ' << name() << ": execute" << nl << nl;
|
||||
|
||||
qin_ = Zero; // resized in 'read'
|
||||
|
||||
for (label rayi = 0; rayi < nRay_; ++rayi)
|
||||
{
|
||||
// Radiative intensity field for this ray
|
||||
const volScalarField& I = dom_.IRay(rayi).I();
|
||||
|
||||
// Sample radiative intensity ray at probe locations
|
||||
tmp<scalarField> tIp = internalProber::sample(I);
|
||||
const scalarField& Ip = tIp.cref();
|
||||
|
||||
const scalarList& n_dAveRay = n_dAve_[rayi];
|
||||
const boolList& Cray = C_[rayi];
|
||||
|
||||
// Add incident radiative heat flux per probe location for each ray
|
||||
for (label pi = 0; pi < szProbes_; ++pi)
|
||||
{
|
||||
if (Cray[pi])
|
||||
{
|
||||
qin_[pi] += Ip[pi]*n_dAveRay[pi];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::radiometerProbes::write()
|
||||
{
|
||||
// Skip if there is no probe to sample, or the radiation model is inactive
|
||||
if (!szProbes_ || !dom_.radiation() || !shouldCalcThisStep())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Log << type() << ' ' << name() << ": write" << nl << nl;
|
||||
|
||||
if (UPstream::master())
|
||||
{
|
||||
Ostream& os = file();
|
||||
|
||||
os << mesh_.time().timeOutputValue();
|
||||
for (label pi = 0; pi < szProbes_; ++pi)
|
||||
{
|
||||
os << ',' << qin_[pi];
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
|
||||
firstIter_ = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,200 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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::functionObjects::radiometerProbes
|
||||
|
||||
Group
|
||||
grpUtilitiesFunctionObjects
|
||||
|
||||
Description
|
||||
Probes the incident radiative heat flux, qin, at arbitrary points within a
|
||||
domain.
|
||||
|
||||
Usage
|
||||
Minimal example by using \c system/controlDict.functions:
|
||||
\verbatim
|
||||
radiometer
|
||||
{
|
||||
// Mandatory entries
|
||||
type radiometerProbes;
|
||||
libs (utilityFunctionObjects);
|
||||
probeLocations (<vectorList>);
|
||||
probeNormals (<vectorList>);
|
||||
|
||||
// Inherited entries
|
||||
...
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
type | Type name: radiometerProbes | word | yes | -
|
||||
libs | Library name: utilityFunctionObjects | word | yes | -
|
||||
probeLocations | Locations of probes | vectorList | yes | -
|
||||
probeNormals | Normals of specified probes | vectorList | yes | -
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link regionFunctionObject.H \endlink
|
||||
- \link internalProber.H \endlink
|
||||
- \link writeFile.H \endlink
|
||||
- \link fvDOM.H \endlink
|
||||
|
||||
Note
|
||||
- The function object can only be used with the \c fvDOM radiation model.
|
||||
- The \c solverFreq input of the \c fvDOM model has superiority over
|
||||
\c executeControl and \c writeControl entries.
|
||||
|
||||
SourceFiles
|
||||
radiometerProbes.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_functionObjects_radiometerProbes_H
|
||||
#define Foam_functionObjects_radiometerProbes_H
|
||||
|
||||
#include "regionFunctionObject.H"
|
||||
#include "internalProber.H"
|
||||
#include "writeFile.H"
|
||||
#include "fvDOM.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace functionObjects
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class radiometerProbes Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class radiometerProbes
|
||||
:
|
||||
public regionFunctionObject,
|
||||
public internalProber,
|
||||
public writeFile
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Const reference to the underlying radiation model
|
||||
const radiation::fvDOM& dom_;
|
||||
|
||||
//- Normal vectors of the specified probes
|
||||
vectorField n_;
|
||||
|
||||
//- Pre-computed inner product of probe normals (n_) and average
|
||||
//- solid-angle direction (dAve) per radiative intensity ray
|
||||
List<scalarList> n_dAve_;
|
||||
|
||||
//- Directional selection coefficient for radiative intensity rays
|
||||
// false: ray entering the probe
|
||||
// true: ray leaving the probe
|
||||
List<boolList> C_;
|
||||
|
||||
//- Incident radiative heat flux per probe location
|
||||
scalarField qin_;
|
||||
|
||||
//- Number of radiative intensity rays
|
||||
label nRay_;
|
||||
|
||||
//- Number of probe locations/normals
|
||||
label szProbes_;
|
||||
|
||||
//- Flag to identify whether the iteration is the first iteration
|
||||
// Resets with a restarted simulation
|
||||
bool firstIter_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Write file-header information into the output file
|
||||
virtual void writeFileHeader(Ostream& os);
|
||||
|
||||
//- Return the flag to decide if radiation-model calculations are
|
||||
//- performed, so that function object calculations can proceed
|
||||
bool shouldCalcThisStep() const
|
||||
{
|
||||
return
|
||||
firstIter_
|
||||
|| (mesh_.time().timeIndex() % dom_.solverFreq() == 0);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("radiometerProbes");
|
||||
|
||||
|
||||
// Generated Methods
|
||||
|
||||
//- No copy construct
|
||||
radiometerProbes(const radiometerProbes&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const radiometerProbes&) = delete;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from name, Time and dictionary
|
||||
radiometerProbes
|
||||
(
|
||||
const word& name,
|
||||
const Time& runTime,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~radiometerProbes() = default;
|
||||
|
||||
|
||||
// Public Member Functions
|
||||
|
||||
//- Read the function object settings
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
//- Execute the function object
|
||||
virtual bool execute();
|
||||
|
||||
//- Write to data files/fields and to streams
|
||||
virtual bool write();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace functionObjects
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -76,7 +76,7 @@ Foam::functionObjects::thermoCoupleProbes::thermoCoupleProbes
|
||||
}
|
||||
else
|
||||
{
|
||||
Ttc_ = probes::sample(thermo_.T());
|
||||
Ttc_ = prober().sample(thermo_.T());
|
||||
}
|
||||
|
||||
// Note: can only create the solver once all samples have been found
|
||||
@ -89,7 +89,7 @@ Foam::functionObjects::thermoCoupleProbes::thermoCoupleProbes
|
||||
|
||||
Foam::label Foam::functionObjects::thermoCoupleProbes::nEqns() const
|
||||
{
|
||||
return this->size();
|
||||
return prober().size();
|
||||
}
|
||||
|
||||
|
||||
@ -108,19 +108,21 @@ void Foam::functionObjects::thermoCoupleProbes::derivatives
|
||||
scalarField Cpc(y.size(), Zero);
|
||||
scalarField kappac(y.size(), Zero);
|
||||
|
||||
const auto& p = prober();
|
||||
|
||||
if (radiationFieldName_ != "none")
|
||||
{
|
||||
G = sample(mesh_.lookupObject<volScalarField>(radiationFieldName_));
|
||||
G = p.sample(mesh_.lookupObject<volScalarField>(radiationFieldName_));
|
||||
}
|
||||
|
||||
Tc = probes::sample(thermo_.T());
|
||||
Tc = p.sample(thermo_.T());
|
||||
|
||||
Uc = mag(this->sample(mesh_.lookupObject<volVectorField>(UName_)));
|
||||
Uc = mag(p.sample(mesh_.lookupObject<volVectorField>(UName_)));
|
||||
|
||||
rhoc = this->sample(thermo_.rho()());
|
||||
kappac = this->sample(thermo_.kappa()());
|
||||
muc = this->sample(thermo_.mu()());
|
||||
Cpc = this->sample(thermo_.Cp()());
|
||||
rhoc = p.sample(thermo_.rho()());
|
||||
kappac = p.sample(thermo_.kappa()());
|
||||
muc = p.sample(thermo_.mu()());
|
||||
Cpc = p.sample(thermo_.Cp()());
|
||||
|
||||
scalarField Re(rhoc*Uc*d_/muc);
|
||||
scalarField Pr(Cpc*muc/kappac);
|
||||
@ -163,7 +165,7 @@ void Foam::functionObjects::thermoCoupleProbes::jacobian
|
||||
|
||||
bool Foam::functionObjects::thermoCoupleProbes::write()
|
||||
{
|
||||
if (!pointField::empty())
|
||||
if (!prober().empty())
|
||||
{
|
||||
(void) prepare(ACTION_WRITE);
|
||||
|
||||
@ -182,7 +184,7 @@ bool Foam::functionObjects::thermoCoupleProbes::write()
|
||||
|
||||
bool Foam::functionObjects::thermoCoupleProbes::execute()
|
||||
{
|
||||
if (!pointField::empty())
|
||||
if (!prober().empty())
|
||||
{
|
||||
scalar dt = mesh_.time().deltaTValue();
|
||||
scalar t = mesh_.time().value();
|
||||
|
||||
@ -42,7 +42,8 @@ void Foam::functionObjects::thermoCoupleProbes::writeValues
|
||||
|
||||
os << setw(w) << timeValue;
|
||||
|
||||
forAll(*this, probei)
|
||||
const pointField& probes = prober().probeLocations();
|
||||
forAll(probes, probei)
|
||||
{
|
||||
// if (includeOutOfBounds_ || processor_[probei] != -1)
|
||||
{
|
||||
|
||||
@ -14,7 +14,7 @@ $(derivedSources)/buoyancyEnergy/buoyancyEnergy.C
|
||||
$(derivedSources)/buoyancyForce/buoyancyForce.C
|
||||
$(derivedSources)/directionalPressureGradientExplicitSource/directionalPressureGradientExplicitSource.C
|
||||
$(derivedSources)/explicitPorositySource/explicitPorositySource.C
|
||||
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.cxx
|
||||
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.C
|
||||
$(derivedSources)/meanVelocityForce/meanVelocityForce.C
|
||||
$(derivedSources)/meanVelocityForce/patchMeanVelocityForce/patchMeanVelocityForce.C
|
||||
$(derivedSources)/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.C
|
||||
|
||||
@ -29,6 +29,7 @@ License
|
||||
#include "fvMatrices.H"
|
||||
#include "fvmLaplacian.H"
|
||||
#include "fvcGrad.H"
|
||||
#include "zeroGradientFvPatchField.H"
|
||||
#include "basicThermo.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
@ -44,12 +45,6 @@ namespace fv
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Implementation
|
||||
#include "jouleHeatingSourceImpl.cxx"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::volSymmTensorField>
|
||||
@ -120,8 +115,11 @@ Foam::fv::jouleHeatingSource::jouleHeatingSource
|
||||
),
|
||||
mesh
|
||||
),
|
||||
curTimeIndex_(-1),
|
||||
anisotropicElectricalConductivity_(false)
|
||||
anisotropicElectricalConductivity_(false),
|
||||
scalarSigmaVsTPtr_(nullptr),
|
||||
vectorSigmaVsTPtr_(nullptr),
|
||||
csysPtr_(nullptr),
|
||||
curTimeIndex_(-1)
|
||||
{
|
||||
// Set the field name to that of the energy
|
||||
// field from which the temperature is obtained
|
||||
@ -164,7 +162,7 @@ void Foam::fv::jouleHeatingSource::addSup
|
||||
else
|
||||
{
|
||||
// Update sigma as a function of T if required
|
||||
const auto& sigma = updateSigma(scalarSigmaVsTPtr_);
|
||||
const volScalarField& sigma = updateSigma(scalarSigmaVsTPtr_);
|
||||
|
||||
// Solve the electrical potential equation
|
||||
fvScalarMatrix VEqn(fvm::laplacian(sigma, V_));
|
||||
@ -228,7 +226,7 @@ bool Foam::fv::jouleHeatingSource::read(const dictionary& dict)
|
||||
|
||||
initialiseSigma(coeffs_, scalarSigmaVsTPtr_);
|
||||
|
||||
csysPtr_.reset(nullptr); // Do not need coordinate system
|
||||
csysPtr_.clear(); // Do not need coordinate system
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -137,28 +137,25 @@ Note
|
||||
anisotropic (vectorial) electrical conductivity.
|
||||
- \c anisotropicElectricalConductivity=false enables
|
||||
isotropic (scalar) electrical conductivity.
|
||||
|
||||
The electrical conductivity can be specified using either:
|
||||
- The electrical conductivity can be specified using either:
|
||||
- If the \c sigma entry is present the electrical conductivity is specified
|
||||
as a function of temperature using a \c Function1 type.
|
||||
- If not present the \c sigma field will be read from file.
|
||||
- If the \c anisotropicElectricalConductivity flag is set to \c true,
|
||||
\c sigma should be specified as a vector quantity.
|
||||
.
|
||||
|
||||
See also
|
||||
- Foam::Function1
|
||||
- Foam::coordSystem
|
||||
- Foam::fa::jouleHeatingSource
|
||||
|
||||
SourceFiles
|
||||
jouleHeatingSource.cxx
|
||||
jouleHeatingSourceImpl.cxx
|
||||
jouleHeatingSource.C
|
||||
jouleHeatingSourceTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_fv_jouleHeatingSource_H
|
||||
#define Foam_fv_jouleHeatingSource_H
|
||||
#ifndef fv_jouleHeatingSource_H
|
||||
#define fv_jouleHeatingSource_H
|
||||
|
||||
#include "fvOption.H"
|
||||
#include "Function1.H"
|
||||
@ -188,6 +185,9 @@ class jouleHeatingSource
|
||||
//- Electrical potential field / [V]
|
||||
volScalarField V_;
|
||||
|
||||
//- Flag to indicate that the electrical conductivity is anisotropic
|
||||
bool anisotropicElectricalConductivity_;
|
||||
|
||||
//- Electrical conductivity as a scalar function of temperature
|
||||
autoPtr<Function1<scalar>> scalarSigmaVsTPtr_;
|
||||
|
||||
@ -200,9 +200,6 @@ class jouleHeatingSource
|
||||
//- Current time index (used for updating)
|
||||
label curTimeIndex_;
|
||||
|
||||
//- Flag to indicate that the electrical conductivity is anisotropic
|
||||
bool anisotropicElectricalConductivity_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -217,13 +214,13 @@ class jouleHeatingSource
|
||||
void initialiseSigma
|
||||
(
|
||||
const dictionary& dict,
|
||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
||||
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||
);
|
||||
|
||||
//- Update the electrical conductivity field
|
||||
template<class Type>
|
||||
const GeometricField<Type, fvPatchField, volMesh>&
|
||||
updateSigma(const autoPtr<Function1<Type>>& sigmaFunctionPtr) const;
|
||||
updateSigma(const autoPtr<Function1<Type>>& sigmaVsTPtr) const;
|
||||
|
||||
|
||||
public:
|
||||
@ -256,21 +253,21 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Evaluation
|
||||
// Evaluation
|
||||
|
||||
//- Add explicit contribution to energy equation
|
||||
virtual void addSup
|
||||
(
|
||||
const volScalarField& rho,
|
||||
fvMatrix<scalar>& eqn,
|
||||
const label fieldi
|
||||
);
|
||||
//- Add explicit contribution to compressible momentum equation
|
||||
virtual void addSup
|
||||
(
|
||||
const volScalarField& rho,
|
||||
fvMatrix<scalar>& eqn,
|
||||
const label fieldi
|
||||
);
|
||||
|
||||
|
||||
// IO
|
||||
// IO
|
||||
|
||||
//- Read source dictionary
|
||||
virtual bool read(const dictionary& dict);
|
||||
//- Read source dictionary
|
||||
virtual bool read(const dictionary& dict);
|
||||
};
|
||||
|
||||
|
||||
@ -281,6 +278,12 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "jouleHeatingSourceTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,25 +27,18 @@ License
|
||||
|
||||
#include "emptyFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::fv::jouleHeatingSource::initialiseSigma
|
||||
(
|
||||
const dictionary& dict,
|
||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
||||
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
||||
|
||||
const word sigmaName
|
||||
(
|
||||
IOobject::scopedName(typeName, "sigma")
|
||||
);
|
||||
|
||||
IOobject io
|
||||
(
|
||||
sigmaName,
|
||||
IOobject::scopedName(typeName, "sigma"),
|
||||
mesh_.time().timeName(),
|
||||
mesh_.thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -55,11 +48,11 @@ void Foam::fv::jouleHeatingSource::initialiseSigma
|
||||
|
||||
autoPtr<FieldType> tsigma;
|
||||
|
||||
// Is sigma defined using a Function1 ?
|
||||
sigmaFunctionPtr = Function1<Type>::NewIfPresent("sigma", dict, &mesh_);
|
||||
|
||||
if (sigmaFunctionPtr)
|
||||
if (dict.found("sigma"))
|
||||
{
|
||||
// Sigma to be defined using a Function1 type
|
||||
sigmaVsTPtr = Function1<Type>::New("sigma", dict, &mesh_);
|
||||
|
||||
tsigma.reset
|
||||
(
|
||||
new FieldType
|
||||
@ -92,32 +85,28 @@ template<class Type>
|
||||
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>&
|
||||
Foam::fv::jouleHeatingSource::updateSigma
|
||||
(
|
||||
const autoPtr<Function1<Type>>& sigmaFunctionPtr
|
||||
const autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||
) const
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
||||
|
||||
const word sigmaName
|
||||
auto& sigma = mesh_.lookupObjectRef<FieldType>
|
||||
(
|
||||
IOobject::scopedName(typeName, "sigma")
|
||||
);
|
||||
|
||||
auto& sigma = mesh_.lookupObjectRef<FieldType>(sigmaName);
|
||||
|
||||
if (!sigmaFunctionPtr)
|
||||
if (!sigmaVsTPtr)
|
||||
{
|
||||
// Electrical conductivity field, sigma, was specified by the user
|
||||
return sigma;
|
||||
}
|
||||
|
||||
const auto& sigmaFunction = sigmaFunctionPtr();
|
||||
|
||||
const auto& T = mesh_.lookupObject<volScalarField>(TName_);
|
||||
|
||||
// Internal field
|
||||
forAll(sigma, i)
|
||||
{
|
||||
sigma[i] = sigmaFunction.value(T[i]);
|
||||
sigma[i] = sigmaVsTPtr->value(T[i]);
|
||||
}
|
||||
|
||||
|
||||
@ -131,7 +120,7 @@ Foam::fv::jouleHeatingSource::updateSigma
|
||||
const scalarField& Tbf = T.boundaryField()[patchi];
|
||||
forAll(pf, facei)
|
||||
{
|
||||
pf[facei] = sigmaFunction.value(Tbf[facei]);
|
||||
pf[facei] = sigmaVsTPtr->value(Tbf[facei]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,7 +480,6 @@ void Foam::faMeshReconstructor::createMesh()
|
||||
(
|
||||
new faMesh
|
||||
(
|
||||
procMesh_.name(),
|
||||
*serialVolMesh_,
|
||||
identity(singlePatchFaces_.size()) // faceLabels
|
||||
)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -144,23 +144,11 @@ KirchhoffShell::KirchhoffShell
|
||||
)
|
||||
:
|
||||
vibrationShellModel(modelType, mesh, dict),
|
||||
h_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
dict.getOrDefault<word>("h", suffixed("hs")),
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
regionMesh()
|
||||
),
|
||||
ps_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
dict.getOrDefault<word>("ps", suffixed("ps")),
|
||||
"ps_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
@ -169,11 +157,23 @@ KirchhoffShell::KirchhoffShell
|
||||
regionMesh(),
|
||||
dimensionedScalar(dimPressure, Zero)
|
||||
),
|
||||
h_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"h_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
regionMesh()
|
||||
),
|
||||
laplaceW_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed("laplaceW"),
|
||||
"laplaceW_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -186,7 +186,7 @@ KirchhoffShell::KirchhoffShell
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed("laplace2W"),
|
||||
"laplace2W_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -199,7 +199,7 @@ KirchhoffShell::KirchhoffShell
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed("w0"),
|
||||
"w0_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -212,7 +212,7 @@ KirchhoffShell::KirchhoffShell
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed("w00"),
|
||||
"w00_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -225,7 +225,7 @@ KirchhoffShell::KirchhoffShell
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed("laplaceW0"),
|
||||
"laplaceW0_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -238,7 +238,7 @@ KirchhoffShell::KirchhoffShell
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
suffixed("laplace2W0"),
|
||||
"laplace2W0_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
@ -256,7 +256,6 @@ KirchhoffShell::KirchhoffShell
|
||||
init(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
void KirchhoffShell::preEvolveRegion()
|
||||
|
||||
@ -24,7 +24,7 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::regionModels::KirchhoffShell (Foam::regionFaModels)
|
||||
Foam::regionFaModels::KirchhoffShell
|
||||
|
||||
Description
|
||||
Vibration-shell finite-area model.
|
||||
@ -51,25 +51,9 @@ Usage
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
vibrationShellModel | Type name: KirchhoffShell | word | yes | -
|
||||
f0 | Damping coefficient [1/s] | scalar | yes | -
|
||||
f1 | Damping coefficient [1/s] | scalar | yes | -
|
||||
f2 | Damping coefficient [1/s] | scalar | yes | -
|
||||
h | Name of thickness field | word | no | hs (suffix)
|
||||
ps | Name of pressure field | word | no | ps (suffix)
|
||||
\endtable
|
||||
|
||||
Fields/variables used:
|
||||
\table
|
||||
Property | Description | Type | Deflt
|
||||
h | Thickness | shell | hs (suffix)
|
||||
ps | Pressure on shell | shell | ps (suffix)
|
||||
\endtable
|
||||
|
||||
Naming changes from 2056 and earlier:
|
||||
\table
|
||||
Keyword | Description | Keyword (old) | Deflt (old)
|
||||
h | Thickness (shell) | - | "h_" + regionName
|
||||
ps | Pressure (shell) | - | "ps_" + regionName
|
||||
f0 | Damping coefficient [1/s] | scalar | yes | -
|
||||
f1 | Damping coefficient [1/s] | scalar | yes | -
|
||||
f2 | Damping coefficient [1/s] | scalar | yes | -
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
@ -106,12 +90,12 @@ class KirchhoffShell
|
||||
|
||||
// Source term fields
|
||||
|
||||
//- Shell thickness [m]
|
||||
areaScalarField h_;
|
||||
|
||||
//- External surface source [Pa]
|
||||
const areaScalarField ps_;
|
||||
|
||||
//- Thickness [m]
|
||||
areaScalarField h_;
|
||||
|
||||
//- Laplace of the displacement
|
||||
areaScalarField laplaceW_;
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ License
|
||||
|
||||
#include "regionFaModel.H"
|
||||
#include "faMesh.H"
|
||||
#include "faMeshesRegistry.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -73,7 +74,7 @@ Foam::IOobject createModelIOobject
|
||||
(
|
||||
objName,
|
||||
mesh.time().constant(),
|
||||
faMesh::Registry(mesh),
|
||||
faMeshesRegistry::New(mesh).thisDb(),
|
||||
IOobjectOption::NO_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::REGISTER
|
||||
@ -140,71 +141,12 @@ Foam::IOobject createPropertiesIOobject
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::regionModels::regionFaModel::constructMeshObjects
|
||||
(
|
||||
// Just for error reference
|
||||
const dictionary& dict
|
||||
)
|
||||
void Foam::regionModels::regionFaModel::constructMeshObjects()
|
||||
{
|
||||
regionMeshPtr_.reset(nullptr);
|
||||
|
||||
#if 1
|
||||
regionMeshPtr_.reset
|
||||
(
|
||||
new faMesh(areaName_, primaryMesh_)
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
// With try/catch and error messages
|
||||
|
||||
// DIY
|
||||
// regionMeshPtr_ = faMesh::TryNew(areaName_, primaryMesh_);
|
||||
|
||||
// More heavy handed, but gives a better chance of locating
|
||||
// the source of the error.
|
||||
{
|
||||
const bool oldThrowingError = FatalError.throwing(true);
|
||||
const bool oldThrowingIOerr = FatalIOError.throwing(true);
|
||||
|
||||
try
|
||||
{
|
||||
regionMeshPtr_.reset
|
||||
(
|
||||
new faMesh(areaName_, primaryMesh_)
|
||||
);
|
||||
}
|
||||
catch (const Foam::error& err)
|
||||
{
|
||||
Warning << err << nl << endl;
|
||||
|
||||
// Trickery to get original message
|
||||
err.write(Warning, false);
|
||||
}
|
||||
catch (const Foam::IOerror& err)
|
||||
{
|
||||
Warning << err << nl << endl;
|
||||
|
||||
// Trickery to get original message
|
||||
err.write(Warning, false);
|
||||
}
|
||||
|
||||
FatalError.throwing(oldThrowingError);
|
||||
FatalIOError.throwing(oldThrowingIOerr);
|
||||
}
|
||||
|
||||
if (!regionMeshPtr_)
|
||||
{
|
||||
FatalError
|
||||
<< "Failed to create finite-area mesh [" << areaName_
|
||||
<< "] for model: "<< modelName_ << nl
|
||||
<< "A common cause is an incorrect or"
|
||||
" missing 'area' entry in the setup" << nl
|
||||
<< ">>>>" << nl
|
||||
<< dict.relativeName() << dict << "<<<<" << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -292,35 +234,7 @@ Foam::regionModels::regionFaModel::regionFaModel
|
||||
regionName_(dict.get<word>("region")),
|
||||
coeffs_(dict.subOrEmptyDict(modelName + "Coeffs"))
|
||||
{
|
||||
// Suffix hint for variable names
|
||||
if
|
||||
(
|
||||
coeffs_.readIfPresent("suffixing", suffixHint_)
|
||||
|| dict.readIfPresent("suffixing", suffixHint_)
|
||||
)
|
||||
{
|
||||
Switch sw = Switch::find(suffixHint_);
|
||||
|
||||
if (sw.good())
|
||||
{
|
||||
if (!sw) // No suffix
|
||||
{
|
||||
suffixHint_.clear();
|
||||
}
|
||||
}
|
||||
else if (suffixHint_ == "default")
|
||||
{
|
||||
// Use default suffix
|
||||
sw = true;
|
||||
}
|
||||
|
||||
if (sw) // Default suffix
|
||||
{
|
||||
suffixHint_ = '_' + regionName_;
|
||||
}
|
||||
}
|
||||
|
||||
constructMeshObjects(dict);
|
||||
constructMeshObjects();
|
||||
initialise();
|
||||
|
||||
if (readFields)
|
||||
@ -336,14 +250,9 @@ void Foam::regionModels::regionFaModel::evolve()
|
||||
{
|
||||
if (active_)
|
||||
{
|
||||
Info<< "\nEvolving " << modelName_
|
||||
<< " for region " << regionMesh().name();
|
||||
|
||||
if (!polyMesh::regionName(areaName_).empty())
|
||||
{
|
||||
Info<< " [" << areaName_ << "]";
|
||||
}
|
||||
Info<< endl;
|
||||
Info<< "\nEvolving " << modelName_ << " for region "
|
||||
<< regionMesh().name() << " : "
|
||||
<< polyMesh::regionName(areaName_) << endl;
|
||||
|
||||
preEvolveRegion();
|
||||
|
||||
@ -356,7 +265,7 @@ void Foam::regionModels::regionFaModel::evolve()
|
||||
{
|
||||
Info<< incrIndent;
|
||||
info();
|
||||
Info<< decrIndent << endl;
|
||||
Info<< endl << decrIndent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,20 +57,9 @@ Usage
|
||||
region | Name of operand region | word | yes | -
|
||||
area | Name of the finite-area mesh | word | no | region0
|
||||
active | Flag to activate the model | bool | yes | -
|
||||
suffixing | Suffix hint for model variables | word | no | -
|
||||
infoOutput | Flag to activate information output | bool | no | false
|
||||
\endtable
|
||||
|
||||
Note
|
||||
The \c suffixing parameter is a hint that individual models may use
|
||||
when automatically generating variable names internally. For example,
|
||||
a model \em may provide ("T" + suffixing) and ("q" + suffixing)
|
||||
as its default names temperature and flux fields, respectively.
|
||||
If the user specifies \c suffixing = "_foo", those \em default names
|
||||
would then become "T_foo" and "q_foo", respectively.
|
||||
Suffixing (true|false|none|default|...) currently selects between
|
||||
no suffix and ('_'+region).
|
||||
|
||||
SourceFiles
|
||||
regionFaModelI.H
|
||||
regionFaModel.C
|
||||
@ -101,7 +90,7 @@ class regionFaModel
|
||||
// Private Member Functions
|
||||
|
||||
//- Construct region mesh and fields
|
||||
void constructMeshObjects(const dictionary&);
|
||||
void constructMeshObjects();
|
||||
|
||||
//- Initialise the region
|
||||
void initialise();
|
||||
@ -129,21 +118,18 @@ protected:
|
||||
//- Model name
|
||||
const word modelName_;
|
||||
|
||||
//- Suffix hint for automatic model variable names (default: "")
|
||||
word suffixHint_;
|
||||
|
||||
//- The finite-area mesh name (default: region0)
|
||||
//- The finite-area mesh name
|
||||
word areaName_;
|
||||
|
||||
//- Region name
|
||||
word regionName_;
|
||||
|
||||
//- Model coefficients dictionary
|
||||
dictionary coeffs_;
|
||||
|
||||
//- Pointer to the region mesh database
|
||||
autoPtr<faMesh> regionMeshPtr_;
|
||||
|
||||
//- Model coefficients dictionary
|
||||
dictionary coeffs_;
|
||||
|
||||
//- Dictionary of output properties
|
||||
autoPtr<IOdictionary> outputPropertiesPtr_;
|
||||
|
||||
@ -238,15 +224,6 @@ public:
|
||||
//- Return mapping between surface and volume fields
|
||||
const volSurfaceMapping& vsm() const;
|
||||
|
||||
//- The suffix hint for automatic model variable names
|
||||
const word& suffixHint() const noexcept { return suffixHint_; }
|
||||
|
||||
//- Return the concatenation of \p base and the suffix hint
|
||||
inline word suffixed(const char* base) const;
|
||||
|
||||
//- Return the concatenation of \p base and the suffix hint
|
||||
inline word suffixed(const std::string& base) const;
|
||||
|
||||
|
||||
// Evolution
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ License
|
||||
|
||||
#include "regionFaModel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::faMesh& Foam::regionModels::regionFaModel::regionMesh() const
|
||||
{
|
||||
@ -106,18 +106,4 @@ inline bool Foam::regionModels::regionFaModel::isRegionPatch
|
||||
}
|
||||
|
||||
|
||||
inline Foam::word
|
||||
Foam::regionModels::regionFaModel::suffixed(const char* base) const
|
||||
{
|
||||
return word(base + suffixHint_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::word
|
||||
Foam::regionModels::regionFaModel::suffixed(const std::string& base) const
|
||||
{
|
||||
return word(base + suffixHint_);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -123,29 +123,14 @@ thermalShell::thermalShell
|
||||
)
|
||||
:
|
||||
thermalShellModel(modelType, mesh, dict),
|
||||
hName_(dict.getOrDefault<word>("h", suffixed("hs"))),
|
||||
qsName_(dict.getOrDefault<word>("qs", suffixed("qs"))),
|
||||
qrName_(dict.getOrDefault<word>("qr", "none")),
|
||||
nNonOrthCorr_(1),
|
||||
// Only need/want thermal solid properties
|
||||
thermo_(dict.subDict("thermo"), solidProperties::THERMAL),
|
||||
h_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
hName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
regionMesh()
|
||||
),
|
||||
qs_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
qsName_,
|
||||
"qs_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
@ -154,6 +139,19 @@ thermalShell::thermalShell
|
||||
regionMesh(),
|
||||
dimensionedScalar(dimPower/dimArea, Zero)
|
||||
),
|
||||
h_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"h_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
regionMesh()
|
||||
),
|
||||
qrName_(dict.getOrDefault<word>("qr", "none")),
|
||||
thickness_(dict.getOrDefault<scalar>("thickness", 0))
|
||||
{
|
||||
init(dict);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -56,28 +56,11 @@ Usage
|
||||
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
thermalShellModel | Type name: thermalShell | word | yes | -
|
||||
h | Name of thickness field | word | no | hs (suffix)
|
||||
qs | Name of source field | word | no | qs (suffix)
|
||||
qr | Name of radiative heat flux field | word | no | none
|
||||
thermo | Solid thermal properties | dict | yes | -
|
||||
thickness | Uniform shell thickness [m] | scalar | choice | -
|
||||
\endtable
|
||||
|
||||
Fields/variables used:
|
||||
\table
|
||||
Property | Description | Type | Deflt
|
||||
h | Thickness | shell | hs (suffix)
|
||||
qs | Source field | shell | qs (suffix)
|
||||
qr | Radiative heat flux field | volume | none
|
||||
\endtable
|
||||
|
||||
Note the following naming changes from 2056 and earlier:
|
||||
\table
|
||||
Keyword | Description | Keyword (old) | Deflt (old)
|
||||
h | Temperature (volume) | h | "h_" + regionName
|
||||
qs | Temperature (shell) | qs | "qs_" + regionName
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
thermalShellModel | Type name: thermalShell | word | yes | -
|
||||
thermo | Solid thermal properties | dictionary | yes | -
|
||||
qr | Name of radiative heat flux field | word | no | none
|
||||
thickness | Uniform film thickness [m] | scalar | choice | -
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
@ -85,6 +68,7 @@ Usage
|
||||
|
||||
SourceFiles
|
||||
thermalShell.C
|
||||
thermalShellI.H
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -124,38 +108,31 @@ protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Name of shell thickness [height] field (default: "hs" + suffix)
|
||||
const word hName_;
|
||||
// Solution parameters
|
||||
|
||||
//- Name of surface energy source (default: "qs" + suffix)
|
||||
const word qsName_;
|
||||
|
||||
//- Name of (volume) radiative flux field (default: none)
|
||||
const word qrName_;
|
||||
//- Number of non orthogonal correctors
|
||||
label nNonOrthCorr_;
|
||||
|
||||
|
||||
// Solution Parameters
|
||||
// Thermo properties
|
||||
|
||||
//- Number of non orthogonal correctors
|
||||
label nNonOrthCorr_;
|
||||
//- Solid properties
|
||||
solidProperties thermo_;
|
||||
|
||||
|
||||
// Thermo properties
|
||||
// Source term fields
|
||||
|
||||
//- Solid properties
|
||||
solidProperties thermo_;
|
||||
//- External surface energy source [J/m2/s]
|
||||
areaScalarField qs_;
|
||||
|
||||
//- Film thickness [m]
|
||||
areaScalarField h_;
|
||||
|
||||
// Source term fields
|
||||
//- Name of the primary region radiative flux
|
||||
const word qrName_;
|
||||
|
||||
//- Shell thickness field [m]
|
||||
areaScalarField h_;
|
||||
|
||||
//- External surface energy source [J/m2/s]
|
||||
areaScalarField qs_;
|
||||
|
||||
//- Uniform shell thickness [m]
|
||||
scalar thickness_;
|
||||
//- Uniform film thickness [m]
|
||||
scalar thickness_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
@ -197,7 +174,7 @@ public:
|
||||
|
||||
// Fields
|
||||
|
||||
//- Return the shell specific heat capacity [J/kg/K]
|
||||
//- Return the film specific heat capacity [J/kg/K]
|
||||
const tmp<areaScalarField> Cp() const;
|
||||
|
||||
//- Return density [kg/m3]
|
||||
|
||||
@ -50,14 +50,13 @@ thermalShellModel::thermalShellModel
|
||||
)
|
||||
:
|
||||
regionFaModel(mesh, "thermalShell", modelType, dict, true),
|
||||
TName_(dict.getOrDefault<word>("T", suffixed("Ts"))),
|
||||
TprimaryName_(dict.getOrDefault<word>("Tprimary", "T")),
|
||||
Tp_(mesh.lookupObject<volScalarField>(TprimaryName_)),
|
||||
TName_(dict.get<word>("T")),
|
||||
Tp_(mesh.lookupObject<volScalarField>(TName_)),
|
||||
T_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
TName_,
|
||||
"Ts_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
@ -72,8 +71,8 @@ thermalShellModel::thermalShellModel
|
||||
{
|
||||
if (faOptions_.optionList::empty())
|
||||
{
|
||||
Info<< "No finite-area options present for area:"
|
||||
<< regionFaModel::areaName() << endl;
|
||||
Info<< "No finite area options present for area : "
|
||||
<< polyMesh::regionName(regionFaModel::areaName()) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::regionModels::thermalShellModel
|
||||
Foam::regionModels::thermalShellModels::thermalShellModel
|
||||
|
||||
Description
|
||||
Intermediate class for thermal-shell finite-area models.
|
||||
@ -34,12 +34,12 @@ Usage
|
||||
\verbatim
|
||||
<patchName>
|
||||
{
|
||||
// Mandatory entries
|
||||
T <word>;
|
||||
|
||||
// Optional entries
|
||||
thermalShellModel <word>;
|
||||
|
||||
T <word>;
|
||||
Tprimary <word>;
|
||||
|
||||
// Inherited entries
|
||||
...
|
||||
}
|
||||
@ -47,27 +47,12 @@ Usage
|
||||
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
T | Name of operand temperature field | word | no | Ts (suffix)
|
||||
Tprimary | Name of primary temperature field | word | no | T
|
||||
thermalShellModel | Name of thermalShellModel thermal-shell model <!--
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
T | Name of operand temperature field | word | yes | -
|
||||
thermalShellModel | Name of thermal-shell model <!--
|
||||
--> | word | choice | -
|
||||
\endtable
|
||||
|
||||
Fields/variables used:
|
||||
\table
|
||||
Property | Description | Type | Deflt
|
||||
T | Temperature | shell | Ts (suffix)
|
||||
Tprimary | Temperature | volume | T
|
||||
\endtable
|
||||
|
||||
\b BREAKING Naming changes from 2056 and earlier:
|
||||
\table
|
||||
Keyword | Description | Keyword (old) | Deflt (old)
|
||||
T | Temperature (shell) | - | "Ts_" + regionName
|
||||
Tprimary | Temperature (volume) | T | -
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link regionFaModel.H \endlink
|
||||
|
||||
@ -104,11 +89,8 @@ protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Name of shell temperature field (default: "Ts" + suffix)
|
||||
const word TName_;
|
||||
|
||||
//- Name of volume temperature field (default: "T")
|
||||
const word TprimaryName_;
|
||||
//- Name of the temperature field
|
||||
word TName_;
|
||||
|
||||
//- Primary (volume) region temperature
|
||||
const volScalarField& Tp_;
|
||||
|
||||
@ -53,7 +53,7 @@ vibrationShellModel::vibrationShellModel
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
dict.getOrDefault<word>("ws", suffixed("ws")),
|
||||
"ws_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
@ -65,7 +65,7 @@ vibrationShellModel::vibrationShellModel
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
dict.getOrDefault<word>("as", suffixed("as")),
|
||||
"as_" + regionName_,
|
||||
regionMesh().time().timeName(),
|
||||
regionMesh().thisDb(),
|
||||
IOobject::NO_READ,
|
||||
|
||||
@ -24,7 +24,7 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::regionModels::vibrationShellModel
|
||||
Foam::regionModels::thermalShellModels::vibrationShellModel
|
||||
|
||||
Description
|
||||
Intermediate class for vibration-shell finite-area models.
|
||||
@ -52,19 +52,9 @@ Usage
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
vibrationShellModel | Name of vibration-shell model | word | yes | -
|
||||
p | Name of primary pressure field | word | yes | -
|
||||
solid | Solid properties | dict | yes | -
|
||||
as | Name of shell acceleration field | word | no | as (suffix)
|
||||
ps | Name of pressure (source) on shell | word | no | ps (suffix)
|
||||
ws | Name of shell displacement field | word | no | ws (suffix)
|
||||
\endtable
|
||||
|
||||
Naming changes from 2056 and earlier:
|
||||
\table
|
||||
Keyword | Description | Keyword (old) | Deflt (old)
|
||||
as | Acceleration (shell) | - | "as_" + regionName
|
||||
ps | Pressure on shell | - | "ps_" + regionName
|
||||
ws | Displacement (shell) | - | "ws_" + regionName
|
||||
p | Name of the coupled field in the primary <!--
|
||||
--> region | word | yes | -
|
||||
solid | Solid properties | dictionary | yes | -
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
@ -103,19 +93,19 @@ protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Shell displacement [m]
|
||||
//- Shell displacement
|
||||
areaScalarField w_;
|
||||
|
||||
//- Shell acceleration [m/s2]
|
||||
//- Shell acceleration
|
||||
areaScalarField a_;
|
||||
|
||||
//- Solid properties
|
||||
solidProperties solid_;
|
||||
|
||||
//- Name of primary region acoustic pressure field
|
||||
//- Name of the coupled field in the primary region
|
||||
word pName_;
|
||||
|
||||
//- Primary region acoustic pressure [Pa]
|
||||
//- Primary region acoustic pressure
|
||||
const volScalarField& pa_;
|
||||
|
||||
//- Reference to faOptions
|
||||
@ -177,26 +167,26 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the primary region presssure
|
||||
const volScalarField& pa() const noexcept { return pa_; }
|
||||
//- Return primary region pa
|
||||
const volScalarField& pa() const noexcept { return pa_; }
|
||||
|
||||
//- Return the shell displacement
|
||||
const areaScalarField& w() const noexcept { return w_; }
|
||||
//- Return shell displacement
|
||||
const areaScalarField& w() const noexcept { return w_; }
|
||||
|
||||
//- Return the shell acceleration
|
||||
const areaScalarField& a() const noexcept { return a_; }
|
||||
//- Return shell acceleration
|
||||
const areaScalarField& a() const noexcept { return a_; }
|
||||
|
||||
//- Return faOptions
|
||||
Foam::fa::options& faOptions() noexcept { return faOptions_; }
|
||||
//- Return faOptions
|
||||
Foam::fa::options& faOptions() noexcept { return faOptions_; }
|
||||
|
||||
//- Return solid properties
|
||||
const solidProperties& solid() const noexcept { return solid_; }
|
||||
//- Return solid properties
|
||||
const solidProperties& solid() const noexcept { return solid_; }
|
||||
|
||||
|
||||
// Evolution
|
||||
|
||||
//- Pre-evolve region
|
||||
virtual void preEvolveRegion();
|
||||
//- Pre-evolve region
|
||||
virtual void preEvolveRegion();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
probes/probers/prober.C
|
||||
probes/probers/internalProber/internalProber.C
|
||||
probes/probers/patchProber/patchProber.C
|
||||
probes/probes.C
|
||||
probes/patchProbes.C
|
||||
|
||||
|
||||
453
src/sampling/probes/Probes/Probes.C
Normal file
453
src/sampling/probes/Probes/Probes.C
Normal file
@ -0,0 +1,453 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2025 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 "Probes.H"
|
||||
#include "IOmanip.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "SpanStream.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Prober>
|
||||
void Foam::Probes<Prober>::createProbeFiles(const wordList& fieldNames)
|
||||
{
|
||||
// Open new output streams
|
||||
|
||||
bool needsNewFiles = false;
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
if (!probeFilePtrs_.found(fieldName))
|
||||
{
|
||||
needsNewFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsNewFiles && Pstream::master())
|
||||
{
|
||||
DebugInfo
|
||||
<< "Probing fields: " << fieldNames << nl
|
||||
<< "Probing locations: " << prober_.probeLocations() << nl
|
||||
<< endl;
|
||||
|
||||
// Put in undecomposed case
|
||||
// (Note: gives problems for distributed data running)
|
||||
|
||||
fileName probeDir
|
||||
(
|
||||
mesh_.time().globalPath()
|
||||
/ functionObject::outputPrefix
|
||||
/ name()/mesh_.regionName()
|
||||
// Use startTime as the instance for output files
|
||||
/ mesh_.time().timeName(mesh_.time().startTime().value())
|
||||
);
|
||||
probeDir.clean(); // Remove unneeded ".."
|
||||
|
||||
// Create directory if needed
|
||||
Foam::mkDir(probeDir);
|
||||
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
if (probeFilePtrs_.found(fieldName))
|
||||
{
|
||||
// Safety
|
||||
continue;
|
||||
}
|
||||
|
||||
auto osPtr = autoPtr<OFstream>::New(probeDir/fieldName);
|
||||
auto& os = *osPtr;
|
||||
|
||||
if (!os.good())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot open probe output file: " << os.name() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
probeFilePtrs_.insert(fieldName, osPtr);
|
||||
|
||||
DebugInfo<< "open probe stream: " << os.name() << endl;
|
||||
|
||||
const unsigned int width(IOstream::defaultPrecision() + 7);
|
||||
os.setf(std::ios_base::left);
|
||||
|
||||
const pointField& probeLocs = prober_.probeLocations();
|
||||
const labelList& processors = prober_.processors();
|
||||
const labelList& patchIDList = prober_.patchIDList();
|
||||
const pointField& oldPoints = prober_.oldPoints();
|
||||
|
||||
forAll(probeLocs, probei)
|
||||
{
|
||||
os << "# Probe " << probei << ' ' << probeLocs[probei];
|
||||
|
||||
if (processors[probei] == -1)
|
||||
{
|
||||
os << " # Not Found";
|
||||
}
|
||||
else if (probei < patchIDList.size())
|
||||
{
|
||||
const label patchi = patchIDList[probei];
|
||||
if (patchi != -1)
|
||||
{
|
||||
const polyBoundaryMesh& bm = mesh_.boundaryMesh();
|
||||
if
|
||||
(
|
||||
patchi < bm.nNonProcessor()
|
||||
|| processors[probei] == Pstream::myProcNo()
|
||||
)
|
||||
{
|
||||
os << " at patch " << bm[patchi].name();
|
||||
}
|
||||
os << " with a distance of "
|
||||
<< mag(probeLocs[probei]-oldPoints[probei])
|
||||
<< " m to the original point "
|
||||
<< oldPoints[probei];
|
||||
}
|
||||
}
|
||||
|
||||
os << nl;
|
||||
}
|
||||
|
||||
os << setw(width) << "# Time";
|
||||
|
||||
forAll(probeLocs, probei)
|
||||
{
|
||||
if (prober_.includeOutOfBounds() || processors[probei] != -1)
|
||||
{
|
||||
os << ' ' << setw(width) << probei;
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
template<class Type>
|
||||
void Foam::Probes<Prober>::writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values,
|
||||
const scalar timeValue
|
||||
)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
const unsigned int width(IOstream::defaultPrecision() + 7);
|
||||
OFstream& os = *probeFilePtrs_[fieldName];
|
||||
|
||||
os << setw(width) << timeValue;
|
||||
|
||||
OCharStream buf;
|
||||
|
||||
const bool includeOutOfBounds = prober_.includeOutOfBounds();
|
||||
const labelList& procs = prober_.processors();
|
||||
forAll(values, probei)
|
||||
{
|
||||
if (includeOutOfBounds || procs[probei] != -1)
|
||||
{
|
||||
buf.rewind();
|
||||
buf << values[probei];
|
||||
os << ' ' << setw(width) << buf.str().data();
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
template<class GeoField>
|
||||
void Foam::Probes<Prober>::performAction
|
||||
(
|
||||
const fieldGroup<GeoField>& fieldNames,
|
||||
unsigned request
|
||||
)
|
||||
{
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
tmp<GeoField> tfield = getOrLoadField<GeoField>(fieldName);
|
||||
|
||||
if (tfield)
|
||||
{
|
||||
const auto& field = tfield();
|
||||
const scalar timeValue = field.time().timeOutputValue();
|
||||
|
||||
Field<typename GeoField::value_type> values(prober_.sample(field));
|
||||
|
||||
this->storeResults(fieldName, values);
|
||||
if (request & ACTION_WRITE)
|
||||
{
|
||||
this->writeValues(fieldName, values, timeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Prober>
|
||||
Foam::label Foam::Probes<Prober>::prepare(unsigned request)
|
||||
{
|
||||
// Prefilter on selection
|
||||
HashTable<wordHashSet> selected =
|
||||
(
|
||||
loadFromFiles_
|
||||
? IOobjectList(mesh_, mesh_.time().timeName()).classes(fieldSelection_)
|
||||
: mesh_.classes(fieldSelection_)
|
||||
);
|
||||
|
||||
// Classify and count fields
|
||||
label nFields = 0;
|
||||
do
|
||||
{
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(InputType, Target) \
|
||||
{ \
|
||||
Target.clear(); /* Remove old values */ \
|
||||
const auto iter = selected.cfind(InputType::typeName); \
|
||||
if (iter.good()) \
|
||||
{ \
|
||||
/* Add new (current) values */ \
|
||||
Target.append(iter.val().sortedToc()); \
|
||||
nFields += Target.size(); \
|
||||
} \
|
||||
}
|
||||
|
||||
doLocalCode(volScalarField, scalarFields_);
|
||||
doLocalCode(volVectorField, vectorFields_);
|
||||
doLocalCode(volSphericalTensorField, sphericalTensorFields_);
|
||||
doLocalCode(volSymmTensorField, symmTensorFields_);
|
||||
doLocalCode(volTensorField, tensorFields_);
|
||||
|
||||
doLocalCode(surfaceScalarField, surfaceScalarFields_);
|
||||
doLocalCode(surfaceVectorField, surfaceVectorFields_);
|
||||
doLocalCode(surfaceSphericalTensorField, surfaceSphericalTensorFields_);
|
||||
doLocalCode(surfaceSymmTensorField, surfaceSymmTensorFields_);
|
||||
doLocalCode(surfaceTensorField, surfaceTensorFields_);
|
||||
#undef doLocalCode
|
||||
}
|
||||
while (false);
|
||||
|
||||
|
||||
// Adjust file streams
|
||||
if (Pstream::master())
|
||||
{
|
||||
wordHashSet currentFields(2*nFields);
|
||||
currentFields.insert(scalarFields_);
|
||||
currentFields.insert(vectorFields_);
|
||||
currentFields.insert(sphericalTensorFields_);
|
||||
currentFields.insert(symmTensorFields_);
|
||||
currentFields.insert(tensorFields_);
|
||||
|
||||
currentFields.insert(surfaceScalarFields_);
|
||||
currentFields.insert(surfaceVectorFields_);
|
||||
currentFields.insert(surfaceSphericalTensorFields_);
|
||||
currentFields.insert(surfaceSymmTensorFields_);
|
||||
currentFields.insert(surfaceTensorFields_);
|
||||
|
||||
DebugInfo
|
||||
<< "Probing fields: " << currentFields << nl
|
||||
<< "Probing locations: " << prober_.probeLocations() << nl
|
||||
<< endl;
|
||||
|
||||
// Close streams for fields that no longer exist
|
||||
forAllIters(probeFilePtrs_, iter)
|
||||
{
|
||||
if (!currentFields.erase(iter.key()))
|
||||
{
|
||||
DebugInfo<< "close probe stream: " << iter()->name() << endl;
|
||||
|
||||
probeFilePtrs_.remove(iter);
|
||||
}
|
||||
}
|
||||
|
||||
if ((request & ACTION_WRITE) && !currentFields.empty())
|
||||
{
|
||||
createProbeFiles(currentFields.sortedToc());
|
||||
}
|
||||
}
|
||||
|
||||
return nFields;
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::Probes<Prober>::getOrLoadField(const word& fieldName) const
|
||||
{
|
||||
tmp<GeoField> tfield;
|
||||
|
||||
if (loadFromFiles_)
|
||||
{
|
||||
tfield.emplace
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
mesh_.time().timeName(),
|
||||
mesh_.thisDb(),
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
),
|
||||
mesh_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
tfield.cref(mesh_.cfindObject<GeoField>(fieldName));
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
template<class Type>
|
||||
void Foam::Probes<Prober>::storeResults
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values
|
||||
)
|
||||
{
|
||||
const MinMax<Type> limits(values);
|
||||
const Type avgVal = average(values);
|
||||
|
||||
this->setResult("average(" + fieldName + ")", avgVal);
|
||||
this->setResult("min(" + fieldName + ")", limits.min());
|
||||
this->setResult("max(" + fieldName + ")", limits.max());
|
||||
this->setResult("size(" + fieldName + ")", values.size());
|
||||
|
||||
if (verbose_)
|
||||
{
|
||||
Info<< name() << " : " << fieldName << nl
|
||||
<< " avg: " << avgVal << nl
|
||||
<< " min: " << limits.min() << nl
|
||||
<< " max: " << limits.max() << nl << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Prober>
|
||||
Foam::Probes<Prober>::Probes
|
||||
(
|
||||
const word& name,
|
||||
const Time& runTime,
|
||||
const dictionary& dict,
|
||||
const bool loadFromFiles,
|
||||
const bool readFields
|
||||
)
|
||||
:
|
||||
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||
prober_(mesh_, dict),
|
||||
loadFromFiles_(loadFromFiles),
|
||||
onExecute_(false),
|
||||
fieldSelection_()
|
||||
{
|
||||
if (readFields)
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Prober>
|
||||
bool Foam::Probes<Prober>::verbose(const bool on) noexcept
|
||||
{
|
||||
bool old(verbose_);
|
||||
verbose_ = on;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
bool Foam::Probes<Prober>::read(const dictionary& dict)
|
||||
{
|
||||
dict.readEntry("fields", fieldSelection_);
|
||||
|
||||
verbose_ = dict.getOrDefault("verbose", false);
|
||||
onExecute_ = dict.getOrDefault("sampleOnExecute", false);
|
||||
|
||||
// Close old (unused) streams
|
||||
prepare(ACTION_NONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
bool Foam::Probes<Prober>::performAction(unsigned request)
|
||||
{
|
||||
if (!prober_.empty() && request && prepare(request))
|
||||
{
|
||||
performAction(scalarFields_, request);
|
||||
performAction(vectorFields_, request);
|
||||
performAction(sphericalTensorFields_, request);
|
||||
performAction(symmTensorFields_, request);
|
||||
performAction(tensorFields_, request);
|
||||
|
||||
performAction(surfaceScalarFields_, request);
|
||||
performAction(surfaceVectorFields_, request);
|
||||
performAction(surfaceSphericalTensorFields_, request);
|
||||
performAction(surfaceSymmTensorFields_, request);
|
||||
performAction(surfaceTensorFields_, request);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
bool Foam::Probes<Prober>::execute()
|
||||
{
|
||||
if (onExecute_)
|
||||
{
|
||||
return performAction(ACTION_ALL & ~ACTION_WRITE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class Prober>
|
||||
bool Foam::Probes<Prober>::write()
|
||||
{
|
||||
return performAction(ACTION_ALL);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
238
src/sampling/probes/Probes/Probes.H
Normal file
238
src/sampling/probes/Probes/Probes.H
Normal file
@ -0,0 +1,238 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2025 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::Probes
|
||||
|
||||
Description
|
||||
Base class for sampling fields at specified locations and writing to file.
|
||||
The locations are specified and determined in the derived class. The
|
||||
sampling is done using the specified point prober class.
|
||||
|
||||
SourceFiles
|
||||
Probes.C
|
||||
ProbesTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_Probes_H
|
||||
#define Foam_Probes_H
|
||||
|
||||
#include "fvMeshFunctionObject.H"
|
||||
#include "polyMesh.H"
|
||||
#include "HashPtrTable.H"
|
||||
#include "OFstream.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "surfaceFieldsFwd.H"
|
||||
#include "prober.H"
|
||||
#include "IOobjectList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Probes Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Prober>
|
||||
class Probes
|
||||
:
|
||||
public functionObjects::fvMeshFunctionObject
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The specified point prober
|
||||
Prober prober_;
|
||||
|
||||
|
||||
// Protected Classes
|
||||
|
||||
//- Grouping of field names by GeometricField type
|
||||
template<class GeoField>
|
||||
struct fieldGroup : public DynamicList<word> {};
|
||||
|
||||
|
||||
// Data Types
|
||||
|
||||
//- Local control for sampling actions
|
||||
enum sampleActionType : unsigned
|
||||
{
|
||||
ACTION_NONE = 0,
|
||||
ACTION_WRITE = 0x1,
|
||||
ACTION_STORE = 0x2,
|
||||
ACTION_ALL = 0xF
|
||||
};
|
||||
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Load fields from files (not from objectRegistry)
|
||||
bool loadFromFiles_;
|
||||
|
||||
//- Output verbosity
|
||||
bool verbose_;
|
||||
|
||||
//- Perform sample actions on execute as well
|
||||
bool onExecute_;
|
||||
|
||||
//- Requested names of fields to probe
|
||||
wordRes fieldSelection_;
|
||||
|
||||
|
||||
// Calculated
|
||||
|
||||
//- Current list of field names selected for sampling
|
||||
DynamicList<word> selectedFieldNames_;
|
||||
|
||||
//- Categorized scalar/vector/tensor volume fields
|
||||
fieldGroup<volScalarField> scalarFields_;
|
||||
fieldGroup<volVectorField> vectorFields_;
|
||||
fieldGroup<volSphericalTensorField> sphericalTensorFields_;
|
||||
fieldGroup<volSymmTensorField> symmTensorFields_;
|
||||
fieldGroup<volTensorField> tensorFields_;
|
||||
|
||||
//- Categorized scalar/vector/tensor surface fields
|
||||
fieldGroup<surfaceScalarField> surfaceScalarFields_;
|
||||
fieldGroup<surfaceVectorField> surfaceVectorFields_;
|
||||
fieldGroup<surfaceSphericalTensorField> surfaceSphericalTensorFields_;
|
||||
fieldGroup<surfaceSymmTensorField> surfaceSymmTensorFields_;
|
||||
fieldGroup<surfaceTensorField> surfaceTensorFields_;
|
||||
|
||||
//- Current open files (non-empty on master only)
|
||||
HashPtrTable<OFstream> probeFilePtrs_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Classify field types, close/open file streams
|
||||
// \return number of fields to sample
|
||||
label prepare(unsigned request);
|
||||
|
||||
//- Get from registry or load from disk
|
||||
template<class GeoField>
|
||||
tmp<GeoField> getOrLoadField(const word& fieldName) const;
|
||||
|
||||
//- Store results: min/max/average/size
|
||||
template<class Type>
|
||||
void storeResults(const word& fieldName, const Field<Type>& values);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Create new streams as required
|
||||
void createProbeFiles(const wordList& fieldNames);
|
||||
|
||||
//- Write field values
|
||||
template<class Type>
|
||||
void writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values,
|
||||
const scalar timeValue
|
||||
);
|
||||
|
||||
//- Sample and store/write all applicable sampled fields
|
||||
template<class GeoField>
|
||||
void performAction
|
||||
(
|
||||
const fieldGroup<GeoField>& fieldNames, /* must be sorted */
|
||||
unsigned request
|
||||
);
|
||||
|
||||
//- Perform sampling action with store/write
|
||||
bool performAction(unsigned request);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Time and dictionary
|
||||
Probes
|
||||
(
|
||||
const word& name,
|
||||
const Time& runTime,
|
||||
const dictionary& dict,
|
||||
const bool loadFromFiles = false,
|
||||
const bool readFields = true
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~Probes() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Enable/disable verbose output
|
||||
// \return old value
|
||||
bool verbose(const bool on) noexcept;
|
||||
|
||||
//- Return names of fields to probe
|
||||
virtual const wordRes& fieldNames() const noexcept
|
||||
{
|
||||
return fieldSelection_;
|
||||
}
|
||||
|
||||
//- Return const reference to the point prober
|
||||
const Prober& prober() const noexcept { return prober_; }
|
||||
|
||||
//- Read the settings from the dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
//- Sample and store result if the sampleOnExecute is enabled.
|
||||
virtual bool execute();
|
||||
|
||||
//- Sample and write
|
||||
virtual bool write();
|
||||
|
||||
//- Update for changes of mesh due to readUpdate
|
||||
virtual void readUpdate(const polyMesh::readUpdateState state)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "Probes.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,11 +27,6 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "patchProbes.H"
|
||||
#include "volFields.H"
|
||||
#include "IOmanip.H"
|
||||
#include "mappedPatchBase.H"
|
||||
#include "treeBoundBox.H"
|
||||
#include "treeDataFace.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -39,7 +34,6 @@ License
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(patchProbes, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
functionObject,
|
||||
@ -48,179 +42,6 @@ namespace Foam
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::patchProbes::findElements(const fvMesh& mesh)
|
||||
{
|
||||
(void)mesh.tetBasePtIs();
|
||||
|
||||
const polyBoundaryMesh& bm = mesh.boundaryMesh();
|
||||
|
||||
// All the info for nearest. Construct to miss
|
||||
List<mappedPatchBase::nearInfo> nearest(this->size());
|
||||
|
||||
const labelList patchIDs(bm.patchSet(patchNames_).sortedToc());
|
||||
|
||||
label nFaces = 0;
|
||||
forAll(patchIDs, i)
|
||||
{
|
||||
nFaces += bm[patchIDs[i]].size();
|
||||
}
|
||||
|
||||
if (nFaces > 0)
|
||||
{
|
||||
// Collect mesh faces and bounding box
|
||||
labelList bndFaces(nFaces);
|
||||
treeBoundBox overallBb;
|
||||
|
||||
nFaces = 0;
|
||||
forAll(patchIDs, i)
|
||||
{
|
||||
const polyPatch& pp = bm[patchIDs[i]];
|
||||
forAll(pp, i)
|
||||
{
|
||||
bndFaces[nFaces++] = pp.start()+i;
|
||||
const face& f = pp[i];
|
||||
|
||||
// Without reduction.
|
||||
overallBb.add(pp.points(), f);
|
||||
}
|
||||
}
|
||||
|
||||
Random rndGen(123456);
|
||||
overallBb.inflate(rndGen, 1e-4, ROOTVSMALL);
|
||||
|
||||
|
||||
const indexedOctree<treeDataFace> boundaryTree
|
||||
(
|
||||
treeDataFace(mesh, bndFaces), // patch faces only
|
||||
|
||||
overallBb, // overall search domain
|
||||
8, // maxLevel
|
||||
10, // leafsize
|
||||
3.0 // duplicity
|
||||
);
|
||||
|
||||
forAll(probeLocations(), probei)
|
||||
{
|
||||
const auto& treeData = boundaryTree.shapes();
|
||||
const point sample = probeLocations()[probei];
|
||||
|
||||
pointIndexHit info = boundaryTree.findNearest
|
||||
(
|
||||
sample,
|
||||
Foam::sqr(boundaryTree.bb().mag())
|
||||
);
|
||||
|
||||
if (!info.hit())
|
||||
{
|
||||
info = boundaryTree.findNearest(sample, Foam::sqr(GREAT));
|
||||
}
|
||||
|
||||
const label facei = treeData.objectIndex(info.index());
|
||||
|
||||
const label patchi = bm.whichPatch(facei);
|
||||
|
||||
if (isA<emptyPolyPatch>(bm[patchi]))
|
||||
{
|
||||
WarningInFunction
|
||||
<< " The sample point: " << sample
|
||||
<< " belongs to " << patchi
|
||||
<< " which is an empty patch. This is not permitted. "
|
||||
<< " This sample will not be included "
|
||||
<< endl;
|
||||
}
|
||||
else if (info.hit())
|
||||
{
|
||||
// Note: do we store the face centre or the actual nearest?
|
||||
// We interpolate using the faceI only though (no
|
||||
// interpolation) so it does not actually matter much, just for
|
||||
// the location written to the header.
|
||||
|
||||
//const point& facePt = mesh.faceCentres()[faceI];
|
||||
const point& facePt = info.point();
|
||||
|
||||
mappedPatchBase::nearInfo sampleInfo;
|
||||
|
||||
sampleInfo.first() = pointIndexHit(true, facePt, facei);
|
||||
|
||||
sampleInfo.second().first() = facePt.distSqr(sample);
|
||||
sampleInfo.second().second() = Pstream::myProcNo();
|
||||
|
||||
nearest[probei] = sampleInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find nearest - globally consistent
|
||||
Pstream::listCombineReduce(nearest, mappedPatchBase::nearestEqOp());
|
||||
|
||||
oldPoints_.resize(this->size());
|
||||
|
||||
// Update actual probe locations and store old ones
|
||||
forAll(nearest, samplei)
|
||||
{
|
||||
oldPoints_[samplei] = operator[](samplei);
|
||||
operator[](samplei) = nearest[samplei].first().point();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << nl;
|
||||
forAll(nearest, samplei)
|
||||
{
|
||||
label proci = nearest[samplei].second().second();
|
||||
label locali = nearest[samplei].first().index();
|
||||
|
||||
Info<< " " << samplei << " coord:"<< operator[](samplei)
|
||||
<< " found on processor:" << proci
|
||||
<< " in local face:" << locali
|
||||
<< " with location:" << nearest[samplei].first().point()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract any local faces to sample:
|
||||
// - operator[] : actual point to sample (=nearest point on patch)
|
||||
// - oldPoints_ : original provided point (might be anywhere in the mesh)
|
||||
// - elementList_ : cells, not used
|
||||
// - faceList_ : faces (now patch faces)
|
||||
// - patchIDList_ : patch corresponding to faceList
|
||||
// - processor_ : processor
|
||||
elementList_.resize_nocopy(nearest.size());
|
||||
elementList_ = -1;
|
||||
|
||||
faceList_.resize_nocopy(nearest.size());
|
||||
faceList_ = -1;
|
||||
|
||||
processor_.resize_nocopy(nearest.size());
|
||||
processor_ = -1;
|
||||
|
||||
patchIDList_.resize_nocopy(nearest.size());
|
||||
patchIDList_ = -1;
|
||||
|
||||
forAll(nearest, sampleI)
|
||||
{
|
||||
processor_[sampleI] = nearest[sampleI].second().second();
|
||||
|
||||
if (nearest[sampleI].second().second() == Pstream::myProcNo())
|
||||
{
|
||||
// Store the face to sample
|
||||
faceList_[sampleI] = nearest[sampleI].first().index();
|
||||
const label facei = faceList_[sampleI];
|
||||
if (facei != -1)
|
||||
{
|
||||
processor_[sampleI] = Pstream::myProcNo();
|
||||
patchIDList_[sampleI] = bm.whichPatch(facei);
|
||||
}
|
||||
}
|
||||
reduce(processor_[sampleI], maxOp<label>());
|
||||
reduce(patchIDList_[sampleI], maxOp<label>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::patchProbes::patchProbes
|
||||
@ -232,7 +53,14 @@ Foam::patchProbes::patchProbes
|
||||
const bool readFields
|
||||
)
|
||||
:
|
||||
probes(name, runTime, dict, loadFromFiles, false)
|
||||
Base
|
||||
(
|
||||
name,
|
||||
runTime,
|
||||
dict,
|
||||
loadFromFiles,
|
||||
readFields
|
||||
)
|
||||
{
|
||||
if (readFields)
|
||||
{
|
||||
@ -243,52 +71,13 @@ Foam::patchProbes::patchProbes
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::patchProbes::performAction(unsigned request)
|
||||
{
|
||||
if (!pointField::empty() && request && prepare(request))
|
||||
{
|
||||
performAction(scalarFields_, request);
|
||||
performAction(vectorFields_, request);
|
||||
performAction(sphericalTensorFields_, request);
|
||||
performAction(symmTensorFields_, request);
|
||||
performAction(tensorFields_, request);
|
||||
|
||||
performAction(surfaceScalarFields_, request);
|
||||
performAction(surfaceVectorFields_, request);
|
||||
performAction(surfaceSphericalTensorFields_, request);
|
||||
performAction(surfaceSymmTensorFields_, request);
|
||||
performAction(surfaceTensorFields_, request);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::patchProbes::execute()
|
||||
{
|
||||
if (onExecute_)
|
||||
{
|
||||
return performAction(ACTION_ALL & ~ACTION_WRITE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::patchProbes::write()
|
||||
{
|
||||
return performAction(ACTION_ALL);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::patchProbes::read(const dictionary& dict)
|
||||
{
|
||||
if (!dict.readIfPresent("patches", patchNames_))
|
||||
if (!(Probes::read(dict) && prober_.read(dict)))
|
||||
{
|
||||
patchNames_.resize(1);
|
||||
patchNames_.first() = dict.get<word>("patch");
|
||||
return false;
|
||||
}
|
||||
|
||||
return probes::read(dict);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,52 +28,71 @@ Class
|
||||
Foam::patchProbes
|
||||
|
||||
Description
|
||||
Set of locations to sample at patches
|
||||
Probes the specified points on specified patches. The points get snapped
|
||||
onto the nearest point on the nearest face of the specified patch, and the
|
||||
sampling is actioned on the snapped locations.
|
||||
|
||||
Call write() to sample and write files.
|
||||
- find nearest location on nearest face
|
||||
- update *this with location (so header contains 'snapped' locations
|
||||
- use *this as the sampling location
|
||||
|
||||
Example of function object specification:
|
||||
Usage
|
||||
Minimal example by using \c system/controlDict.functions:
|
||||
\verbatim
|
||||
patchProbes
|
||||
{
|
||||
// Mandatory entries
|
||||
type patchProbes;
|
||||
libs (sampling);
|
||||
|
||||
// Name of the directory for probe data
|
||||
name patchProbes;
|
||||
fields (<wordRes>);
|
||||
probeLocations (<vectorList>);
|
||||
patches (<wordRes>); // or patch <word>;
|
||||
|
||||
// Patches to sample (wildcards allowed)
|
||||
patches (".*inl.*");
|
||||
// Optional entries
|
||||
verbose <bool>;
|
||||
sampleOnExecute <bool>;
|
||||
fixedLocations <bool>;
|
||||
includeOutOfBounds <bool>;
|
||||
interpolationScheme <word>;
|
||||
|
||||
// Write at same frequency as fields
|
||||
writeControl writeTime;
|
||||
writeInterval 1;
|
||||
|
||||
// Fields to be probed
|
||||
fields (p U);
|
||||
|
||||
// Locations to probe. These get snapped onto the nearest point
|
||||
// on the selected patches
|
||||
probeLocations
|
||||
(
|
||||
( -100 0 0.01 ) // at inlet
|
||||
);
|
||||
...
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
type | Type name: patchProbes | word | yes | -
|
||||
libs | Library name: sampling | word | yes | -
|
||||
fields | Names of the fields to be probed | wordRes | yes | -
|
||||
probeLocations | Locations of the probes | vectorField | yes | -
|
||||
patches | Patches to sample (wildcards allowed) | wordRes | yes | -
|
||||
verbose | Enable/disable verbose output | bool | no | false
|
||||
sampleOnExecute | Sample on execution and store results | bool | no <!--
|
||||
--> | false
|
||||
fixedLocations | Do not recalculate cells if mesh moves | bool | no | true
|
||||
includeOutOfBounds | Include out-of-bounds locations | bool | no | true
|
||||
interpolationScheme | Scheme to obtain values at the points | word <!--
|
||||
--> | no | cell
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link fvMeshFunctionObject.H \endlink
|
||||
- \link Probes.H \endlink
|
||||
- \link patchProber.H \endlink
|
||||
- \link prober.H \endlink
|
||||
|
||||
Note
|
||||
- The \c includeOutOfBounds filters out points that haven't been found.
|
||||
Default is to include them (with value \c -VGREAT).
|
||||
|
||||
SourceFiles
|
||||
patchProbes.C
|
||||
patchProbesTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_patchProbes_H
|
||||
#define Foam_patchProbes_H
|
||||
|
||||
#include "probes.H"
|
||||
#include "Probes.H"
|
||||
#include "patchProber.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -81,57 +100,17 @@ namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class patchProbes Declaration
|
||||
Class patchProbes Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class patchProbes
|
||||
:
|
||||
public probes
|
||||
public Probes<patchProber>
|
||||
{
|
||||
protected:
|
||||
// Private Data
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Patches to sample
|
||||
wordRes patchNames_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find elements containing patchProbes
|
||||
virtual void findElements(const fvMesh& mesh); // override
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Write field values
|
||||
template<class Type>
|
||||
void writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values,
|
||||
const scalar timeValue
|
||||
);
|
||||
|
||||
//- Sample and store/write applicable volume/surface fields
|
||||
template<class GeoField>
|
||||
void performAction
|
||||
(
|
||||
const fieldGroup<GeoField>& fieldNames, /* must be sorted */
|
||||
unsigned request
|
||||
);
|
||||
|
||||
//- Perform sampling action with store/write
|
||||
bool performAction(unsigned request);
|
||||
|
||||
|
||||
//- No copy construct
|
||||
patchProbes(const patchProbes&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const patchProbes&) = delete;
|
||||
//- Use simpler synonym for the base type
|
||||
using Base = Probes<patchProber>;
|
||||
|
||||
|
||||
public:
|
||||
@ -142,7 +121,7 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Time and dictionary
|
||||
//- Construct from name, Time and dictionary
|
||||
patchProbes
|
||||
(
|
||||
const word& name,
|
||||
@ -152,54 +131,26 @@ public:
|
||||
const bool readFields = true
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~patchProbes() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Sample and store result if the sampleOnExecute is enabled.
|
||||
virtual bool execute();
|
||||
//- Bring Base::prober into this class's public scope.
|
||||
using Base::prober;
|
||||
|
||||
//- Sample and write
|
||||
virtual bool write();
|
||||
|
||||
//- Read
|
||||
//- Read the settings from the dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
|
||||
// Sampling
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const VolumeField<Type>&) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const SurfaceField<Type>&) const;
|
||||
|
||||
//- Sample a single field on all sample locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const word& fieldName) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sampleSurfaceField(const word& fieldName) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "patchProbesTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
188
src/sampling/probes/probers/internalProber/internalProber.C
Normal file
188
src/sampling/probes/probers/internalProber/internalProber.C
Normal file
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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 "internalProber.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(internalProber, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::internalProber::findElements(const fvMesh& mesh)
|
||||
{
|
||||
DebugInfo<< "internalProber: resetting sample locations" << endl;
|
||||
|
||||
const pointField& probeLocations = this->probeLocations();
|
||||
|
||||
cellIds_.resize_nocopy(probeLocations.size());
|
||||
faceIds_.resize_nocopy(probeLocations.size());
|
||||
procIds_.resize_nocopy(probeLocations.size());
|
||||
procIds_ = -1;
|
||||
|
||||
forAll(probeLocations, probei)
|
||||
{
|
||||
const point& location = probeLocations[probei];
|
||||
|
||||
const label celli = mesh.findCell(location);
|
||||
|
||||
cellIds_[probei] = celli;
|
||||
|
||||
if (celli != -1)
|
||||
{
|
||||
const labelList& cellFaces = mesh.cells()[celli];
|
||||
const vector& cellCentre = mesh.cellCentres()[celli];
|
||||
scalar minDistance = GREAT;
|
||||
label minFaceID = -1;
|
||||
forAll(cellFaces, i)
|
||||
{
|
||||
label facei = cellFaces[i];
|
||||
vector dist = mesh.faceCentres()[facei] - cellCentre;
|
||||
if (mag(dist) < minDistance)
|
||||
{
|
||||
minDistance = mag(dist);
|
||||
minFaceID = facei;
|
||||
}
|
||||
}
|
||||
faceIds_[probei] = minFaceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
faceIds_[probei] = -1;
|
||||
}
|
||||
|
||||
if (debug && (cellIds_[probei] != -1 || faceIds_[probei] != -1))
|
||||
{
|
||||
Pout<< "internalProber : found point " << location
|
||||
<< " in cell " << cellIds_[probei]
|
||||
<< " and face " << faceIds_[probei] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if all probes have been found.
|
||||
forAll(cellIds_, probei)
|
||||
{
|
||||
const point& location = probeLocations[probei];
|
||||
label celli = cellIds_[probei];
|
||||
label facei = faceIds_[probei];
|
||||
|
||||
procIds_[probei] = (celli != -1 ? Pstream::myProcNo() : -1);
|
||||
|
||||
// Check at least one processor with cell.
|
||||
reduce(celli, maxOp<label>());
|
||||
reduce(facei, maxOp<label>());
|
||||
reduce(procIds_[probei], maxOp<label>());
|
||||
|
||||
if (celli == -1)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Did not find location " << location
|
||||
<< " in any cell. Skipping location." << endl;
|
||||
}
|
||||
}
|
||||
else if (facei == -1)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Did not find location " << location
|
||||
<< " in any face. Skipping location." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure location not on two domains.
|
||||
if (cellIds_[probei] != -1 && cellIds_[probei] != celli)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Location " << location
|
||||
<< " seems to be on multiple domains:"
|
||||
<< " cell " << cellIds_[probei]
|
||||
<< " on my domain " << Pstream::myProcNo()
|
||||
<< " and cell " << celli << " on some other domain."
|
||||
<< nl
|
||||
<< "This might happen if the probe location is on"
|
||||
<< " a processor patch. Change the location slightly"
|
||||
<< " to prevent this." << endl;
|
||||
}
|
||||
|
||||
if (faceIds_[probei] != -1 && faceIds_[probei] != facei)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Location " << location
|
||||
<< " seems to be on multiple domains:"
|
||||
<< " cell " << faceIds_[probei]
|
||||
<< " on my domain " << Pstream::myProcNo()
|
||||
<< " and face " << facei << " on some other domain."
|
||||
<< nl
|
||||
<< "This might happen if the probe location is on"
|
||||
<< " a processor patch. Change the location slightly"
|
||||
<< " to prevent this." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::internalProber::internalProber
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
prober(mesh, dict)
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::internalProber::read(const dictionary& dict)
|
||||
{
|
||||
if (!prober::read(dict))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialise cells to sample from supplied locations
|
||||
findElements(mesh_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
140
src/sampling/probes/probers/internalProber/internalProber.H
Normal file
140
src/sampling/probes/probers/internalProber/internalProber.H
Normal file
@ -0,0 +1,140 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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::internalProber
|
||||
|
||||
Description
|
||||
A utility class for probing field values at specified point locations
|
||||
within an \c fvMesh.
|
||||
|
||||
The \c internalProber stores a list of 3D point coordinates and
|
||||
determines the corresponding mesh elements (cells or faces) that contain
|
||||
these points. It provides methods to sample volume or surface fields at
|
||||
the stored locations, with support for fixed or mesh-moving point
|
||||
coordinates.
|
||||
|
||||
Features include:
|
||||
- Reading probe locations and settings from a dictionary
|
||||
- Support for fixed or moving locations (for dynamic mesh cases)
|
||||
- Optional inclusion of points that lie outside of the mesh domain
|
||||
- Selection of interpolation/sampling schemes for fixed locations
|
||||
- Sampling of volume and surface fields by name or by direct reference
|
||||
- Automatic update of element mapping when the mesh changes or moves
|
||||
|
||||
SourceFiles
|
||||
internalProber.C
|
||||
internalProberTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_internalProber_H
|
||||
#define Foam_internalProber_H
|
||||
|
||||
#include "prober.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class internalProber Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class internalProber
|
||||
:
|
||||
public prober
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find cells and faces containing probes
|
||||
virtual void findElements(const fvMesh& mesh);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("internalProber");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Time and dictionary
|
||||
internalProber
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~internalProber() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Sampling
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const VolumeField<Type>&) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const SurfaceField<Type>&) const;
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const word& fieldName) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sampleSurfaceField(const word& fieldName) const;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Read the settings dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "internalProberTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,122 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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 "internalProber.H"
|
||||
#include "interpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::internalProber::sample(const VolumeField<Type>& vField) const
|
||||
{
|
||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||
|
||||
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||
auto& values = tvalues.ref();
|
||||
|
||||
if (fixedLocations_)
|
||||
{
|
||||
autoPtr<interpolation<Type>> interpPtr
|
||||
(
|
||||
interpolation<Type>::New(samplePointScheme_, vField)
|
||||
);
|
||||
|
||||
const pointField& probeLocations = this->probeLocations();
|
||||
forAll(probeLocations, probei)
|
||||
{
|
||||
if (cellIds_[probei] >= 0)
|
||||
{
|
||||
const vector& position = probeLocations[probei];
|
||||
|
||||
values[probei] = interpPtr().interpolate
|
||||
(
|
||||
position,
|
||||
cellIds_[probei],
|
||||
-1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(*this, probei)
|
||||
{
|
||||
if (cellIds_[probei] >= 0)
|
||||
{
|
||||
values[probei] = vField[cellIds_[probei]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pstream::listCombineReduce(values, isNotEqOp<Type>());
|
||||
|
||||
return tvalues;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::internalProber::sample(const SurfaceField<Type>& sField) const
|
||||
{
|
||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||
|
||||
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||
auto& values = tvalues.ref();
|
||||
|
||||
const pointField& probeLocations = this->probeLocations();
|
||||
forAll(probeLocations, probei)
|
||||
{
|
||||
if (faceIds_[probei] >= 0)
|
||||
{
|
||||
values[probei] = sField[faceIds_[probei]];
|
||||
}
|
||||
}
|
||||
|
||||
Pstream::listCombineReduce(values, isNotEqOp<Type>());
|
||||
|
||||
return tvalues;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::internalProber::sample(const word& fieldName) const
|
||||
{
|
||||
return sample(mesh_.lookupObject<VolumeField<Type>>(fieldName));
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::internalProber::sampleSurfaceField(const word& fieldName) const
|
||||
{
|
||||
return sample(mesh_.lookupObject<SurfaceField<Type>>(fieldName));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
252
src/sampling/probes/probers/patchProber/patchProber.C
Normal file
252
src/sampling/probes/probers/patchProber/patchProber.C
Normal file
@ -0,0 +1,252 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2022 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 "patchProber.H"
|
||||
#include "mappedPatchBase.H"
|
||||
#include "treeBoundBox.H"
|
||||
#include "treeDataFace.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(patchProber, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::patchProber::findElements(const fvMesh& mesh)
|
||||
{
|
||||
(void)mesh.tetBasePtIs();
|
||||
|
||||
const polyBoundaryMesh& bm = mesh.boundaryMesh();
|
||||
|
||||
// All the info for nearest. Construct to miss
|
||||
List<mappedPatchBase::nearInfo> nearest(this->size());
|
||||
|
||||
patchIDs_ = bm.patchSet(patchNames_).sortedToc();
|
||||
|
||||
label nFaces = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
nFaces += bm[patchIDs_[i]].size();
|
||||
}
|
||||
|
||||
if (nFaces > 0)
|
||||
{
|
||||
// Collect mesh faces and bounding box
|
||||
labelList bndFaces(nFaces);
|
||||
treeBoundBox overallBb;
|
||||
|
||||
nFaces = 0;
|
||||
forAll(patchIDs_, i)
|
||||
{
|
||||
const polyPatch& pp = bm[patchIDs_[i]];
|
||||
forAll(pp, i)
|
||||
{
|
||||
bndFaces[nFaces++] = pp.start()+i;
|
||||
const face& f = pp[i];
|
||||
|
||||
// Without reduction.
|
||||
overallBb.add(pp.points(), f);
|
||||
}
|
||||
}
|
||||
|
||||
Random rndGen(123456);
|
||||
overallBb.inflate(rndGen, 1e-4, ROOTVSMALL);
|
||||
|
||||
|
||||
const indexedOctree<treeDataFace> boundaryTree
|
||||
(
|
||||
treeDataFace(mesh, bndFaces), // patch faces only
|
||||
|
||||
overallBb, // overall search domain
|
||||
8, // maxLevel
|
||||
10, // leafsize
|
||||
3.0 // duplicity
|
||||
);
|
||||
|
||||
forAll(probeLocations(), probei)
|
||||
{
|
||||
const auto& treeData = boundaryTree.shapes();
|
||||
const point sample = probeLocations()[probei];
|
||||
|
||||
pointIndexHit info = boundaryTree.findNearest
|
||||
(
|
||||
sample,
|
||||
Foam::sqr(boundaryTree.bb().mag())
|
||||
);
|
||||
|
||||
if (!info.hit())
|
||||
{
|
||||
info = boundaryTree.findNearest(sample, Foam::sqr(GREAT));
|
||||
}
|
||||
|
||||
const label facei = treeData.objectIndex(info.index());
|
||||
|
||||
const label patchi = bm.whichPatch(facei);
|
||||
|
||||
if (isA<emptyPolyPatch>(bm[patchi]))
|
||||
{
|
||||
WarningInFunction
|
||||
<< " The sample point: " << sample
|
||||
<< " belongs to " << patchi
|
||||
<< " which is an empty patch. This is not permitted. "
|
||||
<< " This sample will not be included "
|
||||
<< endl;
|
||||
}
|
||||
else if (info.hit())
|
||||
{
|
||||
// Note: do we store the face centre or the actual nearest?
|
||||
// We interpolate using the faceI only though (no
|
||||
// interpolation) so it does not actually matter much, just for
|
||||
// the location written to the header.
|
||||
|
||||
//const point& facePt = mesh.faceCentres()[faceI];
|
||||
const point& facePt = info.point();
|
||||
|
||||
mappedPatchBase::nearInfo sampleInfo;
|
||||
|
||||
sampleInfo.first() = pointIndexHit(true, facePt, facei);
|
||||
|
||||
sampleInfo.second().first() = facePt.distSqr(sample);
|
||||
sampleInfo.second().second() = Pstream::myProcNo();
|
||||
|
||||
nearest[probei] = sampleInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find nearest - globally consistent
|
||||
Pstream::listCombineReduce(nearest, mappedPatchBase::nearestEqOp());
|
||||
|
||||
oldPoints_.resize(this->size());
|
||||
|
||||
pointField& probeLocations = this->probeLocations();
|
||||
// Update actual probe locations and store old ones
|
||||
forAll(nearest, samplei)
|
||||
{
|
||||
oldPoints_[samplei] = probeLocations[samplei];
|
||||
probeLocations[samplei] = nearest[samplei].first().point();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction << nl;
|
||||
forAll(nearest, samplei)
|
||||
{
|
||||
label proci = nearest[samplei].second().second();
|
||||
label locali = nearest[samplei].first().index();
|
||||
|
||||
Info<< " " << samplei << " coord:"<< probeLocations[samplei]
|
||||
<< " found on processor:" << proci
|
||||
<< " in local face:" << locali
|
||||
<< " with location:" << nearest[samplei].first().point()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract any local faces to sample:
|
||||
// - operator[] : actual point to sample (=nearest point on patch)
|
||||
// - oldPoints_ : original provided point (might be anywhere in the mesh)
|
||||
// - cellIds_ : cells, not used
|
||||
// - faceIds_ : faces (now patch faces)
|
||||
// - patchIds_ : patch corresponding to faceList
|
||||
// - procIds_ : processor
|
||||
cellIds_.resize_nocopy(nearest.size());
|
||||
cellIds_ = -1;
|
||||
|
||||
faceIds_.resize_nocopy(nearest.size());
|
||||
faceIds_ = -1;
|
||||
|
||||
procIds_.resize_nocopy(nearest.size());
|
||||
procIds_ = -1;
|
||||
|
||||
patchIds_.resize_nocopy(nearest.size());
|
||||
patchIds_ = -1;
|
||||
|
||||
forAll(nearest, sampleI)
|
||||
{
|
||||
procIds_[sampleI] = nearest[sampleI].second().second();
|
||||
|
||||
if (nearest[sampleI].second().second() == Pstream::myProcNo())
|
||||
{
|
||||
// Store the face to sample
|
||||
faceIds_[sampleI] = nearest[sampleI].first().index();
|
||||
const label facei = faceIds_[sampleI];
|
||||
if (facei != -1)
|
||||
{
|
||||
procIds_[sampleI] = Pstream::myProcNo();
|
||||
patchIds_[sampleI] = bm.whichPatch(facei);
|
||||
}
|
||||
}
|
||||
reduce(procIds_[sampleI], maxOp<label>());
|
||||
reduce(patchIds_[sampleI], maxOp<label>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::patchProber::patchProber
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
prober(mesh, dict)
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::patchProber::read(const dictionary& dict)
|
||||
{
|
||||
if (!prober::read(dict))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dict.readIfPresent("patches", patchNames_))
|
||||
{
|
||||
patchNames_.resize(1);
|
||||
patchNames_.first() = dict.get<word>("patch");
|
||||
}
|
||||
|
||||
// Initialise cells to sample from supplied locations
|
||||
findElements(mesh_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
152
src/sampling/probes/probers/patchProber/patchProber.H
Normal file
152
src/sampling/probes/probers/patchProber/patchProber.H
Normal file
@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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::patchProber
|
||||
|
||||
Description
|
||||
Utility class for probing specified points on user-selected boundary
|
||||
patches. The input points are projected onto the nearest point of the
|
||||
nearest face on the specified patch, ensuring sampling occurs at valid
|
||||
patch locations.
|
||||
|
||||
The patchProber enables sampling of both volume and surface fields
|
||||
at these snapped locations. Patch selection is controlled via patch names or
|
||||
indices, and the class provides runtime selection and dictionary-driven
|
||||
configuration.
|
||||
|
||||
Typical usage involves specifying patch names and probe locations in a
|
||||
dictionary, after which the class manages the mapping and sampling
|
||||
operations.
|
||||
|
||||
SourceFiles
|
||||
patchProber.C
|
||||
patchProberTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_patchProber_H
|
||||
#define Foam_patchProber_H
|
||||
|
||||
#include "prober.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class patchProber Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class patchProber
|
||||
:
|
||||
public prober
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Names of the patches to sample
|
||||
wordRes patchNames_;
|
||||
|
||||
//- Index of the patches to sample
|
||||
labelList patchIDs_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find elements containing patchProber
|
||||
virtual void findElements(const fvMesh& mesh);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("patchProber");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Time and dictionary
|
||||
patchProber
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~patchProber() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the index of the patches to sample
|
||||
const labelList& patchIDs() const noexcept { return patchIDs_; }
|
||||
|
||||
|
||||
// Sampling
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const VolumeField<Type>&) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const SurfaceField<Type>&) const;
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const word& fieldName) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sampleSurfaceField(const word& fieldName) const;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Read the settings dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "patchProberTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -5,8 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,70 +25,15 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "patchProbes.H"
|
||||
#include "patchProber.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "IOmanip.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::patchProbes::writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values,
|
||||
const scalar timeValue
|
||||
)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
const unsigned int w = IOstream::defaultPrecision() + 7;
|
||||
OFstream& os = *probeFilePtrs_[fieldName];
|
||||
|
||||
os << setw(w) << timeValue;
|
||||
|
||||
for (const auto& v : values)
|
||||
{
|
||||
os << ' ' << setw(w) << v;
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::patchProbes::performAction
|
||||
(
|
||||
const fieldGroup<GeoField>& fieldNames,
|
||||
unsigned request
|
||||
)
|
||||
{
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
tmp<GeoField> tfield = getOrLoadField<GeoField>(fieldName);
|
||||
|
||||
if (tfield)
|
||||
{
|
||||
const auto& field = tfield();
|
||||
const scalar timeValue = field.time().timeOutputValue();
|
||||
|
||||
Field<typename GeoField::value_type> values(sample(field));
|
||||
|
||||
this->storeResults(fieldName, values);
|
||||
if (request & ACTION_WRITE)
|
||||
{
|
||||
this->writeValues(fieldName, values, timeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::patchProbes::sample(const VolumeField<Type>& vField) const
|
||||
Foam::patchProber::sample(const VolumeField<Type>& vField) const
|
||||
{
|
||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||
|
||||
@ -101,7 +45,7 @@ Foam::patchProbes::sample(const VolumeField<Type>& vField) const
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
label facei = faceList_[probei];
|
||||
label facei = faceIds_[probei];
|
||||
|
||||
if (facei >= 0)
|
||||
{
|
||||
@ -119,7 +63,7 @@ Foam::patchProbes::sample(const VolumeField<Type>& vField) const
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::patchProbes::sample(const SurfaceField<Type>& sField) const
|
||||
Foam::patchProber::sample(const SurfaceField<Type>& sField) const
|
||||
{
|
||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||
|
||||
@ -131,7 +75,7 @@ Foam::patchProbes::sample(const SurfaceField<Type>& sField) const
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
label facei = faceList_[probei];
|
||||
label facei = faceIds_[probei];
|
||||
|
||||
if (facei >= 0)
|
||||
{
|
||||
@ -149,7 +93,7 @@ Foam::patchProbes::sample(const SurfaceField<Type>& sField) const
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::patchProbes::sample(const word& fieldName) const
|
||||
Foam::patchProber::sample(const word& fieldName) const
|
||||
{
|
||||
return sample(mesh_.lookupObject<VolumeField<Type>>(fieldName));
|
||||
}
|
||||
@ -157,7 +101,7 @@ Foam::patchProbes::sample(const word& fieldName) const
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::patchProbes::sampleSurfaceField(const word& fieldName) const
|
||||
Foam::patchProber::sampleSurfaceField(const word& fieldName) const
|
||||
{
|
||||
return sample(mesh_.lookupObject<SurfaceField<Type>>(fieldName));
|
||||
}
|
||||
188
src/sampling/probes/probers/prober.C
Normal file
188
src/sampling/probes/probers/prober.C
Normal file
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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 "prober.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(prober, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::prober::prober
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
samplePointScheme_("cell")
|
||||
{
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::prober::read(const dictionary& dict)
|
||||
{
|
||||
dict.readEntry("probeLocations", probes_);
|
||||
|
||||
if (probes_.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Empty 'probeLocations' list."
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
fixedLocations_ = dict.getOrDefault<bool>("fixedLocations", true);
|
||||
includeOutOfBounds_ = dict.getOrDefault<bool>("includeOutOfBounds", true);
|
||||
|
||||
if (dict.readIfPresent("interpolationScheme", samplePointScheme_))
|
||||
{
|
||||
if (!fixedLocations_ && samplePointScheme_ != "cell")
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Only cell interpolation can be applied when "
|
||||
<< "not using fixedLocations. InterpolationScheme "
|
||||
<< "entry will be ignored"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Foam::prober::updateMesh(const mapPolyMesh& mpm)
|
||||
{
|
||||
DebugInfo<< "probes: updateMesh" << endl;
|
||||
|
||||
if (&mpm.mesh() != &mesh_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (fixedLocations_)
|
||||
{
|
||||
this->findElements(mesh_);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugInfo<< "probes: remapping sample locations" << endl;
|
||||
|
||||
// 1. Update cells
|
||||
{
|
||||
DynamicList<label> elems(cellIds_.size());
|
||||
|
||||
const labelList& reverseMap = mpm.reverseCellMap();
|
||||
forAll(cellIds_, i)
|
||||
{
|
||||
label celli = cellIds_[i];
|
||||
if (celli != -1)
|
||||
{
|
||||
label newCelli = reverseMap[celli];
|
||||
if (newCelli == -1)
|
||||
{
|
||||
// cell removed
|
||||
}
|
||||
else if (newCelli < -1)
|
||||
{
|
||||
// cell merged
|
||||
elems.append(-newCelli - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// valid new cell
|
||||
elems.append(newCelli);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep -1 elements so the size stays the same
|
||||
elems.append(-1);
|
||||
}
|
||||
}
|
||||
|
||||
cellIds_.transfer(elems);
|
||||
}
|
||||
|
||||
// 2. Update faces
|
||||
{
|
||||
DynamicList<label> elems(faceIds_.size());
|
||||
|
||||
const labelList& reverseMap = mpm.reverseFaceMap();
|
||||
for (const label facei : faceIds_)
|
||||
{
|
||||
if (facei != -1)
|
||||
{
|
||||
label newFacei = reverseMap[facei];
|
||||
if (newFacei == -1)
|
||||
{
|
||||
// face removed
|
||||
}
|
||||
else if (newFacei < -1)
|
||||
{
|
||||
// face merged
|
||||
elems.append(-newFacei - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// valid new face
|
||||
elems.append(newFacei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep -1 elements
|
||||
elems.append(-1);
|
||||
}
|
||||
}
|
||||
|
||||
faceIds_.transfer(elems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::prober::movePoints(const polyMesh& mesh)
|
||||
{
|
||||
DebugInfo<< "probes: movePoints" << endl;
|
||||
|
||||
if (fixedLocations_ && &mesh == &mesh_)
|
||||
{
|
||||
this->findElements(mesh_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
220
src/sampling/probes/probers/prober.H
Normal file
220
src/sampling/probes/probers/prober.H
Normal file
@ -0,0 +1,220 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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::patchProber
|
||||
|
||||
Description
|
||||
Base class for sampling fields at specified internal and boundary locations.
|
||||
|
||||
SourceFiles
|
||||
prober.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_prober_H
|
||||
#define Foam_prober_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "pointField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class prober Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class prober
|
||||
{
|
||||
protected:
|
||||
|
||||
template<class T>
|
||||
struct isNotEqOp
|
||||
{
|
||||
void operator()(T& x, const T& y) const
|
||||
{
|
||||
const T unsetVal(-VGREAT*pTraits<T>::one);
|
||||
|
||||
if (x != unsetVal)
|
||||
{
|
||||
// Keep x.
|
||||
|
||||
// Note: should check for y != unsetVal but multiple sample cells
|
||||
// already handled in read().
|
||||
}
|
||||
else
|
||||
{
|
||||
// x is not set. y might be.
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Const reference to the mesh
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//- Fixed locations (default: true)
|
||||
// Note: set to false for moving mesh calculations where locations
|
||||
// should move with the mesh
|
||||
bool fixedLocations_;
|
||||
|
||||
//- Include probes that were not found (default: true)
|
||||
bool includeOutOfBounds_;
|
||||
|
||||
//- Interpolation/sample scheme to obtain values at the points
|
||||
// Note: only possible when fixedLocations_ is true
|
||||
word samplePointScheme_;
|
||||
|
||||
|
||||
// Calculated
|
||||
|
||||
//- Probe locations
|
||||
pointField probes_;
|
||||
|
||||
//- Cells to be probed (obtained from the locations)
|
||||
labelList cellIds_;
|
||||
|
||||
//- Faces to be probed
|
||||
labelList faceIds_;
|
||||
|
||||
//- Processor holding the cell or face (-1 if point not found
|
||||
//- on any processor)
|
||||
labelList procIds_;
|
||||
|
||||
//- Patch IDs on which the new probes are located
|
||||
labelList patchIds_;
|
||||
|
||||
//- Original probes location
|
||||
pointField oldPoints_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find cells and faces containing probes
|
||||
virtual void findElements(const fvMesh& mesh) = 0;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("prober");
|
||||
|
||||
|
||||
// Generated Methods
|
||||
|
||||
//- No copy construct
|
||||
prober(const prober&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const prober&) = delete;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Time and dictionary
|
||||
prober
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~prober() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return true if no probe locations
|
||||
bool empty() const { return probes_.empty(); }
|
||||
|
||||
//- Return number of probe locations
|
||||
label size() const { return probes_.size(); }
|
||||
|
||||
//- Return true if fixed locations
|
||||
bool fixedLocations() const { return fixedLocations_; }
|
||||
|
||||
//- Return true if include out of bounds probes
|
||||
bool includeOutOfBounds() const { return includeOutOfBounds_; }
|
||||
|
||||
//- Return the interpolation scheme to obtain values at the points
|
||||
// Note: only possible when fixedLocations_ is true
|
||||
const word& samplePointScheme() const { return samplePointScheme_; }
|
||||
|
||||
//- Return const reference to the probe locations
|
||||
const pointField& probeLocations() const { return probes_; }
|
||||
|
||||
//- Return reference to the probe locations
|
||||
pointField& probeLocations() { return probes_; }
|
||||
|
||||
//- Return the location of probe i
|
||||
const point& probe(const label i) const { return probes_[i]; }
|
||||
|
||||
//- Cells to be probed (obtained from the locations)
|
||||
const labelList& elements() const { return cellIds_; }
|
||||
|
||||
//- Return const reference to the faces to be probed
|
||||
const labelList& faces() const { return faceIds_; }
|
||||
|
||||
//- Return const reference to the processor list
|
||||
const labelList& processors() const { return procIds_; }
|
||||
|
||||
//- Return const reference to the patch ID list
|
||||
const labelList& patchIDList() const noexcept { return patchIds_; }
|
||||
|
||||
//- Return const reference to the original probe locations
|
||||
const pointField& oldPoints() const noexcept { return oldPoints_; }
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Read the settings dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
//- Update for changes of mesh
|
||||
virtual void updateMesh(const mapPolyMesh&);
|
||||
|
||||
//- Update for changes of mesh
|
||||
virtual void movePoints(const polyMesh&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,12 +27,6 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "probes.H"
|
||||
#include "dictionary.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "Time.H"
|
||||
#include "IOmanip.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -40,7 +34,6 @@ License
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(probes, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
functionObject,
|
||||
@ -49,315 +42,6 @@ namespace Foam
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::probes::createProbeFiles(const wordList& fieldNames)
|
||||
{
|
||||
// Open new output streams
|
||||
|
||||
bool needsNewFiles = false;
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
if (!probeFilePtrs_.found(fieldName))
|
||||
{
|
||||
needsNewFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsNewFiles && Pstream::master())
|
||||
{
|
||||
DebugInfo
|
||||
<< "Probing fields: " << fieldNames << nl
|
||||
<< "Probing locations: " << *this << nl
|
||||
<< endl;
|
||||
|
||||
// Put in undecomposed case
|
||||
// (Note: gives problems for distributed data running)
|
||||
|
||||
fileName probeDir
|
||||
(
|
||||
mesh_.time().globalPath()
|
||||
/ functionObject::outputPrefix
|
||||
/ name()/mesh_.regionName()
|
||||
// Use startTime as the instance for output files
|
||||
/ mesh_.time().timeName(mesh_.time().startTime().value())
|
||||
);
|
||||
probeDir.clean(); // Remove unneeded ".."
|
||||
|
||||
// Create directory if needed
|
||||
Foam::mkDir(probeDir);
|
||||
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
if (probeFilePtrs_.found(fieldName))
|
||||
{
|
||||
// Safety
|
||||
continue;
|
||||
}
|
||||
|
||||
auto osPtr = autoPtr<OFstream>::New(probeDir/fieldName);
|
||||
auto& os = *osPtr;
|
||||
|
||||
probeFilePtrs_.insert(fieldName, osPtr);
|
||||
|
||||
DebugInfo<< "open probe stream: " << os.name() << endl;
|
||||
|
||||
const unsigned int width(IOstream::defaultPrecision() + 7);
|
||||
os.setf(std::ios_base::left);
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
os << "# Probe " << probei << ' ' << operator[](probei);
|
||||
|
||||
if (processor_[probei] == -1)
|
||||
{
|
||||
os << " # Not Found";
|
||||
}
|
||||
// Only for patchProbes
|
||||
else if (probei < patchIDList_.size())
|
||||
{
|
||||
const label patchi = patchIDList_[probei];
|
||||
if (patchi != -1)
|
||||
{
|
||||
const polyBoundaryMesh& bm = mesh_.boundaryMesh();
|
||||
if
|
||||
(
|
||||
patchi < bm.nNonProcessor()
|
||||
|| processor_[probei] == Pstream::myProcNo()
|
||||
)
|
||||
{
|
||||
os << " at patch " << bm[patchi].name();
|
||||
}
|
||||
os << " with a distance of "
|
||||
<< mag(operator[](probei)-oldPoints_[probei])
|
||||
<< " m to the original point "
|
||||
<< oldPoints_[probei];
|
||||
}
|
||||
}
|
||||
|
||||
os << nl;
|
||||
}
|
||||
|
||||
os << setw(width) << "# Time";
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
if (includeOutOfBounds_ || processor_[probei] != -1)
|
||||
{
|
||||
os << ' ' << setw(width) << probei;
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::probes::findElements(const fvMesh& mesh)
|
||||
{
|
||||
DebugInfo<< "probes: resetting sample locations" << endl;
|
||||
|
||||
elementList_.resize_nocopy(pointField::size());
|
||||
faceList_.resize_nocopy(pointField::size());
|
||||
processor_.resize_nocopy(pointField::size());
|
||||
processor_ = -1;
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
const point& location = (*this)[probei];
|
||||
|
||||
const label celli = mesh.findCell(location);
|
||||
|
||||
elementList_[probei] = celli;
|
||||
|
||||
if (celli != -1)
|
||||
{
|
||||
const labelList& cellFaces = mesh.cells()[celli];
|
||||
const vector& cellCentre = mesh.cellCentres()[celli];
|
||||
scalar minDistance = GREAT;
|
||||
label minFaceID = -1;
|
||||
forAll(cellFaces, i)
|
||||
{
|
||||
label facei = cellFaces[i];
|
||||
vector dist = mesh.faceCentres()[facei] - cellCentre;
|
||||
if (mag(dist) < minDistance)
|
||||
{
|
||||
minDistance = mag(dist);
|
||||
minFaceID = facei;
|
||||
}
|
||||
}
|
||||
faceList_[probei] = minFaceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
faceList_[probei] = -1;
|
||||
}
|
||||
|
||||
if (debug && (elementList_[probei] != -1 || faceList_[probei] != -1))
|
||||
{
|
||||
Pout<< "probes : found point " << location
|
||||
<< " in cell " << elementList_[probei]
|
||||
<< " and face " << faceList_[probei] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if all probes have been found.
|
||||
forAll(elementList_, probei)
|
||||
{
|
||||
const point& location = operator[](probei);
|
||||
label celli = elementList_[probei];
|
||||
label facei = faceList_[probei];
|
||||
|
||||
processor_[probei] = (celli != -1 ? Pstream::myProcNo() : -1);
|
||||
|
||||
// Check at least one processor with cell.
|
||||
reduce(celli, maxOp<label>());
|
||||
reduce(facei, maxOp<label>());
|
||||
reduce(processor_[probei], maxOp<label>());
|
||||
|
||||
if (celli == -1)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Did not find location " << location
|
||||
<< " in any cell. Skipping location." << endl;
|
||||
}
|
||||
}
|
||||
else if (facei == -1)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Did not find location " << location
|
||||
<< " in any face. Skipping location." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure location not on two domains.
|
||||
if (elementList_[probei] != -1 && elementList_[probei] != celli)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Location " << location
|
||||
<< " seems to be on multiple domains:"
|
||||
<< " cell " << elementList_[probei]
|
||||
<< " on my domain " << Pstream::myProcNo()
|
||||
<< " and cell " << celli << " on some other domain."
|
||||
<< nl
|
||||
<< "This might happen if the probe location is on"
|
||||
<< " a processor patch. Change the location slightly"
|
||||
<< " to prevent this." << endl;
|
||||
}
|
||||
|
||||
if (faceList_[probei] != -1 && faceList_[probei] != facei)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Location " << location
|
||||
<< " seems to be on multiple domains:"
|
||||
<< " cell " << faceList_[probei]
|
||||
<< " on my domain " << Pstream::myProcNo()
|
||||
<< " and face " << facei << " on some other domain."
|
||||
<< nl
|
||||
<< "This might happen if the probe location is on"
|
||||
<< " a processor patch. Change the location slightly"
|
||||
<< " to prevent this." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::probes::prepare(unsigned request)
|
||||
{
|
||||
// Prefilter on selection
|
||||
HashTable<wordHashSet> selected =
|
||||
(
|
||||
loadFromFiles_
|
||||
? IOobjectList(mesh_, mesh_.time().timeName()).classes(fieldSelection_)
|
||||
: mesh_.classes(fieldSelection_)
|
||||
);
|
||||
|
||||
// Classify and count fields
|
||||
label nFields = 0;
|
||||
do
|
||||
{
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(InputType, Target) \
|
||||
{ \
|
||||
Target.clear(); /* Remove old values */ \
|
||||
const auto iter = selected.cfind(InputType::typeName); \
|
||||
if (iter.good()) \
|
||||
{ \
|
||||
/* Add new (current) values */ \
|
||||
Target.append(iter.val().sortedToc()); \
|
||||
nFields += Target.size(); \
|
||||
} \
|
||||
}
|
||||
|
||||
doLocalCode(volScalarField, scalarFields_);
|
||||
doLocalCode(volVectorField, vectorFields_)
|
||||
doLocalCode(volSphericalTensorField, sphericalTensorFields_);
|
||||
doLocalCode(volSymmTensorField, symmTensorFields_);
|
||||
doLocalCode(volTensorField, tensorFields_);
|
||||
|
||||
doLocalCode(surfaceScalarField, surfaceScalarFields_);
|
||||
doLocalCode(surfaceVectorField, surfaceVectorFields_);
|
||||
doLocalCode(surfaceSphericalTensorField, surfaceSphericalTensorFields_);
|
||||
doLocalCode(surfaceSymmTensorField, surfaceSymmTensorFields_);
|
||||
doLocalCode(surfaceTensorField, surfaceTensorFields_);
|
||||
#undef doLocalCode
|
||||
}
|
||||
while (false);
|
||||
|
||||
|
||||
// Adjust file streams
|
||||
if (Pstream::master())
|
||||
{
|
||||
wordHashSet currentFields(2*nFields);
|
||||
currentFields.insert(scalarFields_);
|
||||
currentFields.insert(vectorFields_);
|
||||
currentFields.insert(sphericalTensorFields_);
|
||||
currentFields.insert(symmTensorFields_);
|
||||
currentFields.insert(tensorFields_);
|
||||
|
||||
currentFields.insert(surfaceScalarFields_);
|
||||
currentFields.insert(surfaceVectorFields_);
|
||||
currentFields.insert(surfaceSphericalTensorFields_);
|
||||
currentFields.insert(surfaceSymmTensorFields_);
|
||||
currentFields.insert(surfaceTensorFields_);
|
||||
|
||||
DebugInfo
|
||||
<< "Probing fields: " << currentFields << nl
|
||||
<< "Probing locations: " << *this << nl
|
||||
<< endl;
|
||||
|
||||
// Close streams for fields that no longer exist
|
||||
forAllIters(probeFilePtrs_, iter)
|
||||
{
|
||||
if (!currentFields.erase(iter.key()))
|
||||
{
|
||||
DebugInfo<< "close probe stream: " << iter()->name() << endl;
|
||||
|
||||
probeFilePtrs_.remove(iter);
|
||||
}
|
||||
}
|
||||
|
||||
if ((request & ACTION_WRITE) && !currentFields.empty())
|
||||
{
|
||||
createProbeFiles(currentFields.sortedToc());
|
||||
}
|
||||
}
|
||||
|
||||
return nFields;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::probes::probes
|
||||
@ -369,15 +53,14 @@ Foam::probes::probes
|
||||
const bool readFields
|
||||
)
|
||||
:
|
||||
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||
pointField(),
|
||||
loadFromFiles_(loadFromFiles),
|
||||
fixedLocations_(true),
|
||||
includeOutOfBounds_(true),
|
||||
verbose_(false),
|
||||
onExecute_(false),
|
||||
fieldSelection_(),
|
||||
samplePointScheme_("cell")
|
||||
Base
|
||||
(
|
||||
name,
|
||||
runTime,
|
||||
dict,
|
||||
loadFromFiles,
|
||||
readFields
|
||||
)
|
||||
{
|
||||
if (readFields)
|
||||
{
|
||||
@ -388,184 +71,14 @@ Foam::probes::probes
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::probes::verbose(const bool on) noexcept
|
||||
{
|
||||
bool old(verbose_);
|
||||
verbose_ = on;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::probes::read(const dictionary& dict)
|
||||
{
|
||||
dict.readEntry("probeLocations", static_cast<pointField&>(*this));
|
||||
dict.readEntry("fields", fieldSelection_);
|
||||
|
||||
dict.readIfPresent("fixedLocations", fixedLocations_);
|
||||
dict.readIfPresent("includeOutOfBounds", includeOutOfBounds_);
|
||||
|
||||
verbose_ = dict.getOrDefault("verbose", false);
|
||||
onExecute_ = dict.getOrDefault("sampleOnExecute", false);
|
||||
|
||||
if (dict.readIfPresent("interpolationScheme", samplePointScheme_))
|
||||
if (!(Probes::read(dict) && prober_.read(dict)))
|
||||
{
|
||||
if (!fixedLocations_ && samplePointScheme_ != "cell")
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Only cell interpolation can be applied when "
|
||||
<< "not using fixedLocations. InterpolationScheme "
|
||||
<< "entry will be ignored"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise cells to sample from supplied locations
|
||||
findElements(mesh_);
|
||||
|
||||
// Close old (ununsed) streams
|
||||
prepare(ACTION_NONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::probes::performAction(unsigned request)
|
||||
{
|
||||
if (!pointField::empty() && request && prepare(request))
|
||||
{
|
||||
performAction(scalarFields_, request);
|
||||
performAction(vectorFields_, request);
|
||||
performAction(sphericalTensorFields_, request);
|
||||
performAction(symmTensorFields_, request);
|
||||
performAction(tensorFields_, request);
|
||||
|
||||
performAction(surfaceScalarFields_, request);
|
||||
performAction(surfaceVectorFields_, request);
|
||||
performAction(surfaceSphericalTensorFields_, request);
|
||||
performAction(surfaceSymmTensorFields_, request);
|
||||
performAction(surfaceTensorFields_, request);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::probes::execute()
|
||||
{
|
||||
if (onExecute_)
|
||||
{
|
||||
return performAction(ACTION_ALL & ~ACTION_WRITE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::probes::write()
|
||||
{
|
||||
return performAction(ACTION_ALL);
|
||||
}
|
||||
|
||||
|
||||
void Foam::probes::updateMesh(const mapPolyMesh& mpm)
|
||||
{
|
||||
DebugInfo<< "probes: updateMesh" << endl;
|
||||
|
||||
if (&mpm.mesh() != &mesh_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (fixedLocations_)
|
||||
{
|
||||
findElements(mesh_);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugInfo<< "probes: remapping sample locations" << endl;
|
||||
|
||||
// 1. Update cells
|
||||
{
|
||||
DynamicList<label> elems(elementList_.size());
|
||||
|
||||
const labelList& reverseMap = mpm.reverseCellMap();
|
||||
forAll(elementList_, i)
|
||||
{
|
||||
label celli = elementList_[i];
|
||||
if (celli != -1)
|
||||
{
|
||||
label newCelli = reverseMap[celli];
|
||||
if (newCelli == -1)
|
||||
{
|
||||
// cell removed
|
||||
}
|
||||
else if (newCelli < -1)
|
||||
{
|
||||
// cell merged
|
||||
elems.append(-newCelli - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// valid new cell
|
||||
elems.append(newCelli);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep -1 elements so the size stays the same
|
||||
elems.append(-1);
|
||||
}
|
||||
}
|
||||
|
||||
elementList_.transfer(elems);
|
||||
}
|
||||
|
||||
// 2. Update faces
|
||||
{
|
||||
DynamicList<label> elems(faceList_.size());
|
||||
|
||||
const labelList& reverseMap = mpm.reverseFaceMap();
|
||||
for (const label facei : faceList_)
|
||||
{
|
||||
if (facei != -1)
|
||||
{
|
||||
label newFacei = reverseMap[facei];
|
||||
if (newFacei == -1)
|
||||
{
|
||||
// face removed
|
||||
}
|
||||
else if (newFacei < -1)
|
||||
{
|
||||
// face merged
|
||||
elems.append(-newFacei - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// valid new face
|
||||
elems.append(newFacei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep -1 elements
|
||||
elems.append(-1);
|
||||
}
|
||||
}
|
||||
|
||||
faceList_.transfer(elems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::probes::movePoints(const polyMesh& mesh)
|
||||
{
|
||||
DebugInfo<< "probes: movePoints" << endl;
|
||||
|
||||
if (fixedLocations_ && &mesh == &mesh_)
|
||||
{
|
||||
findElements(mesh_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,237 +31,88 @@ Group
|
||||
grpUtilitiesFunctionObjects
|
||||
|
||||
Description
|
||||
Set of locations to sample.
|
||||
Function object to sample fields at specified internal-mesh locations and
|
||||
write to file.
|
||||
|
||||
Call write() to sample and write files.
|
||||
|
||||
Example of function object specification:
|
||||
Usage
|
||||
Minimal example by using \c system/controlDict.functions:
|
||||
\verbatim
|
||||
probes
|
||||
{
|
||||
// Mandatory entries
|
||||
type probes;
|
||||
libs (sampling);
|
||||
|
||||
// Name of the directory for probe data
|
||||
name probes;
|
||||
fields (<wordRes>);
|
||||
probeLocations (<vectorList>);
|
||||
|
||||
// Write at same frequency as fields
|
||||
writeControl writeTime;
|
||||
writeInterval 1;
|
||||
// Optional entries
|
||||
verbose <bool>;
|
||||
sampleOnExecute <bool>;
|
||||
fixedLocations <bool>;
|
||||
includeOutOfBounds <bool>;
|
||||
interpolationScheme <word>;
|
||||
|
||||
// Fields to be probed
|
||||
fields (U "p.*");
|
||||
|
||||
// Optional: do not recalculate cells if mesh moves
|
||||
fixedLocations false;
|
||||
|
||||
// Optional: interpolation scheme to use (default is cell)
|
||||
interpolationScheme cellPoint;
|
||||
|
||||
probeLocations
|
||||
(
|
||||
( 1e-06 0 0.01 ) // at inlet
|
||||
(0.21 -0.20999 0.01) // at outlet1
|
||||
(0.21 0.20999 0.01) // at outlet2
|
||||
(0.21 0 0.01) // at central block
|
||||
);
|
||||
|
||||
// Optional: filter out points that haven't been found. Default
|
||||
// is to include them (with value -VGREAT)
|
||||
includeOutOfBounds true;
|
||||
// Inherited entries
|
||||
...
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Entries:
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
type | Type-name: probes | yes |
|
||||
probeLocations | Probe locations | yes |
|
||||
fields | word/regex list of fields to sample | yes |
|
||||
interpolationScheme | scheme to obtain values | no | cell
|
||||
fixedLocations | Do not recalculate cells if mesh moves | no | true
|
||||
includeOutOfBounds | Include out-of-bounds locations | no | true
|
||||
sampleOnExecute | Sample on execution and store results | no | false
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
type | Type name: probes | word | yes | -
|
||||
libs | Library name: sampling | word | yes | -
|
||||
fields | Names of fields to probe | wordRes | yes | -
|
||||
probeLocations | Locations of probes | vectorList | yes | -
|
||||
verbose | Enable/disable verbose output | bool | no | false
|
||||
sampleOnExecute | Sample on execution and store results | bool | no <!--
|
||||
--> | false
|
||||
fixedLocations | Do not recalculate cells if mesh moves | bool | no | true
|
||||
includeOutOfBounds | Include out-of-bounds locations | bool | no | true
|
||||
interpolationScheme | Scheme to obtain values at the points | word <!--
|
||||
--> | no | cell
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link fvMeshFunctionObject.H \endlink
|
||||
- \link Probes.H \endlink
|
||||
- \link internalProber.H \endlink
|
||||
- \link prober.H \endlink
|
||||
|
||||
Note
|
||||
- The \c includeOutOfBounds filters out points that haven't been found.
|
||||
Default is to include them (with value \c -VGREAT).
|
||||
|
||||
SourceFiles
|
||||
probes.C
|
||||
probesTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_probes_H
|
||||
#define Foam_probes_H
|
||||
|
||||
#include "fvMeshFunctionObject.H"
|
||||
#include "HashPtrTable.H"
|
||||
#include "OFstream.H"
|
||||
#include "polyMesh.H"
|
||||
#include "pointField.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "surfaceFieldsFwd.H"
|
||||
#include "surfaceMesh.H"
|
||||
#include "wordRes.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "Probes.H"
|
||||
#include "internalProber.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class Time;
|
||||
class objectRegistry;
|
||||
class dictionary;
|
||||
class fvMesh;
|
||||
class mapPolyMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class probes Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class probes
|
||||
:
|
||||
public functionObjects::fvMeshFunctionObject,
|
||||
public pointField
|
||||
public Probes<internalProber>
|
||||
{
|
||||
protected:
|
||||
// Private Data
|
||||
|
||||
// Protected Classes
|
||||
//- Use simpler synonym for the base type
|
||||
using Base = Probes<internalProber>;
|
||||
|
||||
//- Grouping of field names by GeometricField type
|
||||
template<class GeoField>
|
||||
struct fieldGroup : public DynamicList<word> {};
|
||||
|
||||
|
||||
// Data Types
|
||||
|
||||
//- Local control for sampling actions
|
||||
enum sampleActionType : unsigned
|
||||
{
|
||||
ACTION_NONE = 0,
|
||||
ACTION_WRITE = 0x1,
|
||||
ACTION_STORE = 0x2,
|
||||
ACTION_ALL = 0xF
|
||||
};
|
||||
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Load fields from files (not from objectRegistry)
|
||||
bool loadFromFiles_;
|
||||
|
||||
//- Fixed locations (default: true)
|
||||
// Note: set to false for moving mesh calculations where locations
|
||||
// should move with the mesh
|
||||
bool fixedLocations_;
|
||||
|
||||
//- Include probes that were not found (default: true)
|
||||
bool includeOutOfBounds_;
|
||||
|
||||
//- Output verbosity
|
||||
bool verbose_;
|
||||
|
||||
//- Perform sample actions on execute as well
|
||||
bool onExecute_;
|
||||
|
||||
//- Requested names of fields to probe
|
||||
wordRes fieldSelection_;
|
||||
|
||||
//- Interpolation/sample scheme to obtain values at the points
|
||||
// Note: only possible when fixedLocations_ is true
|
||||
word samplePointScheme_;
|
||||
|
||||
|
||||
// Calculated
|
||||
|
||||
//- Current list of field names selected for sampling
|
||||
DynamicList<word> selectedFieldNames_;
|
||||
|
||||
//- Categorized scalar/vector/tensor volume fields
|
||||
fieldGroup<volScalarField> scalarFields_;
|
||||
fieldGroup<volVectorField> vectorFields_;
|
||||
fieldGroup<volSphericalTensorField> sphericalTensorFields_;
|
||||
fieldGroup<volSymmTensorField> symmTensorFields_;
|
||||
fieldGroup<volTensorField> tensorFields_;
|
||||
|
||||
//- Categorized scalar/vector/tensor surface fields
|
||||
fieldGroup<surfaceScalarField> surfaceScalarFields_;
|
||||
fieldGroup<surfaceVectorField> surfaceVectorFields_;
|
||||
fieldGroup<surfaceSphericalTensorField> surfaceSphericalTensorFields_;
|
||||
fieldGroup<surfaceSymmTensorField> surfaceSymmTensorFields_;
|
||||
fieldGroup<surfaceTensorField> surfaceTensorFields_;
|
||||
|
||||
//- Cells to be probed (obtained from the locations)
|
||||
labelList elementList_;
|
||||
|
||||
//- Faces to be probed
|
||||
labelList faceList_;
|
||||
|
||||
//- Processor holding the cell or face (-1 if point not found
|
||||
// on any processor)
|
||||
labelList processor_;
|
||||
|
||||
//- Current open files (non-empty on master only)
|
||||
HashPtrTable<OFstream> probeFilePtrs_;
|
||||
|
||||
//- Patch IDs on which the new probes are located (for patchProbes)
|
||||
labelList patchIDList_;
|
||||
|
||||
//- Original probes location (only used for patchProbes)
|
||||
pointField oldPoints_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Find cells and faces containing probes
|
||||
virtual void findElements(const fvMesh& mesh);
|
||||
|
||||
//- Classify field types, close/open file streams
|
||||
// \return number of fields to sample
|
||||
label prepare(unsigned request);
|
||||
|
||||
//- Get from registry or load from disk
|
||||
template<class GeoField>
|
||||
tmp<GeoField> getOrLoadField(const word& fieldName) const;
|
||||
|
||||
//- Store results: min/max/average/size
|
||||
template<class Type>
|
||||
void storeResults(const word& fieldName, const Field<Type>& values);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Create new streams as required
|
||||
void createProbeFiles(const wordList& fieldNames);
|
||||
|
||||
//- Write field values
|
||||
template<class Type>
|
||||
void writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values,
|
||||
const scalar timeValue
|
||||
);
|
||||
|
||||
//- Sample and store/write all applicable sampled fields
|
||||
template<class GeoField>
|
||||
void performAction
|
||||
(
|
||||
const fieldGroup<GeoField>& fieldNames, /* must be sorted */
|
||||
unsigned request
|
||||
);
|
||||
|
||||
//- Perform sampling action with store/write
|
||||
bool performAction(unsigned request);
|
||||
|
||||
//- No copy construct
|
||||
probes(const probes&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const probes&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
@ -288,86 +139,19 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Enable/disable verbose output
|
||||
// \return old value
|
||||
bool verbose(const bool on) noexcept;
|
||||
//- Bring Base::prober into this class's public scope.
|
||||
using Base::prober;
|
||||
|
||||
//- Return names of fields to probe
|
||||
virtual const wordRes& fieldNames() const noexcept
|
||||
{
|
||||
return fieldSelection_;
|
||||
}
|
||||
|
||||
//- Return locations to probe
|
||||
virtual const pointField& probeLocations() const noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
//- Return location for probe i
|
||||
virtual const point& probe(const label i) const
|
||||
{
|
||||
return operator[](i);
|
||||
}
|
||||
|
||||
//- Cells to be probed (obtained from the locations)
|
||||
const labelList& elements() const noexcept
|
||||
{
|
||||
return elementList_;
|
||||
}
|
||||
|
||||
//- Read the probes
|
||||
//- Read the settings from the dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
//- Sample and store result if the sampleOnExecute is enabled.
|
||||
virtual bool execute();
|
||||
|
||||
//- Sample and write
|
||||
virtual bool write();
|
||||
|
||||
//- Update for changes of mesh
|
||||
virtual void updateMesh(const mapPolyMesh&);
|
||||
|
||||
//- Update for changes of mesh
|
||||
virtual void movePoints(const polyMesh&);
|
||||
|
||||
//- Update for changes of mesh due to readUpdate
|
||||
virtual void readUpdate(const polyMesh::readUpdateState state)
|
||||
{}
|
||||
|
||||
|
||||
// Sampling
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const VolumeField<Type>&) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const SurfaceField<Type>&) const;
|
||||
|
||||
//- Sample a volume field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sample(const word& fieldName) const;
|
||||
|
||||
//- Sample a surface field at all locations
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sampleSurfaceField(const word& fieldName) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "probesTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -1,274 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "probes.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "IOmanip.H"
|
||||
#include "interpolation.H"
|
||||
#include "SpanStream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<class T>
|
||||
struct isNotEqOp
|
||||
{
|
||||
void operator()(T& x, const T& y) const
|
||||
{
|
||||
const T unsetVal(-VGREAT*pTraits<T>::one);
|
||||
|
||||
if (x != unsetVal)
|
||||
{
|
||||
// Keep x.
|
||||
|
||||
// Note: should check for y != unsetVal but multiple sample cells
|
||||
// already handled in read().
|
||||
}
|
||||
else
|
||||
{
|
||||
// x is not set. y might be.
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::probes::getOrLoadField(const word& fieldName) const
|
||||
{
|
||||
tmp<GeoField> tfield;
|
||||
|
||||
if (loadFromFiles_)
|
||||
{
|
||||
tfield.emplace
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
mesh_.time().timeName(),
|
||||
mesh_.thisDb(),
|
||||
IOobjectOption::MUST_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
),
|
||||
mesh_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
tfield.cref(mesh_.cfindObject<GeoField>(fieldName));
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::probes::storeResults
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values
|
||||
)
|
||||
{
|
||||
const MinMax<Type> limits(values);
|
||||
const Type avgVal = average(values);
|
||||
|
||||
this->setResult("average(" + fieldName + ")", avgVal);
|
||||
this->setResult("min(" + fieldName + ")", limits.min());
|
||||
this->setResult("max(" + fieldName + ")", limits.max());
|
||||
this->setResult("size(" + fieldName + ")", values.size());
|
||||
|
||||
if (verbose_)
|
||||
{
|
||||
Info<< name() << " : " << fieldName << nl
|
||||
<< " avg: " << avgVal << nl
|
||||
<< " min: " << limits.min() << nl
|
||||
<< " max: " << limits.max() << nl << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::probes::writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& values,
|
||||
const scalar timeValue
|
||||
)
|
||||
{
|
||||
if (Pstream::master())
|
||||
{
|
||||
const unsigned int width(IOstream::defaultPrecision() + 7);
|
||||
OFstream& os = *probeFilePtrs_[fieldName];
|
||||
|
||||
os << setw(width) << timeValue;
|
||||
|
||||
OCharStream buf;
|
||||
|
||||
forAll(values, probei)
|
||||
{
|
||||
if (includeOutOfBounds_ || processor_[probei] != -1)
|
||||
{
|
||||
buf.rewind();
|
||||
buf << values[probei];
|
||||
os << ' ' << setw(width) << buf.str().data();
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::probes::performAction
|
||||
(
|
||||
const fieldGroup<GeoField>& fieldNames,
|
||||
unsigned request
|
||||
)
|
||||
{
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
tmp<GeoField> tfield = getOrLoadField<GeoField>(fieldName);
|
||||
|
||||
if (tfield)
|
||||
{
|
||||
const auto& field = tfield();
|
||||
const scalar timeValue = field.time().timeOutputValue();
|
||||
|
||||
Field<typename GeoField::value_type> values(sample(field));
|
||||
|
||||
this->storeResults(fieldName, values);
|
||||
if (request & ACTION_WRITE)
|
||||
{
|
||||
this->writeValues(fieldName, values, timeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::probes::sample(const VolumeField<Type>& vField) const
|
||||
{
|
||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||
|
||||
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||
auto& values = tvalues.ref();
|
||||
|
||||
if (fixedLocations_)
|
||||
{
|
||||
autoPtr<interpolation<Type>> interpPtr
|
||||
(
|
||||
interpolation<Type>::New(samplePointScheme_, vField)
|
||||
);
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
if (elementList_[probei] >= 0)
|
||||
{
|
||||
const vector& position = operator[](probei);
|
||||
|
||||
values[probei] = interpPtr().interpolate
|
||||
(
|
||||
position,
|
||||
elementList_[probei],
|
||||
-1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(*this, probei)
|
||||
{
|
||||
if (elementList_[probei] >= 0)
|
||||
{
|
||||
values[probei] = vField[elementList_[probei]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pstream::listCombineReduce(values, isNotEqOp<Type>());
|
||||
|
||||
return tvalues;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::probes::sample(const SurfaceField<Type>& sField) const
|
||||
{
|
||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||
|
||||
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||
auto& values = tvalues.ref();
|
||||
|
||||
forAll(*this, probei)
|
||||
{
|
||||
if (faceList_[probei] >= 0)
|
||||
{
|
||||
values[probei] = sField[faceList_[probei]];
|
||||
}
|
||||
}
|
||||
|
||||
Pstream::listCombineReduce(values, isNotEqOp<Type>());
|
||||
|
||||
return tvalues;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::probes::sample(const word& fieldName) const
|
||||
{
|
||||
return sample(mesh_.lookupObject<VolumeField<Type>>(fieldName));
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::probes::sampleSurfaceField(const word& fieldName) const
|
||||
{
|
||||
return sample(mesh_.lookupObject<SurfaceField<Type>>(fieldName));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -243,6 +243,9 @@ public:
|
||||
//- Return access to the temperature field
|
||||
const volScalarField& T() const noexcept { return T_; }
|
||||
|
||||
//- Return the radiation solver frequency
|
||||
label solverFreq() const noexcept { return solverFreq_; }
|
||||
|
||||
//- Source term component (for power of T^4)
|
||||
virtual tmp<volScalarField> Rp() const = 0;
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class areaScalarField;
|
||||
object hs;
|
||||
object h_ceilingShell;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class areaScalarField;
|
||||
object ws;
|
||||
object wS;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -41,7 +41,7 @@ boundaryField
|
||||
nu 0.22;
|
||||
}
|
||||
|
||||
region vibration;
|
||||
region vibrationShell;
|
||||
vibrationShellModel KirchhoffShell;
|
||||
|
||||
f0 0.04;
|
||||
|
||||
@ -17,13 +17,12 @@ FoamFile
|
||||
pressure
|
||||
{
|
||||
type externalFileSource;
|
||||
//fieldName ws_shell;
|
||||
fieldName ws;
|
||||
fieldName ws_vibrationShell;
|
||||
tableName p;
|
||||
active true;
|
||||
timeStart 0.001;
|
||||
duration 0.03;
|
||||
region vibration;
|
||||
region vibrationShell;
|
||||
selectionMode all;
|
||||
|
||||
sampleFormat ensight;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / O peration | Version: v2506 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -26,9 +26,8 @@ d2dt2Schemes
|
||||
|
||||
gradSchemes
|
||||
{
|
||||
default leastSquares;
|
||||
grad(ws) leastSquares;
|
||||
grad(ws_shell) leastSquares;
|
||||
default leastSquares;
|
||||
grad(ws_vibrationShell) leastSquares;
|
||||
}
|
||||
|
||||
divSchemes
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / O peration | Version: v2506 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -16,7 +16,7 @@ FoamFile
|
||||
|
||||
solvers
|
||||
{
|
||||
"(ws|ws_.*)"
|
||||
ws_vibrationShell
|
||||
{
|
||||
solver diagonal;
|
||||
preconditioner DILU;
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object IDefault;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [ 1 0 -3 0 0 0 0 ];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type greyDiffusiveRadiation;
|
||||
value uniform 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,80 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object T;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
internalField uniform 300;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"floor.*"
|
||||
{
|
||||
type fixedValue;
|
||||
|
||||
type compressible::thermalShell;
|
||||
active true;
|
||||
|
||||
area floor;
|
||||
region lower;
|
||||
thermalShellModel thermalShell;
|
||||
|
||||
thermo
|
||||
{
|
||||
// Thermal properties
|
||||
rho 1000;
|
||||
kappa 200;
|
||||
Cp 600;
|
||||
emissivity 0;
|
||||
}
|
||||
|
||||
qr qr;
|
||||
thickness 1e-3;
|
||||
|
||||
value uniform 700;
|
||||
}
|
||||
|
||||
"ceiling.*"
|
||||
{
|
||||
type compressible::thermalShell;
|
||||
active true;
|
||||
|
||||
area ceiling;
|
||||
region upper;
|
||||
thermalShellModel thermalShell;
|
||||
|
||||
thermo
|
||||
{
|
||||
// Thermal properties
|
||||
rho 1000;
|
||||
kappa 200;
|
||||
Cp 600;
|
||||
emissivity 0;
|
||||
}
|
||||
|
||||
qr qr;
|
||||
thickness 1e-3;
|
||||
|
||||
value uniform 300;
|
||||
}
|
||||
|
||||
"fixedWall.*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,30 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volVectorField;
|
||||
object U;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 1 -1 0 0 0 0];
|
||||
|
||||
internalField uniform (0 0 0);
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type noSlip;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object alphat;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [1 -1 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type compressible::alphatWallFunction;
|
||||
value uniform 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object epsilon;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -3 0 0 0 0];
|
||||
|
||||
internalField uniform 0.01;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type epsilonWallFunction;
|
||||
value uniform 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class areaScalarField;
|
||||
object Ts;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
internalField uniform 300;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"side.*"
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 300;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,30 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class areaScalarField;
|
||||
object hs;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 1 0 0 0 0 0];
|
||||
|
||||
internalField uniform 1e-3;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"side.*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class areaScalarField;
|
||||
object Ts;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
internalField uniform 300;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"side.*"
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 300;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,30 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class areaScalarField;
|
||||
object hs;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 1 0 0 0 0 0];
|
||||
|
||||
internalField uniform 1e-3;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"side.*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object k;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 0.1;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type kqRWallFunction;
|
||||
value uniform 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,31 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object nut;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type nutkWallFunction;
|
||||
value uniform 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,43 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object p;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [1 -1 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 1e5;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"floor.*"
|
||||
{
|
||||
type calculated;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
"ceiling.*"
|
||||
{
|
||||
type calculated;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
"fixedWall.*"
|
||||
{
|
||||
type calculated;
|
||||
value $internalField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,43 +0,0 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2512 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object p_rgh;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [1 -1 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 1e5;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
"floor.*"
|
||||
{
|
||||
type fixedFluxPressure;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
"ceiling.*"
|
||||
{
|
||||
type fixedFluxPressure;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
"fixedWall.*"
|
||||
{
|
||||
type fixedFluxPressure;
|
||||
value $internalField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
cleanCase
|
||||
|
||||
## foamListRegions -finite-area
|
||||
for region in ceiling floor
|
||||
do
|
||||
cleanFaMesh -region "$region"
|
||||
rmdir "constant/finite-area/$region" 2>/dev/null
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
./Allrun.pre
|
||||
|
||||
runApplication makeFaMesh -all-area-regions
|
||||
|
||||
runApplication $(getApplication)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user