EHN: add FieldFunction interface for 0/1 clamping

- enables clamp(field, zero_one{}) returning a tmp Field
This commit is contained in:
Mark Olesen
2023-01-21 22:30:33 +01:00
parent 6f68ce5239
commit ab10b4a05c
10 changed files with 227 additions and 7 deletions

View File

@ -152,13 +152,13 @@ int main(int argc, char *argv[])
Info<< nl
<< "field: " << flatOutput(someField) << nl;
Info<< "clamp01: "
<< flatOutput(clamp(someField, scalarMinMax(zero_one{}))()) << nl;
<< flatOutput(clamp(someField, zero_one{})()) << nl;
Info<< "clamp01: "
<< clamp(tmp<scalarField>(someField), scalarMinMax(zero_one{}))<< nl;
<< clamp(tmp<scalarField>(someField), zero_one{})<< nl;
scalarField result(10);
clamp(result, someField, scalarMinMax(zero_one{}));
clamp(result, someField, zero_one{});
Info<< "result: " << result << nl;

View File

@ -319,7 +319,72 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip)
// ------------------------------------------------------------------------- //
// Clamp Methods
template<class Type, class GeoMesh>
void clamp
(
DimensionedField<Type, GeoMesh>& result,
const DimensionedField<Type, GeoMesh>& f1,
const Foam::zero_one
)
{
const MinMax<Type> range(Foam::zero_one{});
clamp(result.field(), f1.field(), range);
result.oriented() = f1.oriented();
}
template<class Type, class GeoMesh>
tmp<DimensionedField<Type, GeoMesh>>
clamp
(
const DimensionedField<Type, GeoMesh>& f1,
const Foam::zero_one
)
{
auto tres =
reuseTmpDimensionedField<Type, Type, GeoMesh>::New
(
f1,
"clamp01(" + f1.name() + ')',
f1.dimensions()
);
clamp(tres.ref(), f1, Foam::zero_one{});
return tres;
}
template<class Type, class GeoMesh>
tmp<DimensionedField<Type, GeoMesh>>
clamp
(
const tmp<DimensionedField<Type, GeoMesh>>& tf1,
const Foam::zero_one
)
{
const auto& f1 = tf1();
auto tres =
reuseTmpDimensionedField<Type, Type, GeoMesh>::New
(
tf1,
"clamp01(" + f1.name() + ')',
f1.dimensions()
);
clamp(tres.field(), f1, Foam::zero_one{});
tf1.clear();
return tres;
}
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //

View File

@ -137,7 +137,36 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip)
// ------------------------------------------------------------------------- //
// Clamp Methods
template<class Type, class GeoMesh>
void clamp
(
DimensionedField<Type, GeoMesh>& result,
const DimensionedField<Type, GeoMesh>& f1,
const Foam::zero_one
);
template<class Type, class GeoMesh>
tmp<DimensionedField<Type, GeoMesh>>
clamp
(
const DimensionedField<Type, GeoMesh>& f1,
const Foam::zero_one
);
template<class Type, class GeoMesh>
tmp<DimensionedField<Type, GeoMesh>>
clamp
(
const tmp<DimensionedField<Type, GeoMesh>>& tf1,
const Foam::zero_one
);
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //

View File

@ -630,6 +630,7 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
// Note: works with zero_one through implicit conversion to MinMax
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)

View File

@ -287,6 +287,7 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
// Note: works with zero_one through implicit conversion to MinMax
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)

View File

@ -700,7 +700,33 @@ void clamp
}
}
template<class Type>
void clamp
(
Field<Type>& result,
const UList<Type>& f1,
const Foam::zero_one& // Note: macros generate a const reference
)
{
if (result.cdata() == f1.cdata())
{
// Apply in-place
result.clamp_range(Foam::zero_one{});
}
else
{
std::transform
(
f1.cbegin(),
f1.cbegin(result.size()),
result.begin(),
clampOp<Type>(Foam::zero_one{})
);
}
}
BINARY_FUNCTION_INTERFACE_FS(Type, Type, MinMax<Type>, clamp)
BINARY_FUNCTION_INTERFACE_FS(Type, Type, Foam::zero_one, clamp)
BINARY_FUNCTION(Type, Type, Type, max)

View File

@ -314,6 +314,7 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
BINARY_TYPE_FUNCTION_FS(Type, Type, Foam::zero_one, clamp)
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clip) // Same as clamp

View File

@ -480,6 +480,74 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
// ------------------------------------------------------------------------- //
// Clamp Methods
template<class Type, template<class> class PatchField, class GeoMesh>
void clamp
(
GeometricField<Type, PatchField, GeoMesh>& result,
const GeometricField<Type, PatchField, GeoMesh>& f1,
const Foam::zero_one
)
{
const MinMax<Type> range(Foam::zero_one{});
clamp(result.primitiveFieldRef(), f1.primitiveField(), range);
clamp(result.boundaryFieldRef(), f1.boundaryField(), range);
result.oriented() = f1.oriented();
}
template<class Type, template<class> class PatchField, class GeoMesh>
tmp<GeometricField<Type, PatchField, GeoMesh>>
clamp
(
const GeometricField<Type, PatchField, GeoMesh>& f1,
const Foam::zero_one
)
{
auto tres =
reuseTmpGeometricField<Type, Type, PatchField, GeoMesh>::New
(
f1,
"clamp01(" + f1.name() + ')',
f1.dimensions()
);
clamp(tres.ref(), f1, Foam::zero_one{});
return tres;
}
template<class Type, template<class> class PatchField, class GeoMesh>
tmp<GeometricField<Type, PatchField, GeoMesh>>
clamp
(
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1,
const Foam::zero_one
)
{
const auto& f1 = tf1();
auto tres =
reuseTmpGeometricField<Type, Type, PatchField, GeoMesh>::New
(
tf1,
"clamp01(" + f1.name() + ')',
f1.dimensions()
);
clamp(tres.ref(), f1, Foam::zero_one{});
tf1.clear();
return tres;
}
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
UNARY_OPERATOR(Type, Type, -, negate, transform)

View File

@ -273,6 +273,36 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, min)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
// ------------------------------------------------------------------------- //
// Clamp Methods
template<class Type, template<class> class PatchField, class GeoMesh>
void clamp
(
GeometricField<Type, PatchField, GeoMesh>& result,
const GeometricField<Type, PatchField, GeoMesh>& f1,
const Foam::zero_one
);
template<class Type, template<class> class PatchField, class GeoMesh>
tmp<GeometricField<Type, PatchField, GeoMesh>>
clamp
(
const GeometricField<Type, PatchField, GeoMesh>& f1,
const Foam::zero_one
);
template<class Type, template<class> class PatchField, class GeoMesh>
tmp<GeometricField<Type, PatchField, GeoMesh>>
clamp
(
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1,
const Foam::zero_one
);
BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //

View File

@ -85,6 +85,7 @@ Description
#define Foam_MinMax_H
#include "scalar.H"
#include "zero.H"
#include "Pair.H"
#include "Tuple2.H"
#include "VectorSpace.H"
@ -97,8 +98,6 @@ namespace Foam
// Forward Declarations
template<class T> class MinMax;
class zero;
class zero_one;
// Common min/max types
typedef MinMax<label> labelMinMax; //!< A label min/max range