ENH: add dimensionSet provisioning for a dimensioned clip() method

- use file-local function to reduce some code clutter
This commit is contained in:
Mark Olesen
2019-01-09 23:44:17 +01:00
parent d0bb3670a7
commit 7720b59066
5 changed files with 228 additions and 96 deletions

View File

@ -27,7 +27,9 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "dimensionSet.H" #include "dimensionSet.H"
#include "dimensionedScalar.H"
#include "IOmanip.H" #include "IOmanip.H"
#include <tuple>
using namespace Foam; using namespace Foam;
@ -39,6 +41,96 @@ using namespace Foam;
Info<< STRING_QUOTE(arg) << " " << arg << nl Info<< STRING_QUOTE(arg) << " " << arg << nl
bool hadDimensionError
(
const std::tuple<bool, dimensionSet, dimensionSet>& input,
bool dimsOk,
std::string errMsg
)
{
if (dimsOk)
{
if (std::get<0>(input))
{
Info<< "(pass) dimension check ok ";
}
else
{
Info<< "(fail) unexpected success for dimension check ";
}
Info<< std::get<1>(input) << " == " << std::get<2>(input) << nl;
}
else
{
if (std::get<0>(input))
{
Info<< "(fail) unexpected";
}
else
{
Info<< "(pass) expected";
}
Info<< " failure" << nl << errMsg.c_str() << nl;
}
return (std::get<0>(input) != dimsOk);
}
unsigned checkDimensions
(
std::initializer_list
<
std::tuple<bool, dimensionSet, dimensionSet>
> tests
)
{
Info<< nl << "Verify dimension checks" << nl << nl;
unsigned nFail = 0;
std::string errMsg;
// Expect some failures
const bool prev = FatalError.throwExceptions();
for
(
const std::tuple<bool, dimensionSet, dimensionSet>& test
: tests
)
{
const bool expected = std::get<0>(test);
const dimensionSet& a = std::get<1>(test);
const dimensionSet& b = std::get<2>(test);
bool dimsOk = false;
try
{
// min(a, b);
clip(a, b);
dimsOk = true;
}
catch (Foam::error& err)
{
errMsg = err.message();
}
if (expected != dimsOk)
{
++nFail;
}
hadDimensionError(test, dimsOk, errMsg);
}
FatalError.throwExceptions(prev);
return nFail;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -92,6 +184,21 @@ int main(int argc, char *argv[])
} }
unsigned nFail = 0;
nFail += checkDimensions
({
{ true, dimless, dimless },
{ false, dimless, dimPressure }
});
if (nFail)
{
Info<< nl << "failed " << nFail << " tests" << nl;
return 1;
}
Info<< nl << "End\n" << endl; Info<< nl << "End\n" << endl;
return 0; return 0;

View File

@ -47,14 +47,49 @@ inline scalar readNasScalar(const std::string& str)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class TYPE> template<class T>
bool hadParsingError
(
const std::pair<bool, std::string>& input,
const std::pair<bool, T>& result,
std::string errMsg
)
{
if (result.first)
{
if (input.first)
{
Info<< "(pass) parsed "
<< input.second << " = " << result.second << nl;
}
else
{
Info<< "(fail) unexpected success for " << input.second << nl;
}
}
else
{
if (input.first)
{
Info<< "(fail) unexpected";
}
else
{
Info<< "(pass) expected";
}
Info<< " failure " << input.second << " >> " << errMsg.c_str() << nl;
}
return (input.first != result.first);
}
template<class T>
unsigned testParsing unsigned testParsing
( (
TYPE (*function)(const std::string&), T (*function)(const std::string&),
std::initializer_list std::initializer_list<std::pair<bool, std::string>> tests
<
Tuple2<bool, std::string>
> tests
) )
{ {
unsigned nFail = 0; unsigned nFail = 0;
@ -63,51 +98,26 @@ unsigned testParsing
// Expect some failures // Expect some failures
const bool prev = FatalIOError.throwExceptions(); const bool prev = FatalIOError.throwExceptions();
for (const Tuple2<bool, std::string>& test : tests) for (const std::pair<bool, std::string>& test : tests)
{ {
const bool expected = test.first(); std::pair<bool, T> result(false, T());
const std::string& str = test.second();
bool parsed = true;
TYPE val;
try try
{ {
val = function (str); result.second = function (test.second);
result.first = true;
} }
catch (Foam::error& err) catch (Foam::error& err)
{ {
parsed = false;
errMsg = err.message(); errMsg = err.message();
} }
if (parsed) if (test.first != result.first)
{ {
if (expected) ++nFail;
{
Info<< "(pass) parsed " << str << " = " << val << nl;
}
else
{
++nFail;
Info<< "(fail) unexpected success for " << str << nl;
}
} }
else
{
if (expected)
{
++nFail;
Info<< "(fail) unexpected";
}
else
{
Info<< "(pass) expected";
}
Info<< " failure " << str hadParsingError(test, result, errMsg);
<< " >> " << errMsg.c_str() << nl;
}
} }
FatalIOError.throwExceptions(prev); FatalIOError.throwExceptions(prev);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2017-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,6 +36,33 @@ namespace Foam
const Foam::scalar Foam::dimensionSet::smallExponent = SMALL; const Foam::scalar Foam::dimensionSet::smallExponent = SMALL;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
static inline bool checkDims
(
const char* what,
const dimensionSet& a,
const dimensionSet& b
)
{
if (a != b)
{
FatalErrorInFunction
<< "Different dimensions for '" << what
<< "'\n dimensions : " << a << " != " << b << nl
<< abort(FatalError);
return false;
}
return true;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dimensionSet::dimensionSet() Foam::dimensionSet::dimensionSet()
@ -166,12 +193,9 @@ bool Foam::dimensionSet::operator!=(const dimensionSet& ds) const
bool Foam::dimensionSet::operator=(const dimensionSet& ds) const bool Foam::dimensionSet::operator=(const dimensionSet& ds) const
{ {
if (dimensionSet::debug && *this != ds) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("(a = b)", *this, ds);
<< "Different dimensions for =" << nl
<< " dimensions : " << *this << " = " << ds << endl
<< abort(FatalError);
} }
return true; return true;
@ -180,12 +204,9 @@ bool Foam::dimensionSet::operator=(const dimensionSet& ds) const
bool Foam::dimensionSet::operator+=(const dimensionSet& ds) const bool Foam::dimensionSet::operator+=(const dimensionSet& ds) const
{ {
if (dimensionSet::debug && *this != ds) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("(a += b)", *this, ds);
<< "Different dimensions for +=" << nl
<< " dimensions : " << *this << " = " << ds << endl
<< abort(FatalError);
} }
return true; return true;
@ -194,12 +215,9 @@ bool Foam::dimensionSet::operator+=(const dimensionSet& ds) const
bool Foam::dimensionSet::operator-=(const dimensionSet& ds) const bool Foam::dimensionSet::operator-=(const dimensionSet& ds) const
{ {
if (dimensionSet::debug && *this != ds) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("(a -= b)", *this, ds);
<< "Different dimensions for -=" << nl
<< " dimensions : " << *this << " = " << ds << endl
<< abort(FatalError);
} }
return true; return true;
@ -226,12 +244,9 @@ bool Foam::dimensionSet::operator/=(const dimensionSet& ds)
Foam::dimensionSet Foam::min(const dimensionSet& ds1, const dimensionSet& ds2) Foam::dimensionSet Foam::min(const dimensionSet& ds1, const dimensionSet& ds2)
{ {
if (dimensionSet::debug && ds1 != ds2) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("min(a, b)", ds1, ds2);
<< "Arguments of min have different dimensions" << nl
<< " dimensions : " << ds1 << " and " << ds2 << endl
<< abort(FatalError);
} }
return ds1; return ds1;
@ -240,12 +255,20 @@ Foam::dimensionSet Foam::min(const dimensionSet& ds1, const dimensionSet& ds2)
Foam::dimensionSet Foam::max(const dimensionSet& ds1, const dimensionSet& ds2) Foam::dimensionSet Foam::max(const dimensionSet& ds1, const dimensionSet& ds2)
{ {
if (dimensionSet::debug && ds1 != ds2) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("max(a, b)", ds1, ds2);
<< "Arguments of max have different dimensions" << nl }
<< " dimensions : " << ds1 << " and " << ds2 << endl
<< abort(FatalError); return ds1;
}
Foam::dimensionSet Foam::clip(const dimensionSet& ds1, const dimensionSet& ds2)
{
if (dimensionSet::debug)
{
checkDims("clip(a, b)", ds1, ds2);
} }
return ds1; return ds1;
@ -464,12 +487,9 @@ Foam::dimensionSet Foam::trans(const dimensionSet& ds)
Foam::dimensionSet Foam::atan2(const dimensionSet& ds1, const dimensionSet& ds2) Foam::dimensionSet Foam::atan2(const dimensionSet& ds1, const dimensionSet& ds2)
{ {
if (dimensionSet::debug && ds1 != ds2) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("atan2(a, b)", ds1, ds2);
<< "Arguments of atan2 have different dimensions" << nl
<< " dimensions : " << ds1 << " and " << ds2 << endl
<< abort(FatalError);
} }
return dimless; return dimless;
@ -508,12 +528,9 @@ Foam::dimensionSet Foam::operator+
const dimensionSet& ds2 const dimensionSet& ds2
) )
{ {
if (dimensionSet::debug && ds1 != ds2) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("(a + b)", ds1, ds2);
<< "LHS and RHS of '+' have different dimensions" << nl
<< " dimensions : " << ds1 << " + " << ds2 << endl
<< abort(FatalError);
} }
return ds1; return ds1;
@ -526,12 +543,9 @@ Foam::dimensionSet Foam::operator-
const dimensionSet& ds2 const dimensionSet& ds2
) )
{ {
if (dimensionSet::debug && ds1 != ds2) if (dimensionSet::debug)
{ {
FatalErrorInFunction checkDims("(a - b)", ds1, ds2);
<< "LHS and RHS of '-' have different dimensions" << nl
<< " dimensions : " << ds1 << " - " << ds2 << endl
<< abort(FatalError);
} }
return ds1; return ds1;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2017-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -70,10 +70,8 @@ public:
// Member Constants // Member Constants
enum //- There are 7 base dimensions
{ static constexpr int nDimensions = 7;
nDimensions = 7 //!< 7 base dimensions
};
//- Enumeration for the dimension exponents //- Enumeration for the dimension exponents
enum dimensionType enum dimensionType
@ -88,8 +86,9 @@ public:
}; };
// Static data members // Static Data Members
//- Tolerance for 'small' exponents, for near-zero rounding
static const scalar smallExponent; static const scalar smallExponent;
@ -216,6 +215,7 @@ public:
//- Return non-const access to the exponents as a list //- Return non-const access to the exponents as a list
FixedList<scalar,7>& values(); FixedList<scalar,7>& values();
//- Copy assign the exponents from the dimensionSet
void reset(const dimensionSet& ds); void reset(const dimensionSet& ds);
@ -291,6 +291,7 @@ Ostream& operator<<(Ostream& os, const dimensionSet& ds);
dimensionSet min(const dimensionSet& ds1, const dimensionSet& ds2); dimensionSet min(const dimensionSet& ds1, const dimensionSet& ds2);
dimensionSet max(const dimensionSet& ds1, const dimensionSet& ds2); dimensionSet max(const dimensionSet& ds1, const dimensionSet& ds2);
dimensionSet clip(const dimensionSet& ds1, const dimensionSet& ds2);
dimensionSet cmptMultiply(const dimensionSet& ds1, const dimensionSet& ds2); dimensionSet cmptMultiply(const dimensionSet& ds1, const dimensionSet& ds2);
dimensionSet cmptDivide(const dimensionSet& ds1, const dimensionSet& ds2); dimensionSet cmptDivide(const dimensionSet& ds1, const dimensionSet& ds2);

View File

@ -421,8 +421,8 @@ Foam::Istream& Foam::dimensionSet::read
if (startToken != token::BEGIN_SQR) if (startToken != token::BEGIN_SQR)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Expected a " << token::BEGIN_SQR << " in dimensionSet" << "Expected a '" << token::BEGIN_SQR << "' in dimensionSet\n"
<< endl << "in stream " << is.info() << "in stream " << is.info() << nl
<< exit(FatalIOError); << exit(FatalIOError);
} }
@ -444,7 +444,7 @@ Foam::Istream& Foam::dimensionSet::read
{ {
// Read first five dimensions // Read first five dimensions
exponents_[dimensionSet::MASS] = nextToken.number(); exponents_[dimensionSet::MASS] = nextToken.number();
for (int d=1; d<dimensionSet::CURRENT; ++d) for (int d=1; d < dimensionSet::CURRENT; ++d)
{ {
is >> exponents_[d]; is >> exponents_[d];
} }
@ -472,8 +472,8 @@ Foam::Istream& Foam::dimensionSet::read
if (nextToken != token::END_SQR) if (nextToken != token::END_SQR)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Expected a " << token::END_SQR << " in dimensionSet " << "Expected a '" << token::END_SQR << "' in dimensionSet\n"
<< endl << "in stream " << is.info() << "in stream " << is.info() << nl
<< exit(FatalIOError); << exit(FatalIOError);
} }
} }
@ -508,8 +508,8 @@ Foam::Istream& Foam::dimensionSet::read
if (startToken != token::BEGIN_SQR) if (startToken != token::BEGIN_SQR)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Expected a " << token::BEGIN_SQR << " in dimensionSet" << "Expected a '" << token::BEGIN_SQR << "' in dimensionSet\n"
<< endl << "in stream " << is.info() << "in stream " << is.info() << nl
<< exit(FatalIOError); << exit(FatalIOError);
} }
@ -606,8 +606,8 @@ Foam::Istream& Foam::dimensionSet::read
if (nextToken != token::END_SQR) if (nextToken != token::END_SQR)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Expected a " << token::END_SQR << " in dimensionSet " << nl << "Expected a '" << token::END_SQR << "' in dimensionSet\n"
<< "in stream " << is.info() << endl << "in stream " << is.info() << nl
<< exit(FatalIOError); << exit(FatalIOError);
} }
} }
@ -631,7 +631,7 @@ Foam::Ostream& Foam::dimensionSet::write
if (writeUnits.valid() && os.format() == IOstream::ASCII) if (writeUnits.valid() && os.format() == IOstream::ASCII)
{ {
scalarField exponents(dimensionSet::nDimensions); scalarField exponents(dimensionSet::nDimensions);
for (int d=0; d<dimensionSet::nDimensions; ++d) for (int d=0; d < dimensionSet::nDimensions; ++d)
{ {
exponents[d] = exponents_[d]; exponents[d] = exponents_[d];
} }
@ -675,7 +675,7 @@ Foam::Ostream& Foam::dimensionSet::write
} }
else else
{ {
for (int d=0; d<dimensionSet::nDimensions; ++d) for (int d=0; d < dimensionSet::nDimensions; ++d)
{ {
if (d) os << token::SPACE; if (d) os << token::SPACE;
os << exponents_[d]; os << exponents_[d];