diff --git a/src/OpenFOAM/fields/Fields/Field/FieldOps.C b/src/OpenFOAM/fields/Fields/Field/FieldOps.C new file mode 100644 index 0000000000000000000000000000000000000000..0c9d997166cd29672d0ac03d2f9d002471c32038 --- /dev/null +++ b/src/OpenFOAM/fields/Fields/Field/FieldOps.C @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 <algorithm> + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template<class Tout, class T1, class UnaryOp> +void Foam::FieldOps::assign +( + Field<Tout>& result, + const Field<T1>& a, + const UnaryOp& op +) +{ + #ifdef FULLDEBUG + if (result.size() != a.size()) + { + FatalErrorInFunction + << "Field sizes do not match: " << result.size() << " (" + << a.size() << ')' << nl + << abort(FatalError); + } + #endif + + std::transform(a.cbegin(), a.cend(), result.begin(), op); +} + + +template<class Tout, class T1, class T2, class BinaryOp> +void Foam::FieldOps::assign +( + Field<Tout>& result, + const Field<T1>& a, + const Field<T2>& b, + const BinaryOp& bop +) +{ + #ifdef FULLDEBUG + if (result.size() != a.size() || result.size() != b.size()) + { + FatalErrorInFunction + << "Field sizes do not match: " << result.size() << " (" + << a.size() << ' ' << b.size() << ')' << nl + << abort(FatalError); + } + #endif + + std::transform(a.cbegin(), a.cend(), b.cbegin(), result.begin(), bop); +} + + +template<class T, class BinaryOp> +void Foam::FieldOps::ternary +( + Field<T>& result, + const Field<T>& a, + const Field<T>& b, + const BinaryOp& bop +) +{ + #ifdef FULLDEBUG + if (result.size() != a.size() || result.size() != b.size()) + { + FatalErrorInFunction + << "Field sizes do not match: " << result.size() << " (" + << a.size() << ' ' << b.size() << ')' << nl + << abort(FatalError); + } + #endif + + forAll(result, i) + { + result[i] = bop(a[i], b[i]) ? a[i] : b[i]; + } +} + + +template<class T, class BoolListType, class FlipOp> +void Foam::FieldOps::ternarySelect +( + Field<T>& result, + const BoolListType& cond, + const Field<T>& a, + const Field<T>& b, + const FlipOp& flip +) +{ + #ifdef FULLDEBUG + if (result.size() != a.size() || result.size() != b.size()) + { + FatalErrorInFunction + << "Field sizes do not match: " << result.size() << " (" + << a.size() << ' ' << b.size() << ')' << nl + << abort(FatalError); + } + #endif + + forAll(result, i) + { + result[i] = flip(cond[i]) ? a[i] : b[i]; + } +} + + +template<class T, class FlipOp> +void Foam::FieldOps::ternarySelect +( + Field<T>& result, + const bitSet& cond, + const Field<T>& a, + const Field<T>& b, + const FlipOp& flip +) +{ + #ifdef FULLDEBUG + if (result.size() != a.size() || result.size() != b.size()) + { + FatalErrorInFunction + << "Field sizes do not match: " << result.size() << " (" + << a.size() << ' ' << b.size() << ')' << nl + << abort(FatalError); + } + #endif + + forAll(result, i) + { + result[i] = flip(cond[i]) ? a[i] : b[i]; + } +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/fields/Fields/Field/FieldOps.H b/src/OpenFOAM/fields/Fields/Field/FieldOps.H new file mode 100644 index 0000000000000000000000000000000000000000..47ebf2917f6b4201930ac7b595f09410d02e61d6 --- /dev/null +++ b/src/OpenFOAM/fields/Fields/Field/FieldOps.H @@ -0,0 +1,208 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. +------------------------------------------------------------------------------- +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/>. + +Namespace + Foam::FieldOps + +Description + Various utility functions to work on Fields + +SourceFiles + FieldOps.C + +\*---------------------------------------------------------------------------*/ + +#ifndef FieldOps_H +#define FieldOps_H + +#include "flipOp.H" +#include "ListOps.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace FieldOps +{ + +/*---------------------------------------------------------------------------*\ + Namespace FieldOps Declarations +\*---------------------------------------------------------------------------*/ + +//- Populate a field as the result of a unary operation on an input. +// It is permissible for inputs/outputs to refer to the same field(s), +// but partially overlapping regions are ill-defined. +// +// Examples, +// \code +// boolField result(sfield1.size()); +// +// FieldOps::assign(result, sfield1, lessOp1<scalar>(0.5)); +// FieldOps::assign(result, lfield1, std::logical_not<bool>()); +// \endcode +// +// Example of using the Random::uniformGeneratorOp unary operator +// to populate a random field, +// \code +// FieldOps::assign +// ( +// sfield, +// sfield, +// Random::uniformGeneratorOp<scalar>(-15, 25) +// ); +// \endcode +// +// \note wraps std::transform +template<class Tout, class T1, class UnaryOp> +void assign +( + Field<Tout>& result, + const Field<T1>& a, + const UnaryOp& op +); + + +//- Populate a field as the result of a binary operation on two inputs. +// It is permissible for inputs/outputs to refer to the same field(s), +// but partially overlapping regions are ill-defined. +// +// Examples, +// \code +// FieldOps::assign(result, sfield1, sfield2, std::less<scalar>()); +// FieldOps::assign(result, lfield1, lfield2, std::logical_or<bool>()); +// \endcode +// +// \note wraps std::transform +template<class Tout, class T1, class T2, class BinaryOp> +void assign +( + Field<Tout>& result, + const Field<T1>& a, + const Field<T2>& b, + const BinaryOp& bop +); + + +//- Emulate a ternary operation, selecting values from a or b +//- depending on the binary predicate. +// +// Examples, +// \code +// FieldOps::ternary(result, sfield1, sfield2, std::less<scalar>()); +// \endcode +template<class T, class BinaryOp> +void ternary +( + Field<T>& result, + const Field<T>& a, + const Field<T>& b, + const BinaryOp& bop +); + + +//- Emulate a ternary operation, selecting values from a or b +//- depending on the conditional. +// +// The meaning of the conditional is adjusted by the flip operation, +// which is typically Foam::noOp() or Foam::flipBoolOp() +// +// Similar parameter requirements as Foam::subset() +// +// Examples, +// \code +// FieldOps::ternarySelect(result, selector, sfield1, sfield2); +// \endcode +template<class T, class BoolListType, class FlipOp> +void ternarySelect +( + Field<T>& result, + const BoolListType& cond, + const Field<T>& a, + const Field<T>& b, + const FlipOp& flip +); + + +//- Emulate a ternary operation, selecting values from a or b +//- depending on the conditional. +// +// The meaning of the conditional is adjusted by the flip operation, +// which is typically Foam::noOp() or Foam::flipBoolOp() +template<class T, class FlipOp> +void ternarySelect +( + Field<T>& result, + const bitSet& cond, + const Field<T>& a, + const Field<T>& b, + const FlipOp& flip +); + + +//- Emulated ternary operation, without condition flipping +template<class T, class BoolListType> +void ternarySelect +( + Field<T>& result, + const BoolListType& cond, + const Field<T>& a, + const Field<T>& b +) +{ + ternarySelect(result, cond, a, b, noOp()); +} + + +//- Emulated ternary operation, without condition flipping +template<class T> +void ternarySelect +( + Field<T>& result, + const bitSet& cond, + const Field<T>& a, + const Field<T>& b +) +{ + ternarySelect(result, cond, a, b, noOp()); +} + + +} // End namespace FieldOps + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "FieldOps.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldOps.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldOps.H new file mode 100644 index 0000000000000000000000000000000000000000..a7fc88765f7399ad9165f9abe333d1d2fe970446 --- /dev/null +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldOps.H @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. +------------------------------------------------------------------------------- +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/>. + +InNamespace + Foam::FieldOps + +Description + Various utility functions to work on geometric fields + +SourceFiles + GeometricFieldOps.H + +\*---------------------------------------------------------------------------*/ + +#ifndef GeometricFieldOps_H +#define GeometricFieldOps_H + +#include "FieldOps.H" +#include "GeometricField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace FieldOps +{ + +/*---------------------------------------------------------------------------*\ + Namespace FieldOps Declarations +\*---------------------------------------------------------------------------*/ + +//- Populate a geometric field as the result of a unary operation on an input. +// It is permissible for inputs/outputs to refer to the same field(s), +// but partially overlapping regions are ill-defined. +template +< + class Tout, class T1, class UnaryOp, + template<class> class PatchField, class GeoMesh +> +void assign +( + GeometricField<Tout, PatchField, GeoMesh>& result, + const GeometricField<T1, PatchField, GeoMesh>& a, + const UnaryOp& op +) +{ + FieldOps::assign + ( + result.primitiveFieldRef(), + a.primitiveField(), + op + ); + + auto& bfld = result.boundaryFieldRef(); + + const label len = bfld.size(); + + for (label i = 0; i < len; ++i) + { + FieldOps::assign + ( + bfld[i], + a.boundaryField()[i], + op + ); + } +} + + +//- Populate a geometric field from the binary operation on two inputs. +// It is permissible for inputs/outputs to refer to the same field(s), +// but partially overlapping regions are ill-defined. +template +< + class Tout, class T1, class T2, class BinaryOp, + template<class> class PatchField, class GeoMesh +> +void assign +( + GeometricField<Tout, PatchField, GeoMesh>& result, + const GeometricField<T1, PatchField, GeoMesh>& a, + const GeometricField<T1, PatchField, GeoMesh>& b, + const BinaryOp& bop +) +{ + FieldOps::assign + ( + result.primitiveFieldRef(), + a.primitiveField(), + b.primitiveField(), + bop + ); + + auto& bfld = result.boundaryFieldRef(); + + const label len = bfld.size(); + + for (label i = 0; i < len; ++i) + { + FieldOps::assign + ( + bfld[i], + a.boundaryField()[i], + b.boundaryField()[i], + bop + ); + } +} + + +//- Emulate a ternary operation, selecting values from a or b +//- depending on the binary predicate. +template +< + class T, class BinaryOp, + template<class> class PatchField, class GeoMesh +> +void ternary +( + GeometricField<T, PatchField, GeoMesh>& result, + const GeometricField<T, PatchField, GeoMesh>& a, + const GeometricField<T, PatchField, GeoMesh>& b, + const BinaryOp& bop +) +{ + FieldOps::ternary + ( + result.primitiveFieldRef(), + a.primitiveField(), + b.primitiveField(), + bop + ); + + auto& bfld = result.boundaryFieldRef(); + + const label len = bfld.size(); + + for (label i = 0; i < len; ++i) + { + FieldOps::ternary + ( + bfld[i], + a.boundaryField()[i], + b.boundaryField()[i], + bop + ); + } +} + + +//- Emulate a ternary operation, selecting field values from a or b +//- depending on the conditional. +// +// Since boolean fields are not normally used, a flip operation is +// a general requirement. +template +< + class T, class BoolType, class FlipOp, + template<class> class PatchField, class GeoMesh +> +void ternarySelect +( + GeometricField<T, PatchField, GeoMesh>& result, + const GeometricField<BoolType, PatchField, GeoMesh>& cond, + const GeometricField<T, PatchField, GeoMesh>& a, + const GeometricField<T, PatchField, GeoMesh>& b, + const FlipOp& flip +) +{ + FieldOps::ternarySelect + ( + result.primitiveFieldRef(), + cond.primitiveField(), + a.primitiveField(), + b.primitiveField(), + flip + ); + + auto& bfld = result.boundaryFieldRef(); + + const label len = bfld.size(); + + for (label i = 0; i < len; ++i) + { + FieldOps::ternarySelect + ( + bfld[i], + cond.boundaryField()[i], + a.boundaryField()[i], + b.boundaryField()[i], + flip + ); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace FieldOps +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //