From b8c3dc4e496fe51ed70e6625c98a9d85d9aa0346 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Fri, 4 Mar 2022 15:46:04 +0100 Subject: [PATCH] ENH: selection mechanism for cloudInfo function object (#2390) - can restrict calculation of D32 and other spray properties to a subset of parcels. Uses a predicate selection mechanism similar to vtkCloud etc. ENH: code cleanup in scalar predicates - pass by value not reference in predicates - additional assign() method to refactor common code --- .../predicates/scalar/scalarPredicates.C | 122 ++++++------ .../predicates/scalar/scalarPredicates.H | 20 +- .../predicates/scalar/scalarPredicatesI.H | 12 +- .../lagrangian/cloudInfo/cloudInfo.C | 187 +++++++++++++++--- .../lagrangian/cloudInfo/cloudInfo.H | 38 +++- 5 files changed, 272 insertions(+), 107 deletions(-) diff --git a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C index 0be0a0400a..04d1ba7953 100644 --- a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C +++ b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -182,30 +182,8 @@ Foam::predicates::scalars::scalars ( std::initializer_list> entries ) -: - List(entries.size()) { - // Access - const auto get0 = - [](const std::pair& entry) { return entry.first; }; - const auto get1 = - [](const std::pair& entry) { return entry.second; }; - - // Check for bad/unknown operations - if (hasBadEntries(entries, get0)) - { - printBadEntries(FatalErrorInFunction, entries, get0, get1) - << exit(FatalError); - } - - // Appears to be good - auto& list = *this; - label idx = 0; - for (const auto& entry : entries) - { - list[idx] = predicates::scalars::operation(entry); - ++idx; - } + assign(entries); } @@ -213,14 +191,29 @@ Foam::predicates::scalars::scalars ( const UList>& entries ) -: - List(entries.size()) { + assign(entries); +} + + +Foam::predicates::scalars::scalars(Istream& is) +{ + is >> *this; +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::predicates::scalars::assign +( + std::initializer_list> entries +) +{ + typedef std::pair tuple_type; + // Access - const auto get0 = - [](const Tuple2& entry) { return entry.first(); }; - const auto get1 = - [](const Tuple2& entry) { return entry.second(); }; + const auto get0 = [](const tuple_type& entry) { return entry.first; }; + const auto get1 = [](const tuple_type& entry) { return entry.second; }; // Check for bad/unknown operations if (hasBadEntries(entries, get0)) @@ -229,27 +222,48 @@ Foam::predicates::scalars::scalars << exit(FatalError); } - // Appears to be good - auto& list = *this; - label idx = 0; - for (const auto& entry : entries) + // Appears to be good, fill the list + this->resize_nocopy(entries.size()); + auto iter = this->begin(); + + for (const tuple_type& entry : entries) { - list[idx] = predicates::scalars::operation(entry); - ++idx; + *iter = predicates::scalars::operation(entry); + ++iter; } } -Foam::predicates::scalars::scalars(Istream& is) -: - List() +void Foam::predicates::scalars::assign +( + const UList>& entries +) { - is >> *this; + typedef Tuple2 tuple_type; + + // Access + const auto get0 = [](const tuple_type& entry) { return entry.first(); }; + const auto get1 = [](const tuple_type& entry) { return entry.second(); }; + + // Check for bad/unknown operations + if (hasBadEntries(entries, get0)) + { + printBadEntries(FatalErrorInFunction, entries, get0, get1) + << exit(FatalError); + } + + // Appears to be good, fill the list + this->resize_nocopy(entries.size()); + auto iter = this->begin(); + + for (const tuple_type& entry : entries) + { + *iter = predicates::scalars::operation(entry); + ++iter; + } } -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - Foam::label Foam::predicates::scalars::find ( const scalar value, @@ -310,29 +324,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Foam::predicates::scalars& list) // Read tuples List> entries(is); - // Access - const auto get0 = - [](const Tuple2& entry) { return entry.first(); }; - const auto get1 = - [](const Tuple2& entry) { return entry.second(); }; - - - // Check for bad/unknown operations - if (hasBadEntries(entries, get0)) - { - printBadEntries(FatalIOErrorInFunction(is), entries, get0, get1) - << exit(FatalIOError); - } - - // Appears to be good - list.resize(entries.size()); - - label idx = 0; - for (const Tuple2& entry : entries) - { - list[idx] = predicates::scalars::operation(entry); - ++idx; - } + list.assign(entries); return is; } diff --git a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H index 4a135f05e0..15e8ed5b4b 100644 --- a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H +++ b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -256,6 +256,14 @@ public: // Member Functions + //- Assign new predicates from an initializer list of + //- (opName opValue) tuples + void assign(std::initializer_list> entries); + + //- Assign new predicates from a list of (opName opValue) tuples + void assign(const UList>& entries); + + // Search //- Index of the first match for the value. @@ -279,23 +287,23 @@ public: //- Match any condition in the list. // // \return True if the value matches any condition in the list. - inline bool match(const scalar& value) const; + inline bool match(const scalar value) const; //- Match any condition in the list. // // \return True if the value matches any condition in the list. - inline bool matchAny(const scalar& value) const; + inline bool matchAny(const scalar value) const; //- Match all conditions in the list. // // \return True if the value matches all conditions in the list. - inline bool matchAll(const scalar& value) const; + inline bool matchAll(const scalar value) const; //- Extract list indices for all matches. // // \return The locations (indices) in the input list where match() // is true - inline labelList matching(const scalar& value) const; + inline labelList matching(const scalar value) const; //- Extract list indices for all matches. // @@ -313,7 +321,7 @@ public: // Member Operators //- Identical to found(), match(), for use as a predicate. - inline bool operator()(const scalar& value) const; + inline bool operator()(const scalar value) const; }; diff --git a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H index 207fe59de5..2275d29cdc 100644 --- a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H +++ b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -70,13 +70,13 @@ inline bool Foam::predicates::scalars::found } -inline bool Foam::predicates::scalars::match(const scalar& value) const +inline bool Foam::predicates::scalars::match(const scalar value) const { return this->matchAny(value); } -inline bool Foam::predicates::scalars::matchAny(const scalar& value) const +inline bool Foam::predicates::scalars::matchAny(const scalar value) const { for (const unary& test : *this) { @@ -90,7 +90,7 @@ inline bool Foam::predicates::scalars::matchAny(const scalar& value) const } -inline bool Foam::predicates::scalars::matchAll(const scalar& value) const +inline bool Foam::predicates::scalars::matchAll(const scalar value) const { for (const unary& test : *this) { @@ -106,7 +106,7 @@ inline bool Foam::predicates::scalars::matchAll(const scalar& value) const inline Foam::labelList Foam::predicates::scalars::matching ( - const scalar& value + const scalar value ) const { labelList indices(this->size()); @@ -154,7 +154,7 @@ inline Foam::labelList Foam::predicates::scalars::matching // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // -inline bool Foam::predicates::scalars::operator()(const scalar& value) const +inline bool Foam::predicates::scalars::operator()(const scalar value) const { return this->found(value); } diff --git a/src/functionObjects/lagrangian/cloudInfo/cloudInfo.C b/src/functionObjects/lagrangian/cloudInfo/cloudInfo.C index 72e2524878..ae81784e44 100644 --- a/src/functionObjects/lagrangian/cloudInfo/cloudInfo.C +++ b/src/functionObjects/lagrangian/cloudInfo/cloudInfo.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015 OpenCFD Ltd. + Copyright (C) 2015-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,8 +27,10 @@ License \*---------------------------------------------------------------------------*/ #include "cloudInfo.H" +#include "cloud.H" #include "kinematicCloud.H" #include "dictionary.H" +#include "mathematicalConstants.H" #include "PstreamReduceOps.H" #include "addToRunTimeSelectionTable.H" @@ -74,8 +76,10 @@ Foam::functionObjects::cloudInfo::cloudInfo const dictionary& dict ) : - regionFunctionObject(name, runTime, dict), - logFiles(obr_, name, dict) + functionObjects::regionFunctionObject(name, runTime, dict), + functionObjects::logFiles(obr_, name, dict), + verbose_(false), + onExecute_(false) { read(dict); } @@ -85,55 +89,175 @@ Foam::functionObjects::cloudInfo::cloudInfo bool Foam::functionObjects::cloudInfo::read(const dictionary& dict) { + parcelSelect_.clear(); + verbose_ = false; + onExecute_ = false; + if (regionFunctionObject::read(dict) && logFiles::read(dict)) { logFiles::resetNames(dict.get("clouds")); Info<< type() << " " << name() << ": "; - if (writeToFile() && names().size()) + if (names().size()) { Info<< "applying to clouds:" << nl; - forAll(names(), cloudi) + for (const word& cldName : names()) { - Info<< " " << names()[cloudi] << nl; - writeFileHeader(files(cloudi)); + Info<< " " << cldName << nl; } Info<< endl; + + // Actions to define selection + parcelSelect_ = dict.subOrEmptyDict("selection"); + + verbose_ = dict.getOrDefault("verbose", false); + onExecute_ = dict.getOrDefault("sampleOnExecute", false); } else { Info<< "no clouds to be processed" << nl << endl; } + + if (writeToFile()) + { + forAll(names(), cloudi) + { + writeFileHeader(files(cloudi)); + } + } } return true; } -bool Foam::functionObjects::cloudInfo::execute() +bool Foam::functionObjects::cloudInfo::performAction(unsigned request) { - return true; -} + if (!request || names().empty()) + { + return true; + } - -bool Foam::functionObjects::cloudInfo::write() -{ forAll(names(), cloudi) { + // The reported quantities + label nTotParcels = 0; + scalar totMass = 0, Dmax = 0, D10 = 0, D32 = 0; + bool applyFilter = false; + const word& cloudName = names()[cloudi]; - const kinematicCloud& cloud = - obr_.lookupObject(cloudName); + const auto* kinCloudPtr = obr_.cfindObject(cloudName); - const label nTotParcels = - returnReduce(cloud.nParcels(), sumOp