ENH: improved handling for clamping
- proper component-wise clamping for MinMax clamp(). - construct clampOp from components - propagate clamp() method from GeometricField to FieldField and Field - clamp_min() and clamp_max() for one-sided clamping, as explicit alternative to min/max free functions which can be less intuitive and often involve additional field copies. - top-level checks to skip applying invalid min/max ranges and bypass the internal checks of MinMax::clamp() etc.
This commit is contained in:
parent
3888bfa17f
commit
ba153df8db
@ -110,8 +110,7 @@ unsigned checkDimensions
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// min(a, b);
|
min(a, b);
|
||||||
clip(a, b);
|
|
||||||
dimsOk = true;
|
dimsOk = true;
|
||||||
}
|
}
|
||||||
catch (const Foam::error& err)
|
catch (const Foam::error& err)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -83,6 +83,9 @@ int main(int argc, char *argv[])
|
|||||||
Info<<"Construct zero : ";
|
Info<<"Construct zero : ";
|
||||||
printInfo(MinMax<scalar>(Zero)) << nl;
|
printInfo(MinMax<scalar>(Zero)) << nl;
|
||||||
|
|
||||||
|
Info<<"Construct zero_one : ";
|
||||||
|
printInfo(MinMax<scalar>(zero_one{})) << nl;
|
||||||
|
|
||||||
Info<<"Construct range : ";
|
Info<<"Construct range : ";
|
||||||
printInfo(MinMax<scalar>(1, 20)) << nl;
|
printInfo(MinMax<scalar>(1, 20)) << nl;
|
||||||
|
|
||||||
@ -92,6 +95,26 @@ int main(int argc, char *argv[])
|
|||||||
Info<<"A 0-1 vector range : ";
|
Info<<"A 0-1 vector range : ";
|
||||||
printInfo(MinMax<vector>::zero_one()) << nl;
|
printInfo(MinMax<vector>::zero_one()) << nl;
|
||||||
|
|
||||||
|
{
|
||||||
|
vector a(0, 1, 20);
|
||||||
|
vector b(2, 1, 0);
|
||||||
|
vector c(4, 10, 12);
|
||||||
|
|
||||||
|
Info<< "vectors:"
|
||||||
|
<< " a = " << a
|
||||||
|
<< " b = " << b
|
||||||
|
<< " c = " << c << nl;
|
||||||
|
|
||||||
|
Info<< "min max = " << min(max(a, b), c) << nl;
|
||||||
|
Info<< "range clamp= " << MinMax<vector>(b, c).clamp(a) << nl;
|
||||||
|
Info<< "clamp = " << clamp(a, b, c) << nl;
|
||||||
|
|
||||||
|
Info<< "clamp 0/1 = " << clamp(a, vector::zero, vector::one) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scalar promotion
|
||||||
|
Info<< "clamp (scalar) = " << clamp(15.0, -1, 1) << nl;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
scalarMinMax range1(10, 20);
|
scalarMinMax range1(10, 20);
|
||||||
@ -180,6 +203,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
{
|
{
|
||||||
MinMax<scalar> limiter(10, 200);
|
MinMax<scalar> limiter(10, 200);
|
||||||
|
clampOp<scalar> clipper(limiter);
|
||||||
|
// clampOp<scalar> clipper(zero_one{});
|
||||||
|
// clampOp<scalar> clipper(10, 200);
|
||||||
|
|
||||||
Info<< nl
|
Info<< nl
|
||||||
<< "Test clipping limiter: " << limiter << nl
|
<< "Test clipping limiter: " << limiter << nl
|
||||||
@ -196,7 +222,10 @@ int main(int argc, char *argv[])
|
|||||||
Info<< nl << "test clip() with limiter: " << limiter << nl;
|
Info<< nl << "test clip() with limiter: " << limiter << nl;
|
||||||
for (const scalar& val : values1)
|
for (const scalar& val : values1)
|
||||||
{
|
{
|
||||||
Info<< "clipped : " << val << " = " << clip(val, limiter) << nl;
|
Info<< "clipped : " << val << " = "
|
||||||
|
<< clip(val, limiter)
|
||||||
|
<< " or " << clip(val, limiter)
|
||||||
|
<< " or " << clipper(val) << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl << "test clip(Field) with limiter: " << limiter << nl;
|
Info<< nl << "test clip(Field) with limiter: " << limiter << nl;
|
||||||
@ -208,9 +237,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "before " << flatOutput(values2) << nl;
|
Info<< "before " << flatOutput(values2) << nl;
|
||||||
|
|
||||||
|
// Too much clutter
|
||||||
|
// for (scalar& val : values2)
|
||||||
|
// {
|
||||||
|
// clampEqOp<scalar>{limiter}(val);
|
||||||
|
// }
|
||||||
|
|
||||||
for (scalar& val : values2)
|
for (scalar& val : values2)
|
||||||
{
|
{
|
||||||
clipEqOp<scalar>()(val, limiter);
|
val = clipper(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "after: " << flatOutput(values2) << nl;
|
Info<< "after: " << flatOutput(values2) << nl;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -24,7 +24,7 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Test minMax
|
Test-minMax2
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ Description
|
|||||||
#include "MinMax.H"
|
#include "MinMax.H"
|
||||||
#include "dimensionedScalar.H"
|
#include "dimensionedScalar.H"
|
||||||
#include "dimensionedMinMax.H"
|
#include "dimensionedMinMax.H"
|
||||||
|
#include "Random.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -78,7 +79,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "Test min/max " << nl;
|
Info<< "Test min/max " << nl;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
scalarMinMax range1(10, 20);
|
scalarMinMax range1(10, 20);
|
||||||
scalarMinMax range2(40, 50);
|
scalarMinMax range2(40, 50);
|
||||||
@ -140,7 +140,34 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
scalarField someField(25);
|
||||||
|
|
||||||
|
Random rnd(4567);
|
||||||
|
for (scalar& val : someField)
|
||||||
|
{
|
||||||
|
val = rnd.position(-0.2, 1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "field: " << flatOutput(someField) << nl;
|
||||||
|
Info<< "clamp01: "
|
||||||
|
<< flatOutput(clamp(someField, scalarMinMax(zero_one{}))()) << nl;
|
||||||
|
|
||||||
|
Info<< "clamp01: "
|
||||||
|
<< clamp(tmp<scalarField>(someField), scalarMinMax(zero_one{}))<< nl;
|
||||||
|
|
||||||
|
scalarField result(10);
|
||||||
|
clamp(result, someField, scalarMinMax(zero_one{}));
|
||||||
|
|
||||||
|
Info<< "result: " << result << nl;
|
||||||
|
|
||||||
|
someField.clamp(zero_one{});
|
||||||
|
|
||||||
|
Info<< "inplace: " << someField << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl << "\nDone\n" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,7 +1279,7 @@ void write_scalarField
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << limits.clip(fld(cellIdx)) << nl;
|
os << limits.clamp(fld(cellIdx)) << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << token::END_LIST << token::END_STATEMENT << nl;
|
os << token::END_LIST << token::END_STATEMENT << nl;
|
||||||
|
@ -58,12 +58,11 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Read porosity, change to blockage. Clamp values [0-1] silently
|
// Read porosity, change to blockage. Clamp values [0-1] silently
|
||||||
static const scalarMinMax limits01(scalarMinMax::zero_one());
|
|
||||||
|
|
||||||
// Volume porosity -> blockage
|
// Volume porosity -> blockage
|
||||||
inline scalar getPorosity(const dictionary& dict)
|
inline scalar getPorosity(const dictionary& dict)
|
||||||
{
|
{
|
||||||
return 1 - limits01.clip(dict.getOrDefault<scalar>("porosity", 0));
|
return 1 - clamp(dict.getOrDefault<scalar>("porosity", 0), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Direction porosities -> blockage
|
// Direction porosities -> blockage
|
||||||
@ -75,7 +74,7 @@ inline vector getPorosities(const dictionary& dict)
|
|||||||
{
|
{
|
||||||
for (scalar& val : blockage)
|
for (scalar& val : blockage)
|
||||||
{
|
{
|
||||||
val = 1 - limits01.clip(val);
|
val = 1 - clamp(val, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,36 +253,38 @@ bool Foam::dimensionSet::operator/=(const dimensionSet& ds)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::dimensionSet Foam::min(const dimensionSet& ds1, const dimensionSet& ds2)
|
Foam::dimensionSet Foam::min(const dimensionSet& a, const dimensionSet& b)
|
||||||
{
|
{
|
||||||
if (dimensionSet::checking())
|
if (dimensionSet::checking())
|
||||||
{
|
{
|
||||||
checkDims("min(a, b)", ds1, ds2);
|
checkDims("min(a, b)", a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ds1;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::dimensionSet Foam::max(const dimensionSet& ds1, const dimensionSet& ds2)
|
Foam::dimensionSet Foam::max(const dimensionSet& a, const dimensionSet& b)
|
||||||
{
|
{
|
||||||
if (dimensionSet::checking())
|
if (dimensionSet::checking())
|
||||||
{
|
{
|
||||||
checkDims("max(a, b)", ds1, ds2);
|
checkDims("max(a, b)", a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ds1;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::dimensionSet Foam::clip(const dimensionSet& ds1, const dimensionSet& ds2)
|
Foam::dimensionSet Foam::clamp(const dimensionSet& a, const dimensionSet& range)
|
||||||
{
|
{
|
||||||
if (dimensionSet::checking())
|
// In may cases the min/max range will be created from raw values
|
||||||
|
// (no dimension) so accept those without error
|
||||||
|
if (dimensionSet::checking() && !range.dimensionless())
|
||||||
{
|
{
|
||||||
checkDims("clip(a, b)", ds1, ds2);
|
checkDims("clamp(a, b)", a, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ds1;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2022 OpenCFD Ltd.
|
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -354,9 +354,9 @@ Ostream& operator<<(Ostream& os, const dimensionSet& ds);
|
|||||||
|
|
||||||
// Global Functions
|
// Global Functions
|
||||||
|
|
||||||
dimensionSet min(const dimensionSet& ds1, const dimensionSet& ds2);
|
dimensionSet min(const dimensionSet& a, const dimensionSet& b);
|
||||||
dimensionSet max(const dimensionSet& ds1, const dimensionSet& ds2);
|
dimensionSet max(const dimensionSet& a, const dimensionSet& b);
|
||||||
dimensionSet clip(const dimensionSet& ds1, const dimensionSet& ds2);
|
dimensionSet clamp(const dimensionSet& a, const dimensionSet& range);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -421,6 +421,8 @@ public:
|
|||||||
const tmp<DimensionedField<cmptType, GeoMesh>>& tdf
|
const tmp<DimensionedField<cmptType, GeoMesh>>& tdf
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Inherits clamp, clamp_min, clamp_max (without dimensions) from Field
|
||||||
|
|
||||||
//- Return the field transpose (only defined for second rank tensors)
|
//- Return the field transpose (only defined for second rank tensors)
|
||||||
tmp<DimensionedField<Type, GeoMesh>> T() const;
|
tmp<DimensionedField<Type, GeoMesh>> T() const;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -282,6 +282,65 @@ void FieldField<Field, Type>::replace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<template<class> class Field, class Type>
|
||||||
|
void FieldField<Field, Type>::clamp
|
||||||
|
(
|
||||||
|
const Type& lower,
|
||||||
|
const Type& upper
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (lower < upper)
|
||||||
|
{
|
||||||
|
for (auto& ff : *this)
|
||||||
|
{
|
||||||
|
ff.clamp(lower, upper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<template<class> class Field, class Type>
|
||||||
|
void FieldField<Field, Type>::clamp
|
||||||
|
(
|
||||||
|
const MinMax<Type>& range
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (range.min() < range.max())
|
||||||
|
{
|
||||||
|
for (auto& ff : *this)
|
||||||
|
{
|
||||||
|
ff.clamp(range.min(), range.max());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<template<class> class Field, class Type>
|
||||||
|
void FieldField<Field, Type>::clamp_min
|
||||||
|
(
|
||||||
|
const Type& lower
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto& ff : *this)
|
||||||
|
{
|
||||||
|
ff.clamp_min(lower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<template<class> class Field, class Type>
|
||||||
|
void FieldField<Field, Type>::clamp_max
|
||||||
|
(
|
||||||
|
const Type& upper
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto& ff : *this)
|
||||||
|
{
|
||||||
|
ff.clamp_max(upper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<template<class> class Field, class Type>
|
template<template<class> class Field, class Type>
|
||||||
tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const
|
tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2022 OpenCFD Ltd.
|
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -149,6 +149,20 @@ public:
|
|||||||
//- Replace a component field of the field
|
//- Replace a component field of the field
|
||||||
void replace(const direction, const cmptType&);
|
void replace(const direction, const cmptType&);
|
||||||
|
|
||||||
|
//- Clamp field values (in-place) to the specified range.
|
||||||
|
// A no-op for an invalid range.
|
||||||
|
void clamp(const Type& lower, const Type& upper);
|
||||||
|
|
||||||
|
//- Clamp field values (in-place) to the specified range.
|
||||||
|
// A no-op for an invalid range.
|
||||||
|
void clamp(const MinMax<Type>& range);
|
||||||
|
|
||||||
|
//- Impose lower (floor) clamp on the field values (in-place)
|
||||||
|
void clamp_min(const Type& lower);
|
||||||
|
|
||||||
|
//- Impose upper (ceiling) clamp on the field values (in-place)
|
||||||
|
void clamp_max(const Type& upper);
|
||||||
|
|
||||||
//- Return the field transpose (only defined for second rank tensors)
|
//- Return the field transpose (only defined for second rank tensors)
|
||||||
tmp<FieldField<Field, Type>> T() const;
|
tmp<FieldField<Field, Type>> T() const;
|
||||||
|
|
||||||
|
@ -673,7 +673,7 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
|
|||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
||||||
|
|
||||||
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip)
|
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -287,7 +287,7 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
|
|||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
||||||
|
|
||||||
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip)
|
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -625,6 +625,50 @@ void Foam::Field<Type>::replace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::Field<Type>::clamp(const Type& lower, const Type& upper)
|
||||||
|
{
|
||||||
|
// Use free functions min(), max() to impose component-wise clamping
|
||||||
|
if (lower < upper)
|
||||||
|
{
|
||||||
|
// std::for_each
|
||||||
|
for (auto& val : *this)
|
||||||
|
{
|
||||||
|
val = min(max(val, lower), upper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::Field<Type>::clamp(const MinMax<Type>& range)
|
||||||
|
{
|
||||||
|
clamp(range.min(), range.max());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::Field<Type>::clamp_min(const Type& lower)
|
||||||
|
{
|
||||||
|
// Use free function max() [sic] to impose component-wise clamp_min
|
||||||
|
// std::for_each
|
||||||
|
for (auto& val : *this)
|
||||||
|
{
|
||||||
|
val = max(val, lower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::Field<Type>::clamp_max(const Type& upper)
|
||||||
|
{
|
||||||
|
// Use free function min() [sic] to impose component-wise clamp_max
|
||||||
|
// std::for_each
|
||||||
|
for (auto& val : *this)
|
||||||
|
{
|
||||||
|
val = min(val, upper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
template<class VSForm>
|
template<class VSForm>
|
||||||
VSForm Foam::Field<Type>::block(const label start) const
|
VSForm Foam::Field<Type>::block(const label start) const
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -415,6 +415,20 @@ public:
|
|||||||
//- Replace a component field of the field
|
//- Replace a component field of the field
|
||||||
void replace(const direction, const cmptType&);
|
void replace(const direction, const cmptType&);
|
||||||
|
|
||||||
|
//- Clamp field values (in-place) to the specified range.
|
||||||
|
// A no-op for an invalid range.
|
||||||
|
void clamp(const Type& lower, const Type& upper);
|
||||||
|
|
||||||
|
//- Clamp field values (in-place) to the specified range.
|
||||||
|
// A no-op for an invalid range.
|
||||||
|
void clamp(const MinMax<Type>& range);
|
||||||
|
|
||||||
|
//- Impose lower (floor) clamp on the field values (in-place)
|
||||||
|
void clamp_min(const Type& lower);
|
||||||
|
|
||||||
|
//- Impose upper (ceiling) clamp on the field values (in-place)
|
||||||
|
void clamp_max(const Type& upper);
|
||||||
|
|
||||||
template<class VSForm>
|
template<class VSForm>
|
||||||
VSForm block(const label start) const;
|
VSForm block(const label start) const;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -656,6 +656,64 @@ TMP_UNARY_FUNCTION(Type, gAverage)
|
|||||||
|
|
||||||
#undef TMP_UNARY_FUNCTION
|
#undef TMP_UNARY_FUNCTION
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void clamp
|
||||||
|
(
|
||||||
|
Field<Type>& result,
|
||||||
|
const UList<Type>& f1,
|
||||||
|
const MinMax<Type>& range
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (result.cdata() == f1.cdata())
|
||||||
|
{
|
||||||
|
// Apply in-place
|
||||||
|
result.clamp(range);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (range.good())
|
||||||
|
{
|
||||||
|
std::transform
|
||||||
|
(
|
||||||
|
f1.cbegin(),
|
||||||
|
f1.cbegin(result.size()),
|
||||||
|
result.begin(),
|
||||||
|
clampOp<Type>(range)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No clamping
|
||||||
|
std::copy(f1.cbegin(), f1.cbegin(result.size()), result.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> clamp
|
||||||
|
(
|
||||||
|
const UList<Type>& f1,
|
||||||
|
const MinMax<Type>& range
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto tres = tmp<Field<Type>>::New(f1.size());
|
||||||
|
clamp(tres.ref(), f1, range);
|
||||||
|
return tres;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> clamp
|
||||||
|
(
|
||||||
|
const tmp<Field<Type>>& tf1,
|
||||||
|
const MinMax<Type>& range
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto tres = reuseTmp<Type, Type>::New(tf1);
|
||||||
|
clamp(tres.ref(), tf1(), range);
|
||||||
|
tf1.clear();
|
||||||
|
return tres;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BINARY_FUNCTION(Type, Type, Type, max)
|
BINARY_FUNCTION(Type, Type, Type, max)
|
||||||
BINARY_FUNCTION(Type, Type, Type, min)
|
BINARY_FUNCTION(Type, Type, Type, min)
|
||||||
@ -667,10 +725,10 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
|
|||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
||||||
|
|
||||||
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip)
|
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip) // Same as clamp
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */
|
||||||
|
|
||||||
UNARY_OPERATOR(Type, Type, -, negate)
|
UNARY_OPERATOR(Type, Type, -, negate)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -313,10 +313,11 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
|
|||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
|
||||||
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
|
||||||
|
|
||||||
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip)
|
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
|
||||||
|
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip) // Same as clamp
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
UNARY_OPERATOR(Type, Type, -, negate)
|
UNARY_OPERATOR(Type, Type, -, negate)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -1250,60 +1250,88 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::replace
|
|||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void Foam::GeometricField<Type, PatchField, GeoMesh>::min
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp
|
||||||
(
|
(
|
||||||
const dimensioned<Type>& dt
|
const Type& lower,
|
||||||
|
const Type& upper
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Foam::min(primitiveFieldRef(), primitiveField(), dt.value());
|
primitiveFieldRef().clamp(lower, upper);
|
||||||
Foam::min(boundaryFieldRef(), boundaryField(), dt.value());
|
boundaryFieldRef().clamp(lower, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void Foam::GeometricField<Type, PatchField, GeoMesh>::max
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp
|
||||||
(
|
(
|
||||||
const dimensioned<Type>& dt
|
const MinMax<Type>& range
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Foam::max(primitiveFieldRef(), primitiveField(), dt.value());
|
primitiveFieldRef().clamp(range.min(), range.max());
|
||||||
Foam::max(boundaryFieldRef(), boundaryField(), dt.value());
|
boundaryFieldRef().clamp(range.min(), range.max());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void Foam::GeometricField<Type, PatchField, GeoMesh>::clip
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp
|
||||||
|
(
|
||||||
|
const dimensioned<Type>& lower,
|
||||||
|
const dimensioned<Type>& upper
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this->clamp(lower.value(), upper.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp
|
||||||
(
|
(
|
||||||
const dimensioned<MinMax<Type>>& range
|
const dimensioned<MinMax<Type>>& range
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Foam::clip(primitiveFieldRef(), primitiveField(), range.value());
|
this->clamp(range.value());
|
||||||
Foam::clip(boundaryFieldRef(), boundaryField(), range.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void Foam::GeometricField<Type, PatchField, GeoMesh>::clip
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp_min
|
||||||
(
|
(
|
||||||
const dimensioned<Type>& minVal,
|
const Type& lower
|
||||||
const dimensioned<Type>& maxVal
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MinMax<Type> range(minVal.value(), maxVal.value());
|
primitiveFieldRef().clamp_min(lower);
|
||||||
|
boundaryFieldRef().clamp_min(lower);
|
||||||
Foam::clip(primitiveFieldRef(), primitiveField(), range);
|
|
||||||
Foam::clip(boundaryFieldRef(), boundaryField(), range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void Foam::GeometricField<Type, PatchField, GeoMesh>::maxMin
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp_max
|
||||||
(
|
(
|
||||||
const dimensioned<Type>& minVal,
|
const Type& upper
|
||||||
const dimensioned<Type>& maxVal
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this->clip(minVal, maxVal);
|
primitiveFieldRef().clamp_max(upper);
|
||||||
|
boundaryFieldRef().clamp_max(upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp_min
|
||||||
|
(
|
||||||
|
const dimensioned<Type>& lower
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this->clamp_min(lower.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::clamp_max
|
||||||
|
(
|
||||||
|
const dimensioned<Type>& upper
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this->clamp_max(upper.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -134,7 +134,6 @@ private:
|
|||||||
//- Read the field - create the field dictionary on-the-fly
|
//- Read the field - create the field dictionary on-the-fly
|
||||||
void readFields();
|
void readFields();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
@ -630,32 +629,39 @@ public:
|
|||||||
const dimensioned<cmptType>& ds
|
const dimensioned<cmptType>& ds
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Use the minimum of the field and specified value
|
//- Clamp field values (in-place) to the specified range.
|
||||||
// This sets the \em ceiling on the field values
|
// A no-op for an invalid range.
|
||||||
void min(const dimensioned<Type>& dt);
|
void clamp(const Type& lower, const Type& upper);
|
||||||
|
|
||||||
//- Use the maximum of the field and specified value
|
//- Clamp field values (in-place) to the specified range.
|
||||||
// This sets the \em floor on the field values
|
// A no-op for an invalid range.
|
||||||
void max(const dimensioned<Type>& dt);
|
void clamp(const MinMax<Type>& range);
|
||||||
|
|
||||||
//- Clip the field to be bounded within the specified range
|
//- Clamp field values (in-place) to the specified range.
|
||||||
void clip(const dimensioned<MinMax<Type>>& range);
|
// A no-op for an invalid range. No dimension checking.
|
||||||
|
void clamp
|
||||||
//- Clip the field to be bounded within the specified range
|
|
||||||
void clip
|
|
||||||
(
|
(
|
||||||
const dimensioned<Type>& minVal,
|
const dimensioned<Type>& lower,
|
||||||
const dimensioned<Type>& maxVal
|
const dimensioned<Type>& upper
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Deprecated(2019-01) identical to clip()
|
//- Clamp field values (in-place) to the specified range.
|
||||||
// \deprecated(2019-01) identical to clip()
|
// A no-op for an invalid range. No dimension checking.
|
||||||
FOAM_DEPRECATED_FOR(2019-01, "clip() method")
|
void clamp(const dimensioned<MinMax<Type>>& range);
|
||||||
void maxMin
|
|
||||||
(
|
//- Impose lower (floor) clamp on the field values (in-place)
|
||||||
const dimensioned<Type>& minVal,
|
void clamp_min(const Type& lower);
|
||||||
const dimensioned<Type>& maxVal
|
|
||||||
);
|
//- Impose upper (ceiling) clamp on the field values (in-place)
|
||||||
|
void clamp_max(const Type& upper);
|
||||||
|
|
||||||
|
//- Impose lower (floor) clamp on the field values (in-place)
|
||||||
|
// No dimension checking
|
||||||
|
void clamp_min(const dimensioned<Type>& lower);
|
||||||
|
|
||||||
|
//- Impose upper (ceiling) clamp on the field values (in-place)
|
||||||
|
// No dimension checking
|
||||||
|
void clamp_max(const dimensioned<Type>& upper);
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -691,7 +697,7 @@ public:
|
|||||||
void operator/=(const dimensioned<scalar>&);
|
void operator/=(const dimensioned<scalar>&);
|
||||||
|
|
||||||
|
|
||||||
// Ostream operators
|
// Ostream Operators
|
||||||
|
|
||||||
friend Ostream& operator<< <Type, PatchField, GeoMesh>
|
friend Ostream& operator<< <Type, PatchField, GeoMesh>
|
||||||
(
|
(
|
||||||
@ -704,6 +710,41 @@ public:
|
|||||||
Ostream&,
|
Ostream&,
|
||||||
const tmp<GeometricField<Type, PatchField, GeoMesh>>&
|
const tmp<GeometricField<Type, PatchField, GeoMesh>>&
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Housekeeping
|
||||||
|
|
||||||
|
//- Clamp field values (in-place) to the specified range.
|
||||||
|
// \deprecated(2023-01) prefer clamp() naming
|
||||||
|
void clip(const dimensioned<MinMax<Type>>& range)
|
||||||
|
{
|
||||||
|
this->clamp(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Clamp field values (in-place) to the specified range.
|
||||||
|
// \deprecated(2023-01) prefer clamp() naming
|
||||||
|
void clip(const dimensioned<Type>& lo, const dimensioned<Type>& hi)
|
||||||
|
{
|
||||||
|
this->clamp(lo.value(), hi.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Use minimum of the field and specified value. ie, clamp_max().
|
||||||
|
// This sets the \em ceiling on the field values
|
||||||
|
// \deprecated(2023-01) prefer clamp_max()
|
||||||
|
void min(const dimensioned<Type>& upper) { this->clamp_max(upper); }
|
||||||
|
|
||||||
|
//- Use maximum of the field and specified value. ie, clamp_min().
|
||||||
|
// This sets the \em floor on the field values
|
||||||
|
// \deprecated(2023-01) prefer clamp_min()
|
||||||
|
void max(const dimensioned<Type>& lower) { this->clamp_min(lower); }
|
||||||
|
|
||||||
|
//- Deprecated(2019-01) identical to clamp()
|
||||||
|
// \deprecated(2019-01) identical to clamp()
|
||||||
|
FOAM_DEPRECATED_FOR(2019-01, "clamp() method")
|
||||||
|
void maxMin(const dimensioned<Type>& lo, const dimensioned<Type>& hi)
|
||||||
|
{
|
||||||
|
return this->clamp(lo.value(), hi.value());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,6 +294,13 @@ inline bool notEqual(const Scalar a, const Scalar b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fast implementation, and with scalar promotion of upper/lower limits
|
||||||
|
inline Scalar clamp(const Scalar& val, const Scalar& lower, const Scalar& upper)
|
||||||
|
{
|
||||||
|
return (val < lower) ? lower : (upper < val) ? upper : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Scalar limit(const Scalar s1, const Scalar s2)
|
inline Scalar limit(const Scalar s1, const Scalar s2)
|
||||||
{
|
{
|
||||||
return (mag(s1) < mag(s2)) ? s1: 0.0;
|
return (mag(s1) < mag(s2)) ? s1: 0.0;
|
||||||
|
@ -141,6 +141,15 @@ inline bool equal(const T& a, const T& b)
|
|||||||
return (a == b);
|
return (a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Return value clamped between upper and lower limits.
|
||||||
|
// Unlike the std::clamp, which selects between references, this version
|
||||||
|
// wraps the min/max free functions for component-wise clamping
|
||||||
|
template<class T>
|
||||||
|
inline T clamp(const T& val, const T& lower, const T& upper)
|
||||||
|
{
|
||||||
|
return min(max(val, lower), upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Struct labelOp Declaration
|
Struct labelOp Declaration
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -67,30 +67,16 @@ Description
|
|||||||
Info<< "values values in range " << mask << nl;
|
Info<< "values values in range " << mask << nl;
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
One particular advantage offered by MinMax is to clip or limit values
|
One advantage offered by MinMax is to clamp or limit values
|
||||||
to a particular range. For example,
|
to a particular range. For example,
|
||||||
\verbatim
|
\verbatim
|
||||||
scalarMinMax range(lower, upper);
|
scalarMinMax range(lower, upper);
|
||||||
|
|
||||||
scalar val;
|
scalar val;
|
||||||
val = range.clip(val) .. return clip values
|
val = range.clamp(val) .. return clamped values
|
||||||
|
|
||||||
// vs.
|
// vs.
|
||||||
val = min(max(value, lower, upper))
|
val = min(max(value, lower), upper)
|
||||||
\endverbatim
|
|
||||||
|
|
||||||
Or when working on lists, the values can be limited in a single pass
|
|
||||||
of the data without intermediate memory allocation.
|
|
||||||
\verbatim
|
|
||||||
scalarField values = ...;
|
|
||||||
|
|
||||||
for (scalar& val : values)
|
|
||||||
{
|
|
||||||
range.inplaceClip(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// vs.
|
|
||||||
values = min(max(values, lower, upper))
|
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -112,6 +98,7 @@ namespace Foam
|
|||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
template<class T> class MinMax;
|
template<class T> class MinMax;
|
||||||
class zero;
|
class zero;
|
||||||
|
class zero_one;
|
||||||
|
|
||||||
// Common min/max types
|
// Common min/max types
|
||||||
typedef MinMax<label> labelMinMax; //!< A label min/max range
|
typedef MinMax<label> labelMinMax; //!< A label min/max range
|
||||||
@ -155,6 +142,9 @@ public:
|
|||||||
//- Construct with a single zero value
|
//- Construct with a single zero value
|
||||||
inline explicit MinMax(const Foam::zero);
|
inline explicit MinMax(const Foam::zero);
|
||||||
|
|
||||||
|
//- Implicit construct from zero_one as 0-1 range (pTraits zero, one)
|
||||||
|
inline MinMax(const Foam::zero_one);
|
||||||
|
|
||||||
//- Construct with a single initial value
|
//- Construct with a single initial value
|
||||||
inline explicit MinMax(const T& val);
|
inline explicit MinMax(const T& val);
|
||||||
|
|
||||||
@ -239,14 +229,9 @@ public:
|
|||||||
//- True if the value is within the range (inclusive check)
|
//- True if the value is within the range (inclusive check)
|
||||||
inline bool contains(const T& val) const;
|
inline bool contains(const T& val) const;
|
||||||
|
|
||||||
//- If out of range, return the respective min/max limits, otherwise
|
//- Return value clamped component-wise.
|
||||||
//- return the value itself.
|
// If the range is invalid, just returns the value.
|
||||||
// If the range is invalid, always return the value.
|
inline T clamp(const T& val) const;
|
||||||
inline const T& clip(const T& val) const;
|
|
||||||
|
|
||||||
//- Inplace clip value by the min/max limits
|
|
||||||
// \return True if clipping was applied.
|
|
||||||
inline bool inplaceClip(T& val) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Manipulate
|
// Manipulate
|
||||||
@ -284,6 +269,15 @@ public:
|
|||||||
|
|
||||||
//- Divide range by scalar factor
|
//- Divide range by scalar factor
|
||||||
inline MinMax<T>& operator/=(const scalar& s);
|
inline MinMax<T>& operator/=(const scalar& s);
|
||||||
|
|
||||||
|
|
||||||
|
// Housekeeping
|
||||||
|
|
||||||
|
//- Old method name. Same as clamp (2023-01)
|
||||||
|
T clip(const T& val) const { return this->clamp(val); }
|
||||||
|
|
||||||
|
//- Old method (2023-01)
|
||||||
|
void inplaceClip(T& val) const { val = this->clamp(val); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -44,7 +44,7 @@ inline Foam::MinMax<T> Foam::MinMax<T>::le(const T& maxVal)
|
|||||||
template<class T>
|
template<class T>
|
||||||
inline Foam::MinMax<T> Foam::MinMax<T>::zero_one()
|
inline Foam::MinMax<T> Foam::MinMax<T>::zero_one()
|
||||||
{
|
{
|
||||||
return MinMax<T>(pTraits<T>::zero, pTraits<T>::one);
|
return MinMax<T>(Foam::zero_one{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,6 +85,13 @@ inline Foam::MinMax<T>::MinMax(const Foam::zero)
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Foam::MinMax<T>::MinMax(const Foam::zero_one)
|
||||||
|
:
|
||||||
|
Tuple2<T,T>(pTraits<T>::zero, pTraits<T>::one)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Foam::MinMax<T>::MinMax(const T& val)
|
inline Foam::MinMax<T>::MinMax(const T& val)
|
||||||
:
|
:
|
||||||
@ -235,45 +242,17 @@ inline bool Foam::MinMax<T>::contains(const T& val) const
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline const T& Foam::MinMax<T>::clip(const T& val) const
|
inline T Foam::MinMax<T>::clamp(const T& val) const
|
||||||
{
|
{
|
||||||
if (good())
|
if (good())
|
||||||
{
|
{
|
||||||
if (val < min())
|
return Foam::min(Foam::max(val, min()), max());
|
||||||
{
|
|
||||||
return min();
|
|
||||||
}
|
|
||||||
else if (max() < val)
|
|
||||||
{
|
|
||||||
return max();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val; // Pass-through
|
return val; // Pass-through
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline bool Foam::MinMax<T>::inplaceClip(T& val) const
|
|
||||||
{
|
|
||||||
if (good())
|
|
||||||
{
|
|
||||||
if (val < min())
|
|
||||||
{
|
|
||||||
val = min();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (max() < val)
|
|
||||||
{
|
|
||||||
val = max();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // No change
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Foam::MinMax<T>& Foam::MinMax<T>::add(const MinMax& other)
|
inline Foam::MinMax<T>& Foam::MinMax<T>::add(const MinMax& other)
|
||||||
{
|
{
|
||||||
|
@ -54,35 +54,60 @@ inline scalar mag(const MinMax<T>& range)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//- Return the value after clipping by the min/max limiter
|
//- Return the value after clamping by the min/max limiter
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T clip(const T& val, const MinMax<T>& range)
|
inline T clip(const T& val, const MinMax<T>& range)
|
||||||
{
|
{
|
||||||
return range.clip(val);
|
return range.clamp(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Unary function for applying component-wise clamping
|
||||||
//- Return the value after clipping by the min/max limiter
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct clipOp
|
struct clampOp
|
||||||
{
|
{
|
||||||
T operator()(T& val, const MinMax<T>& range) const
|
const T lower;
|
||||||
|
const T upper;
|
||||||
|
|
||||||
|
//- Construct from min/max limits. No validity checks
|
||||||
|
clampOp(const T& min, const T& max)
|
||||||
|
:
|
||||||
|
lower(min),
|
||||||
|
upper(max)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Construct from min/max range. No validity checks
|
||||||
|
clampOp(const MinMax<T>& range)
|
||||||
|
:
|
||||||
|
lower(range.min()),
|
||||||
|
upper(range.max())
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Construct as 0-1 min/max range
|
||||||
|
clampOp(const Foam::zero_one)
|
||||||
|
:
|
||||||
|
clampOp(MinMax<T>(Foam::zero_one{}))
|
||||||
|
{}
|
||||||
|
|
||||||
|
T operator()(const T& val) const
|
||||||
{
|
{
|
||||||
return range.clip(val);
|
return min(max(val, lower), upper);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//- Clip value and assign inplace
|
/// Not really needed
|
||||||
template<class T>
|
/// //- Unary function for applying component-wise clamping (inplace)
|
||||||
struct clipEqOp
|
/// template<class T>
|
||||||
{
|
/// struct clampEqOp : public clampOp<T>
|
||||||
bool operator()(T& val, const MinMax<T>& range) const
|
/// {
|
||||||
{
|
/// using clampOp<T>::clampOp;
|
||||||
return range.inplaceClip(val);
|
///
|
||||||
}
|
/// void operator()(T& val) const
|
||||||
};
|
/// {
|
||||||
|
/// val = clampOp<T>::operator()(val);
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
|
||||||
|
|
||||||
//- Extract the min/max range from a list of values.
|
//- Extract the min/max range from a list of values.
|
||||||
@ -156,14 +181,14 @@ struct minMaxEqOp
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//- The magnitude of an initial single value.
|
//- The magnitude of a single value.
|
||||||
inline scalarMinMax minMaxMag(const scalar val)
|
inline scalarMinMax minMaxMag(const scalar val)
|
||||||
{
|
{
|
||||||
return scalarMinMax(Foam::mag(val));
|
return scalarMinMax(Foam::mag(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//- The magnitude of from an initial VectorSpace.
|
//- The magnitude of a VectorSpace.
|
||||||
template<class Form, class Cmpt, direction nCmpt>
|
template<class Form, class Cmpt, direction nCmpt>
|
||||||
inline scalarMinMax minMaxMag(const VectorSpace<Form,Cmpt,nCmpt>& vs)
|
inline scalarMinMax minMaxMag(const VectorSpace<Form,Cmpt,nCmpt>& vs)
|
||||||
{
|
{
|
||||||
|
@ -257,7 +257,7 @@ void Foam::lumpedPointMovement::readDict(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
relax_ = dict.getOrDefault<scalar>("relax", 1);
|
relax_ = dict.getOrDefault<scalar>("relax", 1);
|
||||||
scalarMinMax::zero_one().inplaceClip(relax_);
|
relax_ = clamp(relax_, 0, 1);
|
||||||
|
|
||||||
forcesDict_.merge(dict.subOrEmptyDict("forces"));
|
forcesDict_.merge(dict.subOrEmptyDict("forces"));
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ Foam::pointIndexHit Foam::searchableDisk::findNearest
|
|||||||
v.normalise();
|
v.normalise();
|
||||||
|
|
||||||
// Clip to inner/outer radius
|
// Clip to inner/outer radius
|
||||||
info.setPoint(origin() + radialLimits_.clip(magV)*v);
|
info.setPoint(origin() + radialLimits_.clamp(magV)*v);
|
||||||
|
|
||||||
if (info.point().distSqr(sample) < nearestDistSqr)
|
if (info.point().distSqr(sample) < nearestDistSqr)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user