ENH: use sorted order for fieldSelection::selectionNames() (#2819)

- return a sorted wordList instead of a wordHashSet to ensure that
  fields will be processed in consistent order in parallel
This commit is contained in:
Mark Olesen
2023-07-06 13:05:34 +02:00
parent ed314b2740
commit dc95242cd2
12 changed files with 140 additions and 128 deletions

View File

@ -54,7 +54,7 @@ void executeFunctionObjects
const argList& args, const argList& args,
const Time& runTime, const Time& runTime,
fvMesh& mesh, fvMesh& mesh,
const wordHashSet& selectedFields, const wordList& selectedFields,
functionObjectList& functions, functionObjectList& functions,
bool lastTime bool lastTime
) )
@ -73,11 +73,16 @@ void executeFunctionObjects
objects.size() + constObjects.size() objects.size() + constObjects.size()
); );
const auto nameMatcher = [&](const word& name) -> bool
{
return selectedFields.contains(name);
};
// Read GeometricFields // Read GeometricFields
#undef ReadFields #undef ReadFields
#define ReadFields(FieldType) \ #define ReadFields(FieldType) \
readFields<FieldType>(mesh, objects, selectedFields, storedObjects); readFields<FieldType>(mesh, objects, nameMatcher, storedObjects);
// Read volFields // Read volFields
ReadFields(volScalarField); ReadFields(volScalarField);
@ -105,7 +110,7 @@ void executeFunctionObjects
const pointMesh& pMesh = pointMesh::New(mesh); const pointMesh& pMesh = pointMesh::New(mesh);
#undef ReadPointFields #undef ReadPointFields
#define ReadPointFields(FieldType) \ #define ReadPointFields(FieldType) \
readFields<FieldType>(pMesh, objects, selectedFields, storedObjects); readFields<FieldType>(pMesh, objects, nameMatcher, storedObjects);
ReadPointFields(pointScalarField) ReadPointFields(pointScalarField)
ReadPointFields(pointVectorField); ReadPointFields(pointVectorField);
@ -118,7 +123,7 @@ void executeFunctionObjects
#undef ReadUniformFields #undef ReadUniformFields
#define ReadUniformFields(FieldType) \ #define ReadUniformFields(FieldType) \
readUniformFields<FieldType>(constObjects, selectedFields, storedObjects); readUniformFields<FieldType>(constObjects, nameMatcher, storedObjects);
ReadUniformFields(uniformDimensionedScalarField); ReadUniformFields(uniformDimensionedScalarField);
ReadUniformFields(uniformDimensionedVectorField); ReadUniformFields(uniformDimensionedVectorField);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,8 +32,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_fieldInfo_H #ifndef Foam_functionObjects_fieldInfo_H
#define functionObjects_fieldInfo_H #define Foam_functionObjects_fieldInfo_H
#include "label.H" #include "label.H"
#include "wordRes.H" #include "wordRes.H"
@ -57,7 +57,7 @@ Ostream& operator<<(Ostream&, const fieldInfo&);
class fieldInfo class fieldInfo
{ {
// Pivate Data // Private Data
//- Pattern for the field name(s) //- Pattern for the field name(s)
wordRe name_; wordRe name_;
@ -65,8 +65,8 @@ class fieldInfo
//- Field component //- Field component
label component_; label component_;
//- Found //- Found the field
mutable Switch found_; mutable bool found_;
public: public:
@ -81,9 +81,8 @@ public:
found_(false) found_(false)
{} {}
//- Construct from components //- Construct from components
fieldInfo(const wordRe& name, const label component = -1) explicit fieldInfo(const wordRe& name, const label component = -1)
: :
name_(name), name_(name),
component_(component), component_(component),
@ -91,7 +90,7 @@ public:
{} {}
//- Construct from stream //- Construct from stream
fieldInfo(Istream& is) explicit fieldInfo(Istream& is)
: :
name_(is), name_(is),
component_(readLabel(is)), component_(readLabel(is)),
@ -105,27 +104,27 @@ public:
// Member Functions // Member Functions
const wordRe& name() const //- Return the selector pattern for the field name(s)
{ const wordRe& name() const noexcept { return name_; }
return name_;
}
label component() const //- Return the component
{ label component() const noexcept { return component_; }
return component_;
} //- Return the found state
bool found() const noexcept { return found_; }
//- Set the found state to be 'on'
void found(bool on) const noexcept { found_ = on; }
Switch& found() const
{
return found_;
}
friend bool operator==(const fieldInfo& a, const fieldInfo& b) friend bool operator==(const fieldInfo& a, const fieldInfo& b)
{ {
return return
a.name_ == b.name_ (
&& a.component_ == b.component_ a.found() == b.found()
&& a.found_ == b.found_; && a.component() == b.component()
&& a.name() == b.name()
);
} }
friend bool operator!=(const fieldInfo& a, const fieldInfo& b) friend bool operator!=(const fieldInfo& a, const fieldInfo& b)
@ -143,7 +142,9 @@ public:
} }
friend Ostream& operator<<(Ostream& os, const fieldInfo& fi) friend Ostream& operator<<(Ostream& os, const fieldInfo& fi)
{ {
os << fi.name_ << ' ' << fi.component_ << ' ' << fi.found_; os << fi.name_ << ' '
<< fi.component_ << ' '
<< Switch::name(fi.found_);
return os; return os;
} }
}; };

View File

@ -37,27 +37,28 @@ Foam::functionObjects::fieldSelection::fieldSelection
const bool includeComponents const bool includeComponents
) )
: :
List<fieldInfo>(),
obr_(obr), obr_(obr),
includeComponents_(includeComponents), includeComponents_(includeComponents)
selection_()
{} {}
bool Foam::functionObjects::fieldSelection::resetFieldFilters // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Container>
bool Foam::functionObjects::fieldSelection::resetFieldFiltersImpl
( (
const HashSet<wordRe>& names const Container& names
) )
{ {
static word cmptStr(".component("); static std::string cmptStr(".component(");
static string::size_type len(cmptStr.size()); static std::string::size_type len(cmptStr.size());
DynamicList<fieldInfo> nameAndComponent(names.size()); DynamicList<fieldInfo> nameAndComponent(names.size());
for (const wordRe& name : names) for (const wordRe& name : names)
{ {
string::size_type n = name.find(cmptStr); const auto n = name.find(cmptStr);
if (n != string::npos) if (n != std::string::npos)
{ {
// Field should be written <field>.component(i) // Field should be written <field>.component(i)
@ -76,12 +77,12 @@ bool Foam::functionObjects::fieldSelection::resetFieldFilters
<< exit(FatalError); << exit(FatalError);
} }
word baseName = name.substr(0, n); const word baseName(name.substr(0, n));
// Extract the component - number between ()'s // Extract the component - number between ()'s
string::size_type closei = name.find(')', n); const auto closei = name.find(')', n);
if (closei == string::npos) if (closei == std::string::npos)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Invalid field component specification for " << "Invalid field component specification for "
@ -90,18 +91,18 @@ bool Foam::functionObjects::fieldSelection::resetFieldFilters
<< exit(FatalError); << exit(FatalError);
} }
string::size_type cmptWidth = closei - n - len; const auto cmptWidth = (closei - n - len);
label component label component
( (
readLabel(IStringStream(name.substr(n+len, cmptWidth))()) readLabel(name.substr(n+len, cmptWidth))
); );
nameAndComponent.append(fieldInfo(wordRe(baseName), component)); nameAndComponent.emplace_back(wordRe(baseName), component);
} }
else else
{ {
nameAndComponent.append(fieldInfo(name)); nameAndComponent.emplace_back(name);
} }
} }
@ -111,12 +112,23 @@ bool Foam::functionObjects::fieldSelection::resetFieldFilters
} }
bool Foam::functionObjects::fieldSelection::resetFieldFilters
(
const HashSet<wordRe>& names
)
{
return resetFieldFiltersImpl(names);
}
bool Foam::functionObjects::fieldSelection::resetFieldFilters bool Foam::functionObjects::fieldSelection::resetFieldFilters
( (
const wordRe& name const wordRe& name
) )
{ {
return resetFieldFilters(HashSet<wordRe>({name})); List<wordRe> names(1, name);
return resetFieldFiltersImpl(names);
} }
@ -124,7 +136,8 @@ bool Foam::functionObjects::fieldSelection::resetFieldFilters
bool Foam::functionObjects::fieldSelection::read(const dictionary& dict) bool Foam::functionObjects::fieldSelection::read(const dictionary& dict)
{ {
HashSet<wordRe> fields(dict.lookup("fields")); HashSet<wordRe> fields(0);
dict.readEntry("fields", fields);
return resetFieldFilters(fields); return resetFieldFilters(fields);
} }

View File

@ -39,8 +39,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_fieldSelection_H #ifndef Foam_functionObjects_fieldSelection_H
#define functionObjects_fieldSelection_H #define Foam_functionObjects_fieldSelection_H
#include "fieldInfo.H" #include "fieldInfo.H"
#include "DynamicList.H" #include "DynamicList.H"
@ -51,6 +51,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class dictionary; class dictionary;
class objectRegistry; class objectRegistry;
@ -65,17 +66,19 @@ class fieldSelection
: :
public List<fieldInfo> public List<fieldInfo>
{ {
private:
// Private Member Functions // Private Member Functions
//- Reset the field filters to the given field names
template<class Container>
bool resetFieldFiltersImpl(const Container& names);
//- No copy construct //- No copy construct
fieldSelection(const fieldSelection&) = delete; fieldSelection(const fieldSelection&) = delete;
protected: protected:
// Protected member data // Protected Member Data
//- Reference to the database //- Reference to the database
const objectRegistry& obr_; const objectRegistry& obr_;
@ -97,7 +100,7 @@ protected:
public: public:
//- Construct from object registry //- Construct from object registry
fieldSelection explicit fieldSelection
( (
const objectRegistry& obr, const objectRegistry& obr,
const bool includeComponents = false const bool includeComponents = false
@ -110,13 +113,17 @@ public:
// Member Functions // Member Functions
//- Return the cuurent filters //- The current field selection
const List<fieldInfo>& selection() const noexcept
{
return selection_;
}
//- Return the current filters
inline HashSet<wordRe> filters() const; inline HashSet<wordRe> filters() const;
inline const List<fieldInfo>& selection() const; //- Return the current field selection, in sorted order
inline wordList selectionNames() const;
//- Return the current field selection
inline wordHashSet selectionNames() const;
//- Reset the field filters to the given field names //- Reset the field filters to the given field names
virtual bool resetFieldFilters(const HashSet<wordRe>& names); virtual bool resetFieldFilters(const HashSet<wordRe>& names);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,36 +25,34 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::HashSet<Foam::wordRe> inline Foam::HashSet<Foam::wordRe>
Foam::functionObjects::fieldSelection::filters() const Foam::functionObjects::fieldSelection::filters() const
{ {
HashSet<wordRe> f; HashSet<wordRe> values(2*this->size());
for (const fieldInfo& fi : *this) for (const fieldInfo& fi : *this)
{ {
f.insert(fi.name()); values.insert(fi.name());
} }
return f; return values;
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
inline const Foam::List<Foam::functionObjects::fieldInfo>&
Foam::functionObjects::fieldSelection::selection() const
{
return selection_;
} }
inline Foam::wordHashSet inline Foam::wordList
Foam::functionObjects::fieldSelection::selectionNames() const Foam::functionObjects::fieldSelection::selectionNames() const
{ {
wordHashSet names; DynamicList<word> values(selection_.size());
for (const fieldInfo& fi : selection_) for (const fieldInfo& fi : selection_)
{ {
names.insert(fi.name()); values.push_uniq(fi.name());
} }
wordList names(std::move(values));
Foam::sort(names); // Globally consistent order
return names; return names;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,15 +37,14 @@ void Foam::functionObjects::fieldSelection::addRegistered
{ {
for (const fieldInfo& fi : *this) for (const fieldInfo& fi : *this)
{ {
wordList names(obr_.names<Type>(fi.name())); const wordList names(obr_.sortedNames<Type>(fi.name()));
if (names.size()) if (!names.empty())
{ {
for (const word& name : names) fi.found(true);
{ }
set.append(fieldInfo(wordRe(name), fi.component())); for (const word& name : names)
} {
set.emplace_back(wordRe(name), fi.component());
fi.found() = true;
} }
} }
} }

View File

@ -51,14 +51,13 @@ void Foam::functionObjects::fileFieldSelection::addFromFile
{ {
const wordList names(objects.sortedNames<Type>(fi.name())); const wordList names(objects.sortedNames<Type>(fi.name()));
if (names.size()) if (!names.empty())
{ {
for (const word& name : names) fi.found(true);
{ }
set.append(fieldInfo(wordRe(name))); for (const word& name : names)
} {
set.emplace_back(wordRe(name));
fi.found() = true;
} }
} }
} }

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_fileFieldSelection_H #ifndef Foam_functionObjects_fileFieldSelection_H
#define functionObjects_fileFieldSelection_H #define Foam_functionObjects_fileFieldSelection_H
#include "fieldSelection.H" #include "fieldSelection.H"
@ -91,12 +91,12 @@ class fileFieldSelection
) const; ) const;
//- No copy construct
fileFieldSelection(const fileFieldSelection&) = delete;
public: public:
//- No copy construct
fileFieldSelection(const fileFieldSelection&) = delete;
// Constructors // Constructors
//- Construct from object registry //- Construct from object registry

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -69,11 +69,8 @@ bool Foam::functionObjects::solverFieldSelection::updateSelection()
{ {
if (fi.name().match(solvedField)) if (fi.name().match(solvedField))
{ {
newSelection.append fi.found(true);
( newSelection.emplace_back(wordRe(solvedField), fi.component());
fieldInfo(wordRe(solvedField), fi.component())
);
fi.found() = true;
} }
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_solverFieldSelection_H #ifndef Foam_functionObjects_solverFieldSelection_H
#define functionObjects_solverFieldSelection_H #define Foam_functionObjects_solverFieldSelection_H
#include "fieldSelection.H" #include "fieldSelection.H"
@ -54,18 +54,14 @@ class solverFieldSelection
: :
public fieldSelection public fieldSelection
{ {
private:
// Private Member Functions
//- No copy construct
solverFieldSelection(const solverFieldSelection&) = delete;
public: public:
//- No copy construct
solverFieldSelection(const solverFieldSelection&) = delete;
//- Construct from object registry //- Construct from object registry
solverFieldSelection explicit solverFieldSelection
( (
const objectRegistry& obr, const objectRegistry& obr,
const bool includeComponents = false const bool includeComponents = false

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_volFieldSelection_H #ifndef Foam_functionObjects_volFieldSelection_H
#define functionObjects_volFieldSelection_H #define Foam_functionObjects_volFieldSelection_H
#include "fieldSelection.H" #include "fieldSelection.H"
@ -54,14 +54,6 @@ class volFieldSelection
: :
public fieldSelection public fieldSelection
{ {
private:
// Private Member Functions
//- No copy construct
volFieldSelection(const volFieldSelection&) = delete;
protected: protected:
// Protected Member Functions // Protected Member Functions
@ -73,8 +65,12 @@ protected:
public: public:
//- No copy construct
volFieldSelection(const volFieldSelection&) = delete;
//- Construct from object registry //- Construct from object registry
volFieldSelection explicit volFieldSelection
( (
const objectRegistry& obr, const objectRegistry& obr,
const bool includeComponents = false const bool includeComponents = false

View File

@ -157,11 +157,13 @@ bool Foam::functionObjects::limitFields::execute()
{ {
fieldSet_.updateSelection(); fieldSet_.updateSelection();
Log << type() << " " << name() << ":" << nl; Log << type() << ' ' << name() << ':' << nl;
label count = 0, total = 0;
label count = 0;
for (const word& fieldName : fieldSet_.selectionNames()) for (const word& fieldName : fieldSet_.selectionNames())
{ {
++total;
if if
( (
limitScalarField(fieldName) limitScalarField(fieldName)
@ -177,8 +179,7 @@ bool Foam::functionObjects::limitFields::execute()
if (debug) if (debug)
{ {
Log << " - limited " << count << '/' Log << " - limited " << count << '/' << total << " fields";
<< fieldSet_.selectionNames().size() << " fields";
} }
Log << endl; Log << endl;