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

View File

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

View File

@ -37,27 +37,28 @@ Foam::functionObjects::fieldSelection::fieldSelection
const bool includeComponents
)
:
List<fieldInfo>(),
obr_(obr),
includeComponents_(includeComponents),
selection_()
includeComponents_(includeComponents)
{}
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 string::size_type len(cmptStr.size());
static std::string cmptStr(".component(");
static std::string::size_type len(cmptStr.size());
DynamicList<fieldInfo> nameAndComponent(names.size());
for (const wordRe& name : names)
{
string::size_type n = name.find(cmptStr);
if (n != string::npos)
const auto n = name.find(cmptStr);
if (n != std::string::npos)
{
// Field should be written <field>.component(i)
@ -76,12 +77,12 @@ bool Foam::functionObjects::fieldSelection::resetFieldFilters
<< exit(FatalError);
}
word baseName = name.substr(0, n);
const word baseName(name.substr(0, n));
// 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
<< "Invalid field component specification for "
@ -90,18 +91,18 @@ bool Foam::functionObjects::fieldSelection::resetFieldFilters
<< exit(FatalError);
}
string::size_type cmptWidth = closei - n - len;
const auto cmptWidth = (closei - n - len);
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
{
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
(
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)
{
HashSet<wordRe> fields(dict.lookup("fields"));
HashSet<wordRe> fields(0);
dict.readEntry("fields", fields);
return resetFieldFilters(fields);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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