ENH: use objectRegistry/IOobjectList sorted instead of lookupClass

- in most cases a parallel-consistent order is required.
  Even when the order is not important, it will generally require
  fewer allocations to create a UPtrList of entries instead of a
  HashTable or even a wordList.
This commit is contained in:
Mark Olesen
2023-07-17 18:27:55 +02:00
parent d65e2d89b5
commit db16d80840
70 changed files with 1300 additions and 1758 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -285,7 +285,7 @@ void rewriteField
fieldName,
runTime.timeName(),
runTime,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
)
@ -369,29 +369,7 @@ void rewriteField
}
void rewriteFields
(
const bool dryrun,
const Time& runTime,
const wordList& fieldNames,
const HashTable<word>& thisNames,
const HashTable<word>& nbrNames
)
{
for (const word& fieldName : fieldNames)
{
rewriteField
(
dryrun,
runTime,
fieldName,
thisNames,
nbrNames
);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
@ -473,9 +451,9 @@ int main(int argc, char *argv[])
// Convert any fields
forAll(timeDirs, timeI)
forAll(timeDirs, timei)
{
runTime.setTime(timeDirs[timeI], timeI);
runTime.setTime(timeDirs[timei], timei);
Info<< "Time: " << runTime.timeName() << endl;
@ -514,139 +492,44 @@ int main(int argc, char *argv[])
entry::disableFunctionEntries = 1;
}
// Rewriting of fields:
#undef rewriteFields
#define rewriteFields(FieldType) \
for (const word& fieldName : objects.sortedNames<FieldType>()) \
{ \
rewriteField(dryrun, runTime, fieldName, thisNames, nbrNames); \
}
// volFields
// ~~~~~~~~~
rewriteFields
(
dryrun,
runTime,
objects.names(volScalarField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(volVectorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(volSphericalTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(volSymmTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(volTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields(volScalarField);
rewriteFields(volVectorField);
rewriteFields(volSphericalTensorField);
rewriteFields(volSymmTensorField);
rewriteFields(volTensorField);
// pointFields
// ~~~~~~~~~~~
rewriteFields
(
dryrun,
runTime,
objects.names(pointScalarField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(pointVectorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(pointSphericalTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(pointSymmTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(pointTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields(pointScalarField);
rewriteFields(pointVectorField);
rewriteFields(pointSphericalTensorField);
rewriteFields(pointSymmTensorField);
rewriteFields(pointTensorField);
// surfaceFields
// ~~~~~~~~~~~
// ~~~~~~~~~~~~~
rewriteFields
(
dryrun,
runTime,
objects.names(surfaceScalarField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(surfaceVectorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(surfaceSphericalTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(surfaceSymmTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
dryrun,
runTime,
objects.names(surfaceTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields(surfaceScalarField);
rewriteFields(surfaceVectorField);
rewriteFields(surfaceSphericalTensorField);
rewriteFields(surfaceSymmTensorField);
rewriteFields(surfaceTensorField);
#undef rewriteFields
entry::disableFunctionEntries = oldFlag;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2021 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,23 +52,20 @@ void MapConsistentVolFields
const fvMesh& meshSource = meshToMesh0Interp.fromMesh();
const fvMesh& meshTarget = meshToMesh0Interp.toMesh();
IOobjectList fields = objects.lookupClass(fieldType::typeName);
forAllConstIters(fields, fieldIter)
for (const IOobject& io : objects.csorted<fieldType>())
{
Info<< " interpolating " << (*fieldIter)->name()
<< endl;
Info<< " interpolating " << io.name() << endl;
// Read field. Do not auto-load old-time field
fieldType fieldSource(*fieldIter(), meshSource, false);
fieldType fieldSource(io, meshSource, false);
IOobject fieldTargetIOobject
(
(*fieldIter)->name(),
io.name(),
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
IOobjectOption::MUST_READ,
IOobjectOption::AUTO_WRITE
);
if (fieldTargetIOobject.typeHeaderOk<fieldType>(true))
@ -90,7 +87,7 @@ void MapConsistentVolFields
}
else
{
fieldTargetIOobject.readOpt(IOobject::NO_READ);
fieldTargetIOobject.readOpt(IOobjectOption::NO_READ);
// Interpolate field
fieldType fieldTarget

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,8 +33,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef MapLagrangianFields_H
#define MapLagrangianFields_H
#ifndef Foam_MapLagrangianFields_H
#define Foam_MapLagrangianFields_H
#include "cloud.H"
#include "GeometricField.H"
@ -47,6 +47,59 @@ Description
namespace Foam
{
//- Gets the indices of (source)particles that have been appended to the
// target cloud and maps the lagrangian fields accordingly.
template<class SourceIOFieldType, class TargetIOFieldType>
void MapLagrangianFields
(
const string& cloudName,
const IOobjectList& objects,
const meshToMesh0& meshToMesh0Interp,
const labelList& addParticles,
const char* msg
)
{
const fvMesh& meshTarget = meshToMesh0Interp.toMesh();
for (const IOobject& io : objects.csorted<SourceIOFieldType>())
{
Info<< " mapping lagrangian " << msg << ' ' << io.name() << endl;
// Read field (does not need mesh)
// Note: some fieldFields are 0 size (e.g. collision records)
// if not used, so catch any of those for Field as well
SourceIOFieldType fieldSource(io);
// Map
TargetIOFieldType fieldTarget
(
IOobject
(
io.name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
),
min(fieldSource.size(), addParticles.size()) // handle 0 size
);
if (!fieldSource.empty())
{
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
}
fieldTarget.write();
}
}
//- Gets the indices of (source)particles that have been appended to the
// target cloud and maps the lagrangian fields accordingly.
template<class Type>
@ -60,119 +113,46 @@ void MapLagrangianFields
{
const fvMesh& meshTarget = meshToMesh0Interp.toMesh();
{
IOobjectList fields = objects.lookupClass(IOField<Type>::typeName);
MapLagrangianFields
<
IOField<Type>,
IOField<Type>
>
(
cloudName,
objects,
meshToMesh0Interp,
addParticles,
"Field"
);
forAllConstIters(fields, fieldIter)
{
Info<< " mapping lagrangian field "
<< (*fieldIter)->name() << endl;
// Target is CompactIOField to automatically write in
// compact form for binary format.
MapLagrangianFields
<
IOField<Field<Type>>,
CompactIOField<Field<Type>, Type>
>
(
cloudName,
objects,
meshToMesh0Interp,
addParticles,
"FieldField"
);
// Read field (does not need mesh)
IOField<Type> fieldSource(*fieldIter());
// Map
IOField<Type> fieldTarget
(
IOobject
(
(*fieldIter)->name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(IOField<Field<Type>>::typeName);
forAllConstIters(fieldFields, fieldIter)
{
Info<< " mapping lagrangian fieldField "
<< (*fieldIter)->name() << endl;
// Read field (does not need mesh)
IOField<Field<Type>> fieldSource(*fieldIter());
// Map - use CompactIOField to automatically write in
// compact form for binary format.
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
(*fieldIter)->name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(CompactIOField<Field<Type>, Type>::typeName);
forAllConstIters(fieldFields, fieldIter)
{
Info<< " mapping lagrangian fieldField "
<< (*fieldIter)->name() << endl;
// Read field (does not need mesh)
CompactIOField<Field<Type>, Type> fieldSource(*fieldIter());
// Map
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
(*fieldIter)->name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
MapLagrangianFields
<
CompactIOField<Field<Type>, Type>,
CompactIOField<Field<Type>, Type>
>
(
cloudName,
objects,
meshToMesh0Interp,
addParticles,
"FieldField"
);
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,25 +52,23 @@ void MapVolFields
const fvMesh& meshSource = meshToMesh0Interp.fromMesh();
const fvMesh& meshTarget = meshToMesh0Interp.toMesh();
IOobjectList fields = objects.lookupClass(fieldType::typeName);
forAllConstIters(fields, fieldIter)
for (const IOobject& io : objects.csorted<fieldType>())
{
IOobject fieldTargetIOobject
(
(*fieldIter)->name(),
io.name(),
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
IOobjectOption::MUST_READ,
IOobjectOption::AUTO_WRITE
);
if (fieldTargetIOobject.typeHeaderOk<fieldType>(true))
{
Info<< " interpolating " << (*fieldIter)->name() << endl;
Info<< " interpolating " << io.name() << endl;
// Read field fieldSource. Do not auto-load old-time fields
fieldType fieldSource(*fieldIter(), meshSource, false);
fieldType fieldSource(io, meshSource, false);
// Read fieldTarget. Do not auto-load old-time fields
fieldType fieldTarget

View File

@ -40,11 +40,9 @@ namespace Foam
template<class Type>
void UnMapped(const IOobjectList& objects)
{
IOobjectList fields = objects.lookupClass(Type::typeName);
forAllConstIters(fields, fieldIter)
for (const IOobject& io : objects.csorted<Type>())
{
mvBak((*fieldIter)->objectPath(), "unmapped");
mvBak(io.objectPath(), "unmapped");
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,8 +33,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef MapLagrangianFields_H
#define MapLagrangianFields_H
#ifndef Foam_MapLagrangianFields_H
#define Foam_MapLagrangianFields_H
#include "cloud.H"
#include "GeometricField.H"
@ -47,6 +47,63 @@ Description
namespace Foam
{
//- Gets the indices of (source)particles that have been appended to the
// target cloud and maps the lagrangian fields accordingly.
template<class SourceIOFieldType, class TargetIOFieldType>
void MapLagrangianFields
(
const string& cloudName,
const IOobjectList& objects,
const polyMesh& meshTarget,
const labelList& addParticles,
const char* msg
)
{
for (const IOobject& io : objects.csorted<SourceIOFieldType>())
{
Info<< " mapping lagrangian " << msg << ' ' << io.name() << endl;
// Read field (does not need mesh)
// Note: some fieldFields are 0 size (e.g. collision records)
// if not used, so catch any of those for Field as well
SourceIOFieldType fieldSource(io);
// Map
TargetIOFieldType fieldTarget
(
IOobject
(
io.name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
),
min(fieldSource.size(), addParticles.size()) // handle 0 size
);
if (!fieldSource.empty())
{
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
}
else if (cloud::debug && !addParticles.empty())
{
Pout<< "Not mapping " << io.name()
<< " since source size = 0 and cloud size = "
<< addParticles.size() << endl;
}
fieldTarget.write();
}
}
//- Gets the indices of (source)particles that have been appended to the
// target cloud and maps the lagrangian fields accordingly.
template<class Type>
@ -58,144 +115,46 @@ void MapLagrangianFields
const labelList& addParticles
)
{
{
IOobjectList fields = objects.lookupClass(IOField<Type>::typeName);
MapLagrangianFields
<
IOField<Type>,
IOField<Type>
>
(
cloudName,
objects,
meshTarget,
addParticles,
"Field"
);
forAllConstIters(fields, fieldIter)
{
const word& fieldName = (*fieldIter)->name();
// Target is CompactIOField to automatically write in
// compact form for binary format.
MapLagrangianFields
<
IOField<Field<Type>>,
CompactIOField<Field<Type>, Type>
>
(
cloudName,
objects,
meshTarget,
addParticles,
"FieldField"
);
Info<< " mapping lagrangian field " << fieldName << endl;
// Read field (does not need mesh)
IOField<Type> fieldSource(*fieldIter());
// Map
IOField<Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(IOField<Field<Type>>::typeName);
forAllConstIters(fieldFields, fieldIter)
{
const word& fieldName = (*fieldIter)->name();
Info<< " mapping lagrangian fieldField " << fieldName << endl;
// Read field (does not need mesh)
// Note: some fieldFields are 0 size (e.g. collision records) if
// not used
IOField<Field<Type>> fieldSource(*fieldIter());
// Map - use CompactIOField to automatically write in
// compact form for binary format.
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
min(fieldSource.size(), addParticles.size()) // handle 0 size
);
if (fieldSource.size())
{
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
}
else if (cloud::debug)
{
Pout<< "Not mapping " << fieldName << " since source size "
<< fieldSource.size() << " different to"
<< " cloud size " << addParticles.size()
<< endl;
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(CompactIOField<Field<Type>, Type>::typeName);
forAllConstIters(fieldFields, fieldIter)
{
const word& fieldName = (*fieldIter)->name();
Info<< " mapping lagrangian fieldField " << fieldName << endl;
// Read field (does not need mesh)
CompactIOField<Field<Type>, Type> fieldSource(*fieldIter());
// Map
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
min(fieldSource.size(), addParticles.size()) // handle 0 size
);
if (fieldSource.size())
{
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
}
else if (cloud::debug)
{
Pout<< "Not mapping " << fieldName << " since source size "
<< fieldSource.size() << " different to"
<< " cloud size " << addParticles.size()
<< endl;
}
// Write field
fieldTarget.write();
}
}
MapLagrangianFields
<
CompactIOField<Field<Type>, Type>,
CompactIOField<Field<Type>, Type>
>
(
cloudName,
objects,
meshTarget,
addParticles,
"FieldField"
);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -132,20 +132,21 @@ void MapVolFields
const fvMesh& meshTarget = static_cast<const fvMesh&>(interp.tgtRegion());
// Available fields, sorted order
const wordList fieldNames =
for
(
selectedFields.empty()
? objects.sortedNames<fieldType>()
: objects.sortedNames<fieldType>(selectedFields)
);
for (const word& fieldName : fieldNames)
const IOobject& io :
(
selectedFields.empty()
? objects.csorted<fieldType>()
: objects.csorted<fieldType>(selectedFields)
)
)
{
const fieldType fieldSource(*(objects[fieldName]), meshSource, false);
const fieldType fieldSource(io, meshSource, false);
IOobject targetIO
(
fieldName,
io.name(),
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ
@ -154,7 +155,7 @@ void MapVolFields
if (targetIO.typeHeaderOk<fieldType>(true))
{
Info<< " interpolating onto existing field "
<< fieldName << endl;
<< targetIO.name() << endl;
fieldType fieldTarget(targetIO, meshTarget, false);
@ -167,7 +168,7 @@ void MapVolFields
else
{
Info<< " creating new field "
<< fieldName << endl;
<< targetIO.name() << endl;
targetIO.readOpt(IOobject::NO_READ);

View File

@ -40,11 +40,9 @@ namespace Foam
template<class Type>
void UnMapped(const IOobjectList& objects)
{
IOobjectList fields = objects.lookupClass(Type::typeName);
forAllConstIters(fields, fieldIter)
for (const IOobject& io : objects.csorted<Type>())
{
mvBak((*fieldIter)->objectPath(), "unmapped");
mvBak(io.objectPath(), "unmapped");
}
}