mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add FieldOps with conditionals (assignment, ternary)
This commit is contained in:
committed by
Andrew Heather
parent
fae91edd85
commit
73425eb119
157
src/OpenFOAM/fields/Fields/Field/FieldOps.C
Normal file
157
src/OpenFOAM/fields/Fields/Field/FieldOps.C
Normal file
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
208
src/OpenFOAM/fields/Fields/Field/FieldOps.H
Normal file
208
src/OpenFOAM/fields/Fields/Field/FieldOps.H
Normal file
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user