mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support scalar predicates and lists of scalar predicates (#1056)
This commit is contained in:
3
applications/test/scalarPredicates/Make/files
Normal file
3
applications/test/scalarPredicates/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-scalarPredicates.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-scalarPredicates
|
||||||
1
applications/test/scalarPredicates/Make/options
Normal file
1
applications/test/scalarPredicates/Make/options
Normal file
@ -0,0 +1 @@
|
|||||||
|
/**/
|
||||||
158
applications/test/scalarPredicates/Test-scalarPredicates.C
Normal file
158
applications/test/scalarPredicates/Test-scalarPredicates.C
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
Test-scalarPredicates
|
||||||
|
|
||||||
|
Description
|
||||||
|
Simple tests using predicates for scalars
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "IOstreams.H"
|
||||||
|
#include "labelList.H"
|
||||||
|
#include "scalarList.H"
|
||||||
|
#include "scalarPredicates.H"
|
||||||
|
#include "FlatOutput.H"
|
||||||
|
#include "Tuple2.H"
|
||||||
|
#include "StringStream.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
|
||||||
|
void doTest(const scalarList& values, const predicates::scalars& accept)
|
||||||
|
{
|
||||||
|
// Also tests that output is suppressed
|
||||||
|
Info<<"Have: " << accept.size() << " predicates" << accept << endl;
|
||||||
|
Info<<"values: " << flatOutput(values) << endl;
|
||||||
|
|
||||||
|
for (const scalar& value : values)
|
||||||
|
{
|
||||||
|
if (accept.match(value))
|
||||||
|
{
|
||||||
|
Info<< "matched: " << value << " at "
|
||||||
|
<< flatOutput(accept.matching(value)) << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList matches = accept.matching(values);
|
||||||
|
Info<< "values matched at positions: " << flatOutput(matches) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
scalarList values
|
||||||
|
({
|
||||||
|
-10,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
3.145,
|
||||||
|
1000.56,
|
||||||
|
1e5,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Info<< nl << "From a mixed list of entries" << nl;
|
||||||
|
{
|
||||||
|
predicates::scalars
|
||||||
|
accept
|
||||||
|
({
|
||||||
|
predicates::scalars::lessOp(10),
|
||||||
|
predicates::scalars::greaterOp(100),
|
||||||
|
predicates::scalars::orOp
|
||||||
|
(
|
||||||
|
predicates::scalars::lessOp(-5),
|
||||||
|
predicates::scalars::greaterOp(100)
|
||||||
|
),
|
||||||
|
predicates::scalars::orOp
|
||||||
|
(
|
||||||
|
[](const scalar& val){ return val < 5; },
|
||||||
|
predicates::scalars::greaterOp(100)
|
||||||
|
),
|
||||||
|
|
||||||
|
[](const scalar& val){ return val < -8; },
|
||||||
|
|
||||||
|
// Rather wordy, word normally not be called manually
|
||||||
|
predicates::scalars::operation("le", -9),
|
||||||
|
});
|
||||||
|
|
||||||
|
doTest(values, accept);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Info<< nl << "Construct from list input" << nl;
|
||||||
|
{
|
||||||
|
List<Tuple2<word, scalar>> entries
|
||||||
|
({
|
||||||
|
{"less", 10},
|
||||||
|
{"greater", 100},
|
||||||
|
// Not possible > ((less -5) or (greater 100))
|
||||||
|
{"less", -8},
|
||||||
|
{"le", -9},
|
||||||
|
});
|
||||||
|
|
||||||
|
predicates::scalars accept(entries);
|
||||||
|
|
||||||
|
doTest(values, accept);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl << "Construct from initializer_list input" << nl;
|
||||||
|
{
|
||||||
|
predicates::scalars accept
|
||||||
|
({
|
||||||
|
{"less", 10},
|
||||||
|
{"greater", 100},
|
||||||
|
// Not possible > ((less -5) or (greater 100))
|
||||||
|
{"less", -8},
|
||||||
|
{"le", -9},
|
||||||
|
});
|
||||||
|
|
||||||
|
doTest(values, accept);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl << "Construct from Istream" << nl;
|
||||||
|
{
|
||||||
|
IStringStream is("((less 10) (greater 100) (less -8) (le -9))");
|
||||||
|
predicates::scalars accept(is);
|
||||||
|
|
||||||
|
doTest(values, accept);
|
||||||
|
|
||||||
|
// change some location
|
||||||
|
accept[0] = predicates::scalars::greaterOp(1000);
|
||||||
|
|
||||||
|
Info<< nl << "Reset some values" << nl;
|
||||||
|
doTest(values, accept);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -123,6 +123,8 @@ $(strings)/parsing/parsing.C
|
|||||||
ops = primitives/ops
|
ops = primitives/ops
|
||||||
$(ops)/flipOp.C
|
$(ops)/flipOp.C
|
||||||
|
|
||||||
|
primitives/predicates/scalar/scalarPredicates.C
|
||||||
|
|
||||||
primitives/hashes/Hasher/Hasher.C
|
primitives/hashes/Hasher/Hasher.C
|
||||||
|
|
||||||
sha1 = primitives/hashes/SHA1
|
sha1 = primitives/hashes/SHA1
|
||||||
|
|||||||
332
src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C
Normal file
332
src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "scalarPredicates.H"
|
||||||
|
#include "HashSet.H"
|
||||||
|
#include "FlatOutput.H"
|
||||||
|
#include "Tuple2.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::Enum
|
||||||
|
<
|
||||||
|
Foam::predicates::scalars::opType
|
||||||
|
>
|
||||||
|
Foam::predicates::scalars::opNames
|
||||||
|
({
|
||||||
|
{ opType::EQUAL, "eq" },
|
||||||
|
{ opType::EQUAL, "equal" },
|
||||||
|
{ opType::NOT_EQUAL, "neq" },
|
||||||
|
{ opType::NOT_EQUAL, "notEqual" },
|
||||||
|
{ opType::LESS, "lt" },
|
||||||
|
{ opType::LESS, "less" },
|
||||||
|
{ opType::LESS_EQ, "le" },
|
||||||
|
{ opType::LESS_EQ, "lessEq" },
|
||||||
|
{ opType::GREATER, "gt" },
|
||||||
|
{ opType::GREATER, "greater" },
|
||||||
|
{ opType::GREATER_EQ, "ge" },
|
||||||
|
{ opType::GREATER_EQ, "greaterEq" },
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
std::function<bool(Foam::scalar)> Foam::predicates::scalars::operation
|
||||||
|
(
|
||||||
|
const enum predicates::scalars::opType op,
|
||||||
|
const Foam::scalar opVal,
|
||||||
|
const Foam::scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case opType::EQUAL:
|
||||||
|
return equalOp(opVal, tol);
|
||||||
|
break;
|
||||||
|
case opType::NOT_EQUAL:
|
||||||
|
return notEqualOp(opVal, tol);
|
||||||
|
break;
|
||||||
|
case opType::LESS:
|
||||||
|
return lessOp(opVal);
|
||||||
|
break;
|
||||||
|
case opType::LESS_EQ:
|
||||||
|
return lessEqOp(opVal);
|
||||||
|
break;
|
||||||
|
case opType::GREATER:
|
||||||
|
return greaterOp(opVal);
|
||||||
|
break;
|
||||||
|
case opType::GREATER_EQ:
|
||||||
|
return greaterEqOp(opVal);
|
||||||
|
break;
|
||||||
|
case opType::ALWAYS:
|
||||||
|
return trueOp();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return falseOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
// Check for bad/unknown operations
|
||||||
|
template<class Container, class Get0>
|
||||||
|
static bool hasBadEntries
|
||||||
|
(
|
||||||
|
const Container& entries,
|
||||||
|
const Get0& get0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (const auto& entry : entries)
|
||||||
|
{
|
||||||
|
if (!Foam::predicates::scalars::opNames.found(get0(entry)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Print bad/unknown operations
|
||||||
|
template<class Error, class Container, class Get0, class Get1>
|
||||||
|
static Error& printBadEntries
|
||||||
|
(
|
||||||
|
Error& err,
|
||||||
|
const Container& entries,
|
||||||
|
const Get0& get0,
|
||||||
|
const Get1& get1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
labelHashSet badIndices;
|
||||||
|
|
||||||
|
label idx = 0;
|
||||||
|
|
||||||
|
for (const auto& entry : entries)
|
||||||
|
{
|
||||||
|
if (!Foam::predicates::scalars::opNames.found(get0(entry)))
|
||||||
|
{
|
||||||
|
badIndices.insert(idx);
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
err
|
||||||
|
<< "Entries with unknown operations:" << nl
|
||||||
|
<< idx << nl
|
||||||
|
<< '(' << nl;
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
for (const auto& entry : entries)
|
||||||
|
{
|
||||||
|
const bool bad = badIndices.found(idx);
|
||||||
|
++idx;
|
||||||
|
|
||||||
|
if (bad)
|
||||||
|
{
|
||||||
|
err << ">>> ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err << " ";
|
||||||
|
}
|
||||||
|
err << '(' << get0(entry) << ' ' << get1(entry) << ')';
|
||||||
|
|
||||||
|
if (bad)
|
||||||
|
{
|
||||||
|
err << " <<<";
|
||||||
|
}
|
||||||
|
err << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
err << ')' << nl;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::predicates::scalars::scalars
|
||||||
|
(
|
||||||
|
std::initializer_list<std::pair<word, scalar>> entries
|
||||||
|
)
|
||||||
|
:
|
||||||
|
List<unary>(entries.size())
|
||||||
|
{
|
||||||
|
// Access
|
||||||
|
const auto get0 =
|
||||||
|
[](const std::pair<word,scalar>& entry) { return entry.first; };
|
||||||
|
const auto get1 =
|
||||||
|
[](const std::pair<word,scalar>& 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::predicates::scalars::scalars
|
||||||
|
(
|
||||||
|
const UList<Tuple2<word, scalar>>& entries
|
||||||
|
)
|
||||||
|
:
|
||||||
|
List<unary>(entries.size())
|
||||||
|
{
|
||||||
|
// Access
|
||||||
|
const auto get0 =
|
||||||
|
[](const Tuple2<word,scalar>& entry) { return entry.first(); };
|
||||||
|
const auto get1 =
|
||||||
|
[](const Tuple2<word,scalar>& 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::predicates::scalars::scalars(Istream& is)
|
||||||
|
:
|
||||||
|
List<unary>()
|
||||||
|
{
|
||||||
|
is >> *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::predicates::scalars::find
|
||||||
|
(
|
||||||
|
const scalar& value,
|
||||||
|
const label start
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const label len = this->size();
|
||||||
|
|
||||||
|
if (start >= 0 && len)
|
||||||
|
{
|
||||||
|
// auto iter = this->cbegin();
|
||||||
|
|
||||||
|
for (label i = start; i < len; ++i)
|
||||||
|
{
|
||||||
|
if ((*this)[i](value))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::predicates::scalars::rfind
|
||||||
|
(
|
||||||
|
const scalar& value,
|
||||||
|
const label pos
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const label len1 = (this->size()-1);
|
||||||
|
|
||||||
|
// pos == -1 has same meaning as std::string::npos - search from end
|
||||||
|
for (label i = ((pos >= 0 && pos < len1) ? pos : len1); i >= 0; --i)
|
||||||
|
{
|
||||||
|
if ((*this)[i](value))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::Istream& Foam::operator>>(Istream& is, Foam::predicates::scalars& list)
|
||||||
|
{
|
||||||
|
// Read tuples
|
||||||
|
List<Tuple2<word, scalar>> entries(is);
|
||||||
|
|
||||||
|
// Access
|
||||||
|
const auto get0 =
|
||||||
|
[](const Tuple2<word,scalar>& entry) { return entry.first(); };
|
||||||
|
const auto get1 =
|
||||||
|
[](const Tuple2<word,scalar>& 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<word, scalar>& entry : entries)
|
||||||
|
{
|
||||||
|
list[idx] = predicates::scalars::operation(entry);
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
341
src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H
Normal file
341
src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::predicates::scalars
|
||||||
|
|
||||||
|
Description
|
||||||
|
A list of unary predicates (tests) on scalars.
|
||||||
|
Includes a number of standard comparison predicates
|
||||||
|
(eg, "less", "greater", ...)
|
||||||
|
|
||||||
|
Note
|
||||||
|
This class is still subject to larger changes (2018-11) as it matures.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
scalarPredicates.C
|
||||||
|
scalarPredicatesI.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef scalarPredicates_H
|
||||||
|
#define scalarPredicates_H
|
||||||
|
|
||||||
|
#include "scalar.H"
|
||||||
|
#include "predicates.H"
|
||||||
|
#include "Enum.H"
|
||||||
|
#include "List.H"
|
||||||
|
#include "Tuple2.H"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace predicates
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class scalars Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class scalars
|
||||||
|
:
|
||||||
|
public List<std::function<bool(Foam::scalar)>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public types
|
||||||
|
|
||||||
|
//- The unary function type for testing a scalar
|
||||||
|
typedef std::function<bool(Foam::scalar)> unary;
|
||||||
|
|
||||||
|
//- Enumerations for some standard comparison predicates
|
||||||
|
enum opType
|
||||||
|
{
|
||||||
|
EQUAL, //!< "eq", "equal"
|
||||||
|
NOT_EQUAL, //!< "neq", "notEqual"
|
||||||
|
LESS, //!< "lt", "less"
|
||||||
|
LESS_EQ, //!< "le", "lessEq"
|
||||||
|
GREATER, //!< "gt", "greater"
|
||||||
|
GREATER_EQ, //!< "ge", "greaterEq"
|
||||||
|
ALWAYS, //!< Always matches
|
||||||
|
NEVER, //!< Never matches
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Names for the opType enumeration.
|
||||||
|
static const Enum<opType> opNames;
|
||||||
|
|
||||||
|
|
||||||
|
// Standard comparison methods
|
||||||
|
|
||||||
|
//- Compare for equality, with specified tolerance (non-negative)
|
||||||
|
static unary equalOp
|
||||||
|
(
|
||||||
|
const scalar opVal,
|
||||||
|
const scalar tol = VSMALL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return [=](const scalar val)
|
||||||
|
{
|
||||||
|
return (Foam::mag(opVal - val) <= tol);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Compare for inequality, with specified tolerance (non-negative)
|
||||||
|
static unary notEqualOp
|
||||||
|
(
|
||||||
|
const scalar opVal,
|
||||||
|
const scalar tol = VSMALL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return [=](const scalar val)
|
||||||
|
{
|
||||||
|
return (Foam::mag(opVal - val) > tol);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Test if value is 'less' than prescribed
|
||||||
|
static unary lessOp(const scalar opVal)
|
||||||
|
{
|
||||||
|
return std::bind
|
||||||
|
(
|
||||||
|
std::less<scalar>(), std::placeholders::_1, opVal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Test if value is 'less_equal' to prescribed
|
||||||
|
static unary lessEqOp(const scalar opVal)
|
||||||
|
{
|
||||||
|
return std::bind
|
||||||
|
(
|
||||||
|
std::less_equal<scalar>(), std::placeholders::_1, opVal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Test if value is 'greater' than prescribed
|
||||||
|
//- Compare scalar values for inequality
|
||||||
|
static unary greaterOp(const scalar opVal)
|
||||||
|
{
|
||||||
|
return std::bind
|
||||||
|
(
|
||||||
|
std::greater<scalar>(), std::placeholders::_1, opVal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Test if value is 'greater_equal' to prescribed
|
||||||
|
static unary greaterEqOp(const scalar opVal)
|
||||||
|
{
|
||||||
|
return std::bind
|
||||||
|
(
|
||||||
|
std::greater_equal<scalar>(), std::placeholders::_1, opVal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Special purpose comparison methods
|
||||||
|
|
||||||
|
//- Predicate that always returns true
|
||||||
|
static unary trueOp()
|
||||||
|
{
|
||||||
|
return [](const scalar) { return true; };
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Predicate that always returns false
|
||||||
|
static unary falseOp()
|
||||||
|
{
|
||||||
|
return [](const scalar) { return false; };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Combining operations
|
||||||
|
|
||||||
|
//- Combine unary tests as an AND operation
|
||||||
|
static unary andOp(const unary& test1, const unary& test2)
|
||||||
|
{
|
||||||
|
return [=](const scalar value)
|
||||||
|
{
|
||||||
|
return (test1(value) && test2(value));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Combine unary tests as an OR operation
|
||||||
|
static unary orOp(const unary& test1, const unary& test2)
|
||||||
|
{
|
||||||
|
return [=](const scalar value)
|
||||||
|
{
|
||||||
|
return (test1(value) || test2(value));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Factory for standard comparison methods
|
||||||
|
|
||||||
|
//- Standard comparison method by type
|
||||||
|
static unary operation
|
||||||
|
(
|
||||||
|
const opType op,
|
||||||
|
const scalar opVal,
|
||||||
|
const scalar tol = VSMALL
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Standard comparison method by name
|
||||||
|
inline static unary operation
|
||||||
|
(
|
||||||
|
const word& opName,
|
||||||
|
const scalar opVal,
|
||||||
|
const scalar tol = VSMALL
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Standard comparison method by (name, value)
|
||||||
|
inline static unary operation
|
||||||
|
(
|
||||||
|
const Tuple2<word, scalar>& op,
|
||||||
|
const scalar tol = VSMALL
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Standard comparison method by (name, value)
|
||||||
|
inline static unary operation
|
||||||
|
(
|
||||||
|
const std::pair<word, scalar>& op,
|
||||||
|
const scalar tol = VSMALL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Inherit constructors from List of unary functions
|
||||||
|
using List<unary>::List;
|
||||||
|
|
||||||
|
//- Construct from an initializer list of (opName opValue) tuples
|
||||||
|
explicit scalars(std::initializer_list<std::pair<word, scalar>> entries);
|
||||||
|
|
||||||
|
//- Copy construct from a list of (opName opValue) tuples
|
||||||
|
explicit scalars(const UList<Tuple2<word, scalar>>& entries);
|
||||||
|
|
||||||
|
//- Construct from Istream, from list of (opName opValue) tuples
|
||||||
|
explicit scalars(Istream& is);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~scalars() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Search
|
||||||
|
|
||||||
|
//- Index of the first match for the value.
|
||||||
|
// When start is specified, any occurrences before start are ignored.
|
||||||
|
// Linear search.
|
||||||
|
// \return position in list or -1 if not found.
|
||||||
|
label find(const scalar& value, const label start=0) const;
|
||||||
|
|
||||||
|
//- Index of the last match for the value.
|
||||||
|
// When pos is specified, any occurrences after pos are ignored.
|
||||||
|
// Linear search.
|
||||||
|
// \return position in list or -1 if not found.
|
||||||
|
label rfind(const scalar& value, const label pos=-1) const;
|
||||||
|
|
||||||
|
//- True if the value matches any in the list.
|
||||||
|
// When start is specified, any occurences before start are ignored.
|
||||||
|
// Linear search.
|
||||||
|
// \return true if found.
|
||||||
|
inline bool found(const scalar& value, const label start=0) const;
|
||||||
|
|
||||||
|
//- Match any condition in the list.
|
||||||
|
//
|
||||||
|
// \return True if the value matches any condition in the list.
|
||||||
|
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;
|
||||||
|
|
||||||
|
//- Match all conditions in the list.
|
||||||
|
//
|
||||||
|
// \return True if the value matches all conditions in the list.
|
||||||
|
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;
|
||||||
|
|
||||||
|
//- Extract list indices for all matches.
|
||||||
|
//
|
||||||
|
// \param input A list of scalar inputs to test
|
||||||
|
// \param invert invert the matching logic
|
||||||
|
// \return The locations (indices) in the input list where match()
|
||||||
|
// is true
|
||||||
|
inline labelList matching
|
||||||
|
(
|
||||||
|
const UList<scalar>& input,
|
||||||
|
const bool invert=false
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
//- Identical to found(), match(), for use as a predicate.
|
||||||
|
inline bool operator()(const scalar& value) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace predicates
|
||||||
|
|
||||||
|
|
||||||
|
// IOstream Operators
|
||||||
|
|
||||||
|
//- Suppressed write
|
||||||
|
Ostream& operator<<(Ostream& os, const predicates::scalars& list)
|
||||||
|
{
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Read list of (opName opValue) tuple
|
||||||
|
Istream& operator>>(Istream& is, predicates::scalars& list);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "scalarPredicatesI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
161
src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H
Normal file
161
src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline Foam::predicates::scalars::unary Foam::predicates::scalars::operation
|
||||||
|
(
|
||||||
|
const word& opName,
|
||||||
|
const scalar opVal,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return operation(opNames[opName], opVal, tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::predicates::scalars::unary Foam::predicates::scalars::operation
|
||||||
|
(
|
||||||
|
const Tuple2<word, scalar>& op,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return operation(opNames[op.first()], op.second(), tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::predicates::scalars::unary Foam::predicates::scalars::operation
|
||||||
|
(
|
||||||
|
const std::pair<word, scalar>& op,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return operation(opNames[op.first], op.second, tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::predicates::scalars::found
|
||||||
|
(
|
||||||
|
const scalar& value,
|
||||||
|
const label start
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return (this->find(value, start) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::predicates::scalars::match(const scalar& value) const
|
||||||
|
{
|
||||||
|
return this->matchAny(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::predicates::scalars::matchAny(const scalar& value) const
|
||||||
|
{
|
||||||
|
for (const unary& test : *this)
|
||||||
|
{
|
||||||
|
if (test(value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::predicates::scalars::matchAll(const scalar& value) const
|
||||||
|
{
|
||||||
|
for (const unary& test : *this)
|
||||||
|
{
|
||||||
|
if (!test(value))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (!this->empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::labelList Foam::predicates::scalars::matching
|
||||||
|
(
|
||||||
|
const scalar& value
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
labelList indices(this->size());
|
||||||
|
|
||||||
|
label i = 0, count = 0;
|
||||||
|
for (const unary& test : *this)
|
||||||
|
{
|
||||||
|
if (test(value))
|
||||||
|
{
|
||||||
|
indices[count] = i;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
indices.resize(count);
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::labelList Foam::predicates::scalars::matching
|
||||||
|
(
|
||||||
|
const UList<scalar>& input,
|
||||||
|
const bool invert
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const label len = input.size();
|
||||||
|
|
||||||
|
labelList indices(len);
|
||||||
|
|
||||||
|
label count = 0;
|
||||||
|
for (label i=0; i < len; ++i)
|
||||||
|
{
|
||||||
|
if (match(input[i]) ? !invert : invert)
|
||||||
|
{
|
||||||
|
indices[count] = i;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indices.resize(count);
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::predicates::scalars::operator()(const scalar& value) const
|
||||||
|
{
|
||||||
|
return this->found(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user