Compare commits

..

1 Commits

Author SHA1 Message Date
b5aa32f0ef ENH: provide field functions with inplace/non-inplace variants
- the field functions use a variety of TFOR_ALL... macros to handle
  the field loops. However, these all have a __restrict__ keyword
  buried in the list access functions. This means that any operations
  with identical input and output violate the __restrict__ contract
  and this may be responsible for some of odd results seen with
  particular compiler versions.

- updated the macros into inplace and non-inplace versions with an
  additional rename. For example,

  previous:

     TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2)

  updated:

      TSEQ_FORALL_F_OP_FUNC_F(f1, OP, FUNC, f2)
      TSEQ_FORALL_F_OP_FUNC_F_inplace(f1, OP, FUNC, f2)

  The updated versions now start with a 'TSEQ_FORALL_' prefix to
  indicate that they roughly correspond to a <std::execution::seq>
  execution policy. The change of name is also useful since they are
  now also written supplying the parameter data types.

  The solution is still not necessarily optimal, since it involves a
  run-time check and more writing. For example,
  ```
  if (result.cdata_bytes() == f1.cdata_bytes())
  {
      // std::for_each
      TSEQ_FORALL_F_OP_F_FUNC_inplace(result, =, f1, T)
  }
  else
  {
      // std::transform
      TSEQ_FORALL_F_OP_F_FUNC(result, =, f1, T)
  }
  ```
  However, the check is cheap and is only done once (outside of the loop).

- possibly related to #2925, #3024, #3091, #3166
2024-06-28 11:09:46 +02:00
64 changed files with 1659 additions and 1132 deletions

View File

@ -1,7 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats

View File

@ -34,84 +34,23 @@ Description
Convert legacy VTK file (ascii) containing an unstructured grid
to an OpenFOAM mesh without boundary information.
Usage
\b vtkUnstructuredToFoam \<XXX.vtk\>
Options:
- \par -no-fields
Do not attempt to recreate volFields
Note
The .vtk format does not contain any boundary information.
It is purely a description of the internal mesh. This also limits the
usefulness of reconstructing the volFields.
It is purely a description of the internal mesh.
Not extensively tested.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "fvMesh.H"
#include "polyMesh.H"
#include "IFstream.H"
#include "vtkUnstructuredReader.H"
#include "columnFvMesh.H"
#include "scalarIOField.H"
#include "vectorIOField.H"
#include "volFields.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void constructVolFields(fvMesh& mesh, const vtkUnstructuredReader& reader)
{
const auto fields(reader.cellData().csorted<IOField<Type>>());
for (const auto& field : fields)
{
Info<< "Constructing volField " << field.name() << endl;
// field is
// - cell data followed by
// - boundary face data
auto tfld = GeometricField<Type, fvPatchField, volMesh>::New
(
field.name(),
mesh,
dimless
);
auto& fld = tfld.ref();
fld.instance() = mesh.time().timeName();
fld.writeOpt() = IOobject::AUTO_WRITE;
// Fill cell values
fld.internalFieldRef().field() =
UIndirectList<Type>(field, reader.cellMap());
// Fill boundary values
const auto& map = reader.faceMap();
if (map.size())
{
for (auto& pfld : fld.boundaryFieldRef())
{
const auto& pp = pfld.patch();
forAll(pfld, i)
{
const label bFacei = pp.patch().offset()+i;
pfld[i] = field[map[bFacei]];
}
}
}
regIOobject::store(std::move(tfld));
}
}
int main(int argc, char *argv[])
{
@ -122,14 +61,11 @@ int main(int argc, char *argv[])
);
argList::noParallel();
argList::addOptionCompat("no-fields", {"noFields", 2106});
argList::addArgument("vtk-file", "The input legacy ascii vtk file");
#include "setRootCase.H"
#include "createTime.H"
const bool doFields = !args.found("no-fields");
IFstream mshStream(args.get<fileName>(1));
vtkUnstructuredReader reader(runTime, mshStream);
@ -160,24 +96,6 @@ int main(int argc, char *argv[])
mesh.removeFiles();
mesh.write();
if (doFields)
{
// Re-read mesh as fvMesh so we can have fields
Info<< "Re-reading mesh ..." << endl;
#include "createMesh.H"
constructVolFields<scalar>(mesh, reader);
constructVolFields<vector>(mesh, reader);
constructVolFields<sphericalTensor>(mesh, reader);
constructVolFields<symmTensor>(mesh, reader);
constructVolFields<tensor>(mesh, reader);
// No need to write the mesh, only fields
mesh.thisDb().write();
}
Info<< "End\n" << endl;
return 0;

View File

@ -83,10 +83,6 @@ Note
pitch (rotation about y)
yaw (rotation about z)
- with -rotate and two exactly opposing vectors it will actually mirror
the geometry. Use any of the other rotation options instead or use
two steps, each 90 degrees.
\*---------------------------------------------------------------------------*/
#include "argList.H"

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,6 +40,15 @@ namespace Foam
template<class TypeR, class Type1, class GeoMesh>
struct reuseTmpDimensionedField
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<DimensionedField<Type1, GeoMesh>>& tf1
)
{
return false;
}
//- Pass-through to New DimensionedField
static tmp<DimensionedField<TypeR, GeoMesh>> New
(
@ -79,6 +88,15 @@ struct reuseTmpDimensionedField
template<class TypeR, class GeoMesh>
struct reuseTmpDimensionedField<TypeR, TypeR, GeoMesh>
{
//- Identical types: possibly reusable
static bool reusable
(
const tmp<DimensionedField<TypeR, GeoMesh>>& tf1
)
{
return tf1.movable();
}
//- Allow optional copy assignment of the initial content
//- for identical input and output types
static tmp<DimensionedField<TypeR, GeoMesh>> New
@ -137,9 +155,22 @@ tmp<DimensionedField<TypeR, GeoMesh>> New
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Two-parameter versions
template<class TypeR, class Type1, class Type12, class Type2, class GeoMesh>
struct reuseTmpTmpDimensionedField
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<DimensionedField<Type1, GeoMesh>>& tf1,
const tmp<DimensionedField<Type2, GeoMesh>>& tf2
)
{
return false;
}
static tmp<DimensionedField<TypeR, GeoMesh>> New
(
const tmp<DimensionedField<Type1, GeoMesh>>& tf1,
@ -163,6 +194,17 @@ struct reuseTmpTmpDimensionedField
template<class TypeR, class Type1, class Type12, class GeoMesh>
struct reuseTmpTmpDimensionedField<TypeR, Type1, Type12, TypeR, GeoMesh>
{
//- Second input has return type: possibly reusable
static bool reusable
(
const tmp<DimensionedField<Type1, GeoMesh>>& tf1,
const tmp<DimensionedField<TypeR, GeoMesh>>& tf2
)
{
return tf2.movable();
}
//- Second input has return type
static tmp<DimensionedField<TypeR, GeoMesh>> New
(
const tmp<DimensionedField<Type1, GeoMesh>>& tf1,
@ -195,6 +237,17 @@ struct reuseTmpTmpDimensionedField<TypeR, Type1, Type12, TypeR, GeoMesh>
template<class TypeR, class Type2, class GeoMesh>
struct reuseTmpTmpDimensionedField<TypeR, TypeR, TypeR, Type2, GeoMesh>
{
//- First input has return type: possibly reusable
static bool reusable
(
const tmp<DimensionedField<TypeR, GeoMesh>>& tf1,
const tmp<DimensionedField<Type2, GeoMesh>>& tf2
)
{
return tf1.movable();
}
//- First input has return type
static tmp<DimensionedField<TypeR, GeoMesh>> New
(
const tmp<DimensionedField<TypeR, GeoMesh>>& tf1,
@ -227,6 +280,17 @@ struct reuseTmpTmpDimensionedField<TypeR, TypeR, TypeR, Type2, GeoMesh>
template<class TypeR, class GeoMesh>
struct reuseTmpTmpDimensionedField<TypeR, TypeR, TypeR, TypeR, GeoMesh>
{
//- Both inputs have return type: possibly reusable
static bool reusable
(
const tmp<DimensionedField<TypeR, GeoMesh>>& tf1,
const tmp<DimensionedField<TypeR, GeoMesh>>& tf2
)
{
return (tf1.movable() || tf2.movable());
}
//- Both inputs have return type
static tmp<DimensionedField<TypeR, GeoMesh>> New
(
const tmp<DimensionedField<TypeR, GeoMesh>>& tf1,

View File

@ -47,9 +47,9 @@ void component
const direction d
)
{
const label loopLen = (sf).size();
const label loop_len = (sf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
component(sf[i], f[i], d);
}
@ -59,9 +59,9 @@ void component
template<template<class> class Field, class Type>
void T(FieldField<Field, Type>& f1, const FieldField<Field, Type>& f2)
{
const label loopLen = (f1).size();
const label loop_len = (f1).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
T(f1[i], f2[i]);
}
@ -75,9 +75,9 @@ void pow
const FieldField<Field, Type>& vf
)
{
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
pow(f[i], vf[i]);
}
@ -122,9 +122,9 @@ void sqr
const FieldField<Field, Type>& vf
)
{
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
sqr(f[i], vf[i]);
}
@ -163,9 +163,9 @@ void magSqr
const FieldField<Field, Type>& f
)
{
const label loopLen = (sf).size();
const label loop_len = (sf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
magSqr(sf[i], f[i]);
}
@ -204,9 +204,9 @@ void mag
const FieldField<Field, Type>& f
)
{
const label loopLen = (sf).size();
const label loop_len = (sf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
mag(sf[i], f[i]);
}
@ -245,9 +245,9 @@ void cmptMax
const FieldField<Field, Type>& f
)
{
const label loopLen = (cf).size();
const label loop_len = (cf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
cmptMax(cf[i], f[i]);
}
@ -290,9 +290,9 @@ void cmptMin
const FieldField<Field, Type>& f
)
{
const label loopLen = (cf).size();
const label loop_len = (cf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
cmptMin(cf[i], f[i]);
}
@ -335,9 +335,9 @@ void cmptAv
const FieldField<Field, Type>& f
)
{
const label loopLen = (cf).size();
const label loop_len = (cf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
cmptAv(cf[i], f[i]);
}
@ -380,9 +380,9 @@ void cmptMag
const FieldField<Field, Type>& f
)
{
const label loopLen = (cf).size();
const label loop_len = (cf).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
cmptMag(cf[i], f[i]);
}
@ -428,9 +428,9 @@ Type max(const FieldField<Field, Type>& f)
{
Type result = pTraits<Type>::min;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
if (f[i].size())
{
@ -450,9 +450,9 @@ Type min(const FieldField<Field, Type>& f)
{
Type result = pTraits<Type>::max;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
if (f[i].size())
{
@ -471,9 +471,9 @@ Type sum(const FieldField<Field, Type>& f)
{
Type result = Zero;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
result += sum(f[i]);
}
@ -490,9 +490,9 @@ typename typeOfMag<Type>::type sumMag(const FieldField<Field, Type>& f)
resultType result = Zero;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
result += sumMag(f[i]);
}
@ -507,9 +507,9 @@ Type average(const FieldField<Field, Type>& f)
{
label n = 0;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
n += f[i].size();
}
@ -535,9 +535,9 @@ MinMax<Type> minMax(const FieldField<Field, Type>& f)
{
MinMax<Type> result;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
result += minMax(f[i]);
}
@ -552,9 +552,9 @@ scalarMinMax minMaxMag(const FieldField<Field, Type>& f)
{
scalarMinMax result;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
result += minMaxMag(f[i]);
}
@ -593,9 +593,9 @@ Type gAverage(const FieldField<Field, Type>& f)
{
label n = 0;
const label loopLen = (f).size();
const label loop_len = (f).size();
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
n += f[i].size();
}
@ -672,9 +672,9 @@ void OpFunc \
const FieldField<Field2, Type2>& f2 \
) \
{ \
const label loopLen = (f).size(); \
const label loop_len = (f).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(f[i], f1[i], f2[i]); \
} \
@ -798,9 +798,9 @@ void OpFunc \
const VectorSpace<Form,Cmpt,nCmpt>& vs \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(result[i], f1[i], vs); \
} \
@ -864,9 +864,9 @@ void OpFunc \
const FieldField<Field, Type>& f1 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(result[i], vs, f1[i]); \
} \

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2022-2023 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,9 +40,9 @@ void Func \
const FieldField<Field, Type1>& f1 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
Func(result[i], f1[i]); \
} \
@ -83,9 +83,9 @@ void OpFunc \
const FieldField<Field, Type1>& f1 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(result[i], f1[i]); \
} \
@ -127,9 +127,9 @@ void Func \
const FieldField<Field, Type2>& f2 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
Func(result[i], f1[i], f2[i]); \
} \
@ -204,9 +204,9 @@ void Func \
const FieldField<Field, Type2>& f2 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
Func(result[i], s1, f2[i]); \
} \
@ -248,9 +248,9 @@ void Func \
const Type2& s2 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
Func(result[i], f1[i], s2); \
} \
@ -299,9 +299,9 @@ void OpFunc \
const FieldField<Field, Type2>& f2 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(result[i], f1[i], f2[i]); \
} \
@ -376,9 +376,9 @@ void OpFunc \
const FieldField<Field, Type2>& f2 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(result[i], s1, f2[i]); \
} \
@ -420,9 +420,9 @@ void OpFunc \
const Type2& s2 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
OpFunc(result[i], f1[i], s2); \
} \
@ -472,9 +472,9 @@ void Func \
const FieldField<Field, Type3>& f3 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
Func(result[i], f1[i], f2[i], f3[i]); \
} \
@ -625,9 +625,9 @@ void Func \
const Type3& s3 \
) \
{ \
const label loopLen = (result).size(); \
const label loop_len = (result).size(); \
\
for (label i = 0; i < loopLen; ++i) \
for (label i = 0; i < loop_len; ++i) \
{ \
Func(result[i], f1[i], f2[i], s3); \
} \

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,6 +40,15 @@ namespace Foam
template<template<class> class Field, class TypeR, class Type1>
struct reuseTmpFieldField
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<FieldField<Field, Type1>>& tf1
)
{
return false;
}
//- Pass-through to NewCalculatedType
static tmp<FieldField<Field, TypeR>> New
(
@ -63,6 +72,15 @@ struct reuseTmpFieldField
template<template<class> class Field, class TypeR>
struct reuseTmpFieldField<Field, TypeR, TypeR>
{
//- Identical types: possibly reusable
static bool reusable
(
const tmp<FieldField<Field, TypeR>>& tf1
)
{
return tf1.movable();
}
//- Identical input and return types:
//- allow optional copy assignment of the initial content
static tmp<FieldField<Field, TypeR>> New
@ -76,11 +94,13 @@ struct reuseTmpFieldField<Field, TypeR, TypeR>
return tf1;
}
auto tresult = FieldField<Field, TypeR>::NewCalculatedType(tf1());
const auto& f1 = tf1();
auto tresult = FieldField<Field, TypeR>::NewCalculatedType(f1);
if (initCopy)
{
tresult.ref() = tf1();
tresult.ref() = f1;
}
return tresult;
@ -113,6 +133,16 @@ template
>
struct reuseTmpTmpFieldField
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<FieldField<Field, Type1>>& tf1,
const tmp<FieldField<Field, Type2>>& tf2
)
{
return false;
}
//- Dissimilar types: just use size
static tmp<FieldField<Field, TypeR>> New
(
@ -128,6 +158,16 @@ struct reuseTmpTmpFieldField
template<template<class> class Field, class TypeR, class Type1, class Type12>
struct reuseTmpTmpFieldField<Field, TypeR, Type1, Type12, TypeR>
{
//- Second input has return type: possibly reusable
static bool movable
(
const tmp<FieldField<Field, Type1>>& tf1,
const tmp<FieldField<Field, TypeR>>& tf2
)
{
return tf2.movable();
}
//- Second input has return type
static tmp<FieldField<Field, TypeR>> New
(
@ -148,6 +188,16 @@ struct reuseTmpTmpFieldField<Field, TypeR, Type1, Type12, TypeR>
template<template<class> class Field, class TypeR, class Type2>
struct reuseTmpTmpFieldField<Field, TypeR, TypeR, TypeR, Type2>
{
//- First input has return type: possibly reusable
static bool reusable
(
const tmp<FieldField<Field, TypeR>>& tf1,
const tmp<FieldField<Field, Type2>>& tf2
)
{
return tf1.movable();
}
//- First input has return type
static tmp<FieldField<Field, TypeR>> New
(
@ -168,6 +218,16 @@ struct reuseTmpTmpFieldField<Field, TypeR, TypeR, TypeR, Type2>
template<template<class> class Field, class TypeR>
struct reuseTmpTmpFieldField<Field, TypeR, TypeR, TypeR, TypeR>
{
//- Both inputs have return type: possibly reusable
static bool reusable
(
const tmp<FieldField<Field, TypeR>>& tf1,
const tmp<FieldField<Field, TypeR>>& tf2
)
{
return (tf1.movable() || tf2.movable());
}
//- Both inputs have return type
static tmp<FieldField<Field, TypeR>> New
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -599,7 +599,8 @@ void Foam::Field<Type>::rmap
template<class Type>
void Foam::Field<Type>::negate()
{
TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
// std::for_each
TSEQ_FORALL_F_OP_OP_F_inplace(*this, =, -, *this)
}
@ -629,8 +630,16 @@ void Foam::Field<Type>::replace
const UList<cmptType>& sf
)
{
TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
cmptType, sf)
if (this->cdata_bytes() == sf.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(*this, ., replace, d, sf)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_S_F(*this, ., replace, d, sf)
}
}
@ -653,8 +662,7 @@ void Foam::Field<Type>::replace
const cmptType& c
)
{
TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
cmptType, c)
TSEQ_FORALL_F_OP_FUNC_S_S(*this, ., replace, d, c)
}
@ -778,7 +786,7 @@ template<class Type>
template<class Form, class Cmpt, Foam::direction nCmpt>
void Foam::Field<Type>::operator=(const VectorSpace<Form,Cmpt,nCmpt>& vs)
{
TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
TSEQ_FORALL_F_OP_S(*this, =, vs)
}
@ -787,7 +795,16 @@ void Foam::Field<Type>::operator=(const VectorSpace<Form,Cmpt,nCmpt>& vs)
template<class Type> \
void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
{ \
TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
if (this->cdata_bytes() == f.cdata_bytes()) \
{ \
/* std::for_each */ \
TSEQ_FORALL_F_OP_F_inplace(*this, op, f) \
} \
else \
{ \
/* std::transform */ \
TSEQ_FORALL_F_OP_F(*this, op, f) \
} \
} \
\
template<class Type> \
@ -800,7 +817,7 @@ void Foam::Field<Type>::operator op(const tmp<Field<TYPE>>& tf) \
template<class Type> \
void Foam::Field<Type>::operator op(const TYPE& t) \
{ \
TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
TSEQ_FORALL_F_OP_S(*this, op, t) \
}
COMPUTED_ASSIGNMENT(Type, +=)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,19 +47,32 @@ void component
const direction d
)
{
typedef typename Field<Type>::cmptType resultType;
TFOR_ALL_F_OP_F_FUNC_S
(
resultType, result, =, Type, f1, .component, const direction, d
)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_F_FUNC_S_inplace(result, =, f1, .component, d)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_F_FUNC_S(result, =, f1, .component, d)
}
}
template<class Type>
void T(Field<Type>& result, const UList<Type>& f1)
{
TFOR_ALL_F_OP_F_FUNC(Type, result, =, Type, f1, T)
if (result.cdata() == f1.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_F_FUNC_inplace(result, =, f1, T)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_F_FUNC(result, =, f1, T)
}
}
@ -72,11 +85,19 @@ void pow
{
typedef typename powProduct<Type, r>::type resultType;
TFOR_ALL_F_OP_FUNC_F_S
(
resultType, result, =, pow, Type, f1, resultType,
pTraits<resultType>::zero
)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_S_inplace
(result, =, pow, f1, pTraits<resultType>::zero)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F_S
(result, =, pow, f1, pTraits<resultType>::zero)
}
}
template<class Type, direction r>
@ -116,9 +137,16 @@ void sqr
const UList<Type>& f1
)
{
typedef typename outerProduct<Type, Type>::type resultType;
TFOR_ALL_F_OP_FUNC_F(resultType, result, =, sqr, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, sqr, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, sqr, f1)
}
}
template<class Type>
@ -150,9 +178,16 @@ void magSqr
const UList<Type>& f1
)
{
typedef typename typeOfMag<Type>::type resultType;
TFOR_ALL_F_OP_FUNC_F(resultType, result, =, magSqr, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, magSqr, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, magSqr, f1)
}
}
template<class Type>
@ -186,9 +221,16 @@ void mag
const UList<Type>& f1
)
{
typedef typename typeOfMag<Type>::type resultType;
TFOR_ALL_F_OP_FUNC_F(resultType, result, =, mag, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, mag, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, mag, f1)
}
}
template<class Type>
@ -222,9 +264,16 @@ void cmptMax
const UList<Type>& f1
)
{
typedef typename Field<Type>::cmptType resultType;
TFOR_ALL_F_OP_FUNC_F(resultType, result, =, cmptMax, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, cmptMax, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, cmptMax, f1)
}
}
template<class Type>
@ -254,9 +303,16 @@ void cmptMin
const UList<Type>& f1
)
{
typedef typename Field<Type>::cmptType resultType;
TFOR_ALL_F_OP_FUNC_F(resultType, result, =, cmptMin, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, cmptMin, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, cmptMin, f1)
}
}
template<class Type>
@ -286,9 +342,16 @@ void cmptAv
const UList<Type>& f1
)
{
typedef typename Field<Type>::cmptType resultType;
TFOR_ALL_F_OP_FUNC_F(resultType, result, =, cmptAv, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, cmptAv, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, cmptAv, f1)
}
}
template<class Type>
@ -314,7 +377,16 @@ tmp<Field<typename Field<Type>::cmptType>> cmptAv(const tmp<Field<Type>>& tf1)
template<class Type>
void cmptMag(Field<Type>& result, const UList<Type>& f1)
{
TFOR_ALL_F_OP_FUNC_F(Type, result, =, cmptMag, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, cmptMag, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, cmptMag, f1)
}
}
template<class Type>
@ -338,7 +410,16 @@ tmp<Field<Type>> cmptMag(const tmp<Field<Type>>& tf1)
template<class Type>
void cmptMagSqr(Field<Type>& result, const UList<Type>& f1)
{
TFOR_ALL_F_OP_FUNC_F(Type, result, =, cmptMagSqr, Type, f1)
if (result.cdata_bytes() == f1.cdata_bytes())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, cmptMagSqr, f1)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F(result, =, cmptMagSqr, f1)
}
}
template<class Type>
@ -375,7 +456,7 @@ Type max(const UList<Type>& f1)
if (f1.size())
{
Type result(f1[0]);
TFOR_ALL_S_OP_FUNC_F_S(Type, result, =, max, Type, f1, Type, result)
TSEQ_FORALL_S_OP_FUNC_F_S(result, =, max, f1, result)
return result;
}
@ -390,7 +471,7 @@ Type min(const UList<Type>& f1)
if (f1.size())
{
Type result(f1[0]);
TFOR_ALL_S_OP_FUNC_F_S(Type, result, =, min, Type, f1, Type, result)
TSEQ_FORALL_S_OP_FUNC_F_S(result, =, min, f1, result)
return result;
}
@ -409,7 +490,7 @@ Type sum(const UList<Type>& f1)
if (f1.size())
{
// Use resultType() as functional cast
TFOR_ALL_S_OP_FUNC_F(resultType, result, +=, resultType, Type, f1)
TSEQ_FORALL_S_OP_FUNC_F(result, +=, resultType, f1)
}
return Type(result);
@ -432,15 +513,12 @@ Type maxMagSqr(const UList<Type>& f1)
if (f1.size())
{
Type result(f1[0]);
TFOR_ALL_S_OP_FUNC_F_S
TSEQ_FORALL_S_OP_FUNC_F_S
(
Type,
result,
=,
maxMagSqrOp<Type>(),
Type,
f1,
Type,
result
)
return result;
@ -457,15 +535,12 @@ Type minMagSqr(const UList<Type>& f1)
if (f1.size())
{
Type result(f1[0]);
TFOR_ALL_S_OP_FUNC_F_S
TSEQ_FORALL_S_OP_FUNC_F_S
(
Type,
result,
=,
minMagSqrOp<Type>(),
Type,
f1,
Type,
result
)
return result;
@ -485,7 +560,8 @@ sumProd(const UList<Type>& f1, const UList<Type>& f2)
resultType result = Zero;
if (f1.size() && (f1.size() == f2.size()))
{
TFOR_ALL_S_OP_F_OP_F(resultType, result, +=, Type, f1, &&, Type, f2)
// std::transform
TSEQ_FORALL_S_OP_F_OP_F(result, +=, f1, &&, f2)
}
return result;
}
@ -497,15 +573,12 @@ Type sumCmptProd(const UList<Type>& f1, const UList<Type>& f2)
Type result = Zero;
if (f1.size() && (f1.size() == f2.size()))
{
TFOR_ALL_S_OP_FUNC_F_F
TSEQ_FORALL_S_OP_FUNC_F_F
(
Type,
result,
+=,
cmptMultiply,
Type,
f1,
Type,
f2
)
}
@ -522,7 +595,7 @@ sumSqr(const UList<Type>& f1)
resultType result = Zero;
if (f1.size())
{
TFOR_ALL_S_OP_FUNC_F(resultType, result, +=, sqr, Type, f1)
TSEQ_FORALL_S_OP_FUNC_F(result, +=, sqr, f1)
}
return result;
}
@ -547,7 +620,7 @@ sumMag(const UList<Type>& f1)
resultType result = Zero;
if (f1.size())
{
TFOR_ALL_S_OP_FUNC_F(resultType, result, +=, mag, Type, f1)
TSEQ_FORALL_S_OP_FUNC_F(result, +=, mag, f1)
}
return result;
}
@ -561,7 +634,7 @@ Type sumCmptMag(const UList<Type>& f1)
Type result = Zero;
if (f1.size())
{
TFOR_ALL_S_OP_FUNC_F(Type, result, +=, cmptMag, Type, f1)
TSEQ_FORALL_S_OP_FUNC_F(result, +=, cmptMag, f1)
}
return result;
}
@ -773,8 +846,20 @@ void OpFunc \
const UList<Type2>& f2 \
) \
{ \
typedef typename product<Type1, Type2>::type resultType; \
TFOR_ALL_F_OP_F_OP_F(resultType, result, =, Type1, f1, Op, Type2, f2) \
if \
( \
result.cdata_bytes() == f1.cdata_bytes() \
|| result.cdata_bytes() == f2.cdata_bytes() \
) \
{ \
/* std::for_each */ \
TSEQ_FORALL_F_OP_F_OP_F_inplace(result, =, f1, Op, f2) \
} \
else \
{ \
/* std::transform */ \
TSEQ_FORALL_F_OP_F_OP_F(result, =, f1, Op, f2) \
} \
} \
\
template<class Type1, class Type2> \
@ -829,9 +914,21 @@ void OpFunc \
const VectorSpace<Form,Cmpt,nCmpt>& vs \
) \
{ \
typedef typename product<Type, Form>::type resultType; \
TFOR_ALL_F_OP_F_OP_S \
(resultType, result, =,Type, f1, Op, Form, static_cast<const Form&>(vs))\
if \
( \
result.cdata_bytes() == f1.cdata_bytes() \
) \
{ \
/* std::for_each */ \
TSEQ_FORALL_F_OP_F_OP_S_inplace \
(result, =, f1, Op, static_cast<const Form&>(vs)) \
} \
else \
{ \
/* std::transform */ \
TSEQ_FORALL_F_OP_F_OP_S \
(result, =, f1, Op, static_cast<const Form&>(vs)) \
} \
} \
\
template<class Type, class Form, class Cmpt, direction nCmpt> \
@ -867,9 +964,21 @@ void OpFunc \
const UList<Type>& f1 \
) \
{ \
typedef typename product<Form, Type>::type resultType; \
TFOR_ALL_F_OP_S_OP_F \
(resultType, result, =,Form,static_cast<const Form&>(vs), Op, Type, f1)\
if \
( \
result.cdata_bytes() == f1.cdata_bytes() \
) \
{ \
/* std::for_each */ \
TSEQ_FORALL_F_OP_S_OP_F_inplace \
(result, =, static_cast<const Form&>(vs), Op, f1) \
} \
else \
{ \
/* std::transform */ \
TSEQ_FORALL_F_OP_S_OP_F \
(result, =, static_cast<const Form&>(vs), Op, f1) \
} \
} \
\
template<class Form, class Cmpt, direction nCmpt, class Type> \

View File

@ -40,7 +40,14 @@ void Func \
const UList<Type1>& f1 \
) \
{ \
TFOR_ALL_F_OP_FUNC_F(ReturnType, result, =, ::Foam::Func, Type1, f1) \
if (result.cdata_bytes() == f1.cdata_bytes()) \
{ \
TSEQ_FORALL_F_OP_FUNC_F_inplace(result, =, ::Foam::Func, f1) \
} \
else \
{ \
TSEQ_FORALL_F_OP_FUNC_F(result, =, ::Foam::Func, f1) \
} \
} \
\
TEMPLATE \
@ -78,7 +85,14 @@ void OpFunc \
const UList<Type1>& f1 \
) \
{ \
TFOR_ALL_F_OP_OP_F(ReturnType, result, =, Op, Type1, f1) \
if (result.cdata_bytes() == f1.cdata_bytes()) \
{ \
TSEQ_FORALL_F_OP_OP_F_inplace(result, =, Op, f1) \
} \
else \
{ \
TSEQ_FORALL_F_OP_OP_F(result, =, Op, f1) \
} \
} \
\
TEMPLATE \
@ -117,10 +131,18 @@ void Func \
const UList<Type2>& f2 \
) \
{ \
TFOR_ALL_F_OP_FUNC_F_F \
if \
( \
ReturnType, result, =, ::Foam::Func, Type1, f1, Type2, f2 \
result.cdata_bytes() == f1.cdata_bytes() \
|| result.cdata_bytes() == f2.cdata_bytes() \
) \
{ \
TSEQ_FORALL_F_OP_FUNC_F_F_inplace(result, =, ::Foam::Func, f1, f2) \
} \
else \
{ \
TSEQ_FORALL_F_OP_FUNC_F_F(result, =, ::Foam::Func, f1, f2) \
} \
}
#define BINARY_FUNCTION_INTERFACE(ReturnType, Type1, Type2, Func) \
@ -194,10 +216,14 @@ void Func \
const UList<Type2>& f2 \
) \
{ \
TFOR_ALL_F_OP_FUNC_S_F \
( \
ReturnType, result, =, ::Foam::Func, Type1, s1, Type2, f2 \
) \
if (result.cdata_bytes() == f2.cdata_bytes()) \
{ \
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(result, =, ::Foam::Func, s1, f2) \
} \
else \
{ \
TSEQ_FORALL_F_OP_FUNC_S_F(result, =, ::Foam::Func, s1, f2) \
} \
}
#define BINARY_FUNCTION_INTERFACE_SF(ReturnType, Type1, Type2, Func) \
@ -242,10 +268,14 @@ void Func \
const Type2& s2 \
) \
{ \
TFOR_ALL_F_OP_FUNC_F_S \
( \
ReturnType, result, =, ::Foam::Func, Type1, f1, Type2, s2 \
) \
if (result.cdata_bytes() == f1.cdata_bytes()) \
{ \
TSEQ_FORALL_F_OP_FUNC_F_S_inplace(result, =, ::Foam::Func, f1, s2) \
} \
else \
{ \
TSEQ_FORALL_F_OP_FUNC_F_S(result, =, ::Foam::Func, f1, s2) \
} \
}
#define BINARY_FUNCTION_INTERFACE_FS(ReturnType, Type1, Type2, Func) \
@ -297,7 +327,18 @@ void OpFunc \
const UList<Type2>& f2 \
) \
{ \
TFOR_ALL_F_OP_F_OP_F(ReturnType, result, =, Type1, f1, Op, Type2, f2) \
if \
( \
result.cdata_bytes() == f1.cdata_bytes() \
|| result.cdata_bytes() == f2.cdata_bytes() \
) \
{ \
TSEQ_FORALL_F_OP_F_OP_F_inplace(result, =, f1, Op, f2) \
} \
else \
{ \
TSEQ_FORALL_F_OP_F_OP_F(result, =, f1, Op, f2) \
} \
} \
\
TEMPLATE \
@ -365,7 +406,14 @@ void OpFunc \
const UList<Type2>& f2 \
) \
{ \
TFOR_ALL_F_OP_S_OP_F(ReturnType, result, =, Type1, s1, Op, Type2, f2) \
if (result.cdata_bytes() == f2.cdata_bytes()) \
{ \
TSEQ_FORALL_F_OP_S_OP_F_inplace(result, =, s1, Op, f2) \
} \
else \
{ \
TSEQ_FORALL_F_OP_S_OP_F(result, =, s1, Op, f2) \
} \
} \
\
TEMPLATE \
@ -404,7 +452,14 @@ void OpFunc \
const Type2& s2 \
) \
{ \
TFOR_ALL_F_OP_F_OP_S(ReturnType, result, =, Type1, f1, Op, Type2, s2) \
if (result.cdata_bytes() == f1.cdata_bytes()) \
{ \
TSEQ_FORALL_F_OP_F_OP_S_inplace(result, =, f1, Op, s2) \
} \
else \
{ \
TSEQ_FORALL_F_OP_F_OP_S(result, =, f1, Op, s2) \
} \
} \
\
TEMPLATE \
@ -451,10 +506,21 @@ void Func \
const UList<Type3>& f3 \
) \
{ \
TFOR_ALL_F_OP_FUNC_F_F_F \
if \
( \
ReturnType, result, =, ::Foam::Func, Type1, f1, Type2, f2, Type3, f3 \
result.cdata_bytes() == f1.cdata_bytes() \
|| result.cdata_bytes() == f2.cdata_bytes() \
|| result.cdata_bytes() == f3.cdata_bytes() \
) \
{ \
TSEQ_FORALL_F_OP_FUNC_F_F_F_inplace \
(result, =, ::Foam::Func, f1, f2, f3) \
} \
else \
{ \
TSEQ_FORALL_F_OP_FUNC_F_F_F \
(result, =, ::Foam::Func, f1, f2, f3) \
} \
} \
\
TEMPLATE \
@ -586,10 +652,20 @@ void Func \
const Type3& s3 \
) \
{ \
TFOR_ALL_F_OP_FUNC_F_F_S \
if \
( \
ReturnType, result, =, ::Foam::Func, Type1, f1, Type2, f2, Type3, s3 \
result.cdata_bytes() == f1.cdata_bytes() \
|| result.cdata_bytes() == f2.cdata_bytes() \
) \
{ \
TSEQ_FORALL_F_OP_FUNC_F_F_S_inplace \
(result, =, ::Foam::Func, f1, f2, s3) \
} \
else \
{ \
TSEQ_FORALL_F_OP_FUNC_F_F_S \
(result, =, ::Foam::Func, f1, f2, s3) \
} \
} \
\
TEMPLATE \

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2022-2023 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,8 +32,8 @@ Description
#ifndef Foam_FieldM_H
#define Foam_FieldM_H
#include "error.H"
#include "ListLoopM.H" // For list access macros
#include "errorCheckFields.H" // Field size checks (fulldebug mode)
#include "ListLoopM.H" // List access macros
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -42,126 +42,20 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef FULLDEBUG
template<class Type1, class Type2>
void checkFields
(
const UList<Type1>& f1,
const UList<Type2>& f2,
const char* op
)
{
if (f1.size() != f2.size())
{
FatalErrorInFunction
<< " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
<< " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
<< endl
<< " for operation " << op
<< abort(FatalError);
}
}
template<class Type1, class Type2, class Type3>
void checkFields
(
const UList<Type1>& f1,
const UList<Type2>& f2,
const UList<Type3>& f3,
const char* op
)
{
if (f1.size() != f2.size() || f1.size() != f3.size())
{
FatalErrorInFunction
<< " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
<< ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
<< " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
<< endl
<< " for operation " << op
<< abort(FatalError);
}
}
template<class Type1, class Type2, class Type3, class Type4>
void checkFields
(
const UList<Type1>& f1,
const UList<Type2>& f2,
const UList<Type3>& f3,
const UList<Type4>& f4,
const char* op
)
{
if
(
f1.size() != f2.size()
|| f1.size() != f3.size()
|| f1.size() != f4.size()
)
{
FatalErrorInFunction
<< " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
<< ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
<< ", Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
<< " and Field<"<<pTraits<Type4>::typeName<<"> f4("<<f4.size()<<')'
<< endl
<< " for operation " << op
<< abort(FatalError);
}
}
#else
template<class Type1, class Type2>
void checkFields
(
const UList<Type1>&,
const UList<Type2>&,
const char*
)
{}
template<class Type1, class Type2, class Type3>
void checkFields
(
const UList<Type1>&,
const UList<Type2>&,
const UList<Type3>&,
const char*
)
{}
template<class Type1, class Type2, class Type3, class Type4>
void checkFields
(
const UList<Type1>&,
const UList<Type2>&,
const UList<Type3>&,
const UList<Type4>&,
const char*
)
{}
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ------------
// Unary Free Function : f1 OP Func(f2)
#define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \
#define TSEQ_FORALL_F_OP_FUNC_F_impl(f1, OP, FUNC, f2, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP FUNC(f2) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -170,20 +64,32 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_F(f1, OP, FUNC, f2) \
TSEQ_FORALL_F_OP_FUNC_F_impl(f1, OP, FUNC, f2, __restrict__)
#define TSEQ_FORALL_F_OP_FUNC_F_inplace(f1, OP, FUNC, f2) \
TSEQ_FORALL_F_OP_FUNC_F_impl(f1, OP, FUNC, f2,)
// old-style
#define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \
TSEQ_FORALL_F_OP_FUNC_F_impl(f1, OP, FUNC, f2, __restrict__)
// ------------
// Nullary Member Function : f1 OP f2.FUNC()
// NB: the '.' is not passed in the func parameter
#define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \
#define TSEQ_FORALL_F_OP_F_FUNC_impl(f1, OP, f2, FUNC, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP " f2" #FUNC); \
checkFields(f1, f2, "f1 " #OP " f2 ." #FUNC "()"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP f2.FUNC() */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -192,21 +98,32 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_F_FUNC(f1, OP, f2, FUNC) \
TSEQ_FORALL_F_OP_F_FUNC_impl(f1, OP, f2, FUNC, __restrict__)
#define TSEQ_FORALL_F_OP_F_FUNC_inplace(f1, OP, f2, FUNC) \
TSEQ_FORALL_F_OP_F_FUNC_impl(f1, OP, f2, FUNC,)
// old-style
#define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \
TSEQ_FORALL_F_OP_F_FUNC_impl(f1, OP, f2, FUNC, __restrict__)
// ------------
// Binary Free Function : f1 OP FUNC(f2, f3)
#define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3) \
#define TSEQ_FORALL_F_OP_FUNC_F_F_impl(f1, OP, FUNC, f2, f3, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
List_CONST_ACCESS(typeF3, f3, f3P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_CONST_ACCESS(f3, f3P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP FUNC(f2, f3) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -215,20 +132,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_F_F(f1, OP, FUNC, f2, f3) \
TSEQ_FORALL_F_OP_FUNC_F_F_impl(f1, OP, FUNC, f2, f3, __restrict__)
#define TSEQ_FORALL_F_OP_FUNC_F_F_inplace(f1, OP, FUNC, f2, f3) \
TSEQ_FORALL_F_OP_FUNC_F_F_impl(f1, OP, FUNC, f2, f3,)
// old-style
#define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3) \
TSEQ_FORALL_F_OP_FUNC_F_F_impl(f1, OP, FUNC, f2, f3, __restrict__)
// ------------
// [reduction] Binary Free Function : s OP FUNC(f1, f2)
#define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2) \
#define TSEQ_FORALL_S_OP_FUNC_F_F_impl(s, OP, FUNC, f1, f2, Unused) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)"); \
\
/* Field access */ \
List_CONST_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_CONST_ACCESS(f1, f1P, __restrict__); \
TFOR_List_CONST_ACCESS(f2, f2P, __restrict__); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: s OP FUNC(f1, f2) */ \
const label loop_len = (f1).size(); \
\
/* pragmas, reduction... */ \
for (label i = 0; i < loop_len; ++i) \
@ -237,20 +165,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_S_OP_FUNC_F_F(s, OP, FUNC, f1, f2) \
TSEQ_FORALL_S_OP_FUNC_F_F_impl(s, OP, FUNC, f1, f2, __restrict__)
#define TSEQ_FORALL_S_OP_FUNC_F_F_inplace(s, OP, FUNC, f1, f2) \
TSEQ_FORALL_S_OP_FUNC_F_F_impl(s, OP, FUNC, f1, f2,)
// old-style
#define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2) \
TSEQ_FORALL_S_OP_FUNC_F_F_impl(s, OP, FUNC, f1, f2, __restrict__)
// ------------
// Binary Free Function : f1 OP FUNC(f2, s)
#define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s) \
#define TSEQ_FORALL_F_OP_FUNC_F_S_impl(f1, OP, FUNC, f2, s, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP FUNC(f2, s) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -259,16 +198,27 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_F_S(f1, OP, FUNC, f2, s) \
TSEQ_FORALL_F_OP_FUNC_F_S_impl(f1, OP, FUNC, f2, s, __restrict__)
#define TSEQ_FORALL_F_OP_FUNC_F_S_inplace(f1, OP, FUNC, f2, s) \
TSEQ_FORALL_F_OP_FUNC_F_S_impl(f1, OP, FUNC, f2, s,)
// old-style
#define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s) \
TSEQ_FORALL_F_OP_FUNC_F_S_impl(f1, OP, FUNC, f2, s, __restrict__)
// ------------
// [reduction] Binary Free Function : s1 OP FUNC(f, s2)
#define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2) \
#define TSEQ_FORALL_S_OP_FUNC_F_S_impl(s1, OP, FUNC, f, s2, Unused) \
{ \
/* Field access */ \
List_CONST_ACCESS(typeF, f, fP); \
TFOR_List_CONST_ACCESS(f, fP, __restrict__); \
TFOR_List_LENGTH(f, loop_len); \
\
/* Loop: s1 OP FUNC(f, s2) */ \
const label loop_len = (f).size(); \
\
/* pragmas, reduction... */ \
for (label i = 0; i < loop_len; ++i) \
@ -277,20 +227,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_S_OP_FUNC_F_S(s1, OP, FUNC, f, s2) \
TSEQ_FORALL_S_OP_FUNC_F_S_impl(s1, OP, FUNC, f, s2, __restrict__)
#define TSEQ_FORALL_S_OP_FUNC_F_S_inplace(s1, OP, FUNC, f, s2) \
TSEQ_FORALL_S_OP_FUNC_F_S_impl(s1, OP, FUNC, f, s2,)
// old-style
#define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2) \
TSEQ_FORALL_S_OP_FUNC_F_S_impl(s1, OP, FUNC, f, s2, __restrict__)
// ------------
// Binary Free Function : f1 OP FUNC(s, f2)
#define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2) \
#define TSEQ_FORALL_F_OP_FUNC_S_F_impl(f1, OP, FUNC, s, f2, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP1 f2 OP2 f3 */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -299,16 +260,27 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_S_F(f1, OP, FUNC, s, f2) \
TSEQ_FORALL_F_OP_FUNC_S_F_impl(f1, OP, FUNC, s, f2, __restrict__)
#define TSEQ_FORALL_F_OP_FUNC_S_F_inplace(f1, OP, FUNC, s, f2) \
TSEQ_FORALL_F_OP_FUNC_S_F_impl(f1, OP, FUNC, s, f2,)
// old-style
#define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2) \
TSEQ_FORALL_F_OP_FUNC_S_F_impl(f1, OP, FUNC, s, f2, __restrict__)
// ------------
// Binary Free Function : f1 OP FUNC(s1, s2)
#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2) \
#define TSEQ_FORALL_F_OP_FUNC_S_S_impl(f1, OP, FUNC, s1, s2, Unused) \
{ \
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
TFOR_List_ACCESS(f1, f1P, __restrict__); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP FUNC(s1, s2) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -317,20 +289,32 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_S_S(f1, OP, FUNC, s1, s2) \
TSEQ_FORALL_F_OP_FUNC_S_S_impl(f1, OP, FUNC, s1, s2, __restrict__)
// Unary Member Function : f1 OP f2 FUNC(s)
#define TSEQ_FORALL_F_OP_FUNC_S_S_inplace(f1, OP, FUNC, s1, s2) \
TSEQ_FORALL_F_OP_FUNC_S_S_impl(f1, OP, FUNC, s1, s2,)
#define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s) \
// old-style
#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2) \
TSEQ_FORALL_F_OP_FUNC_S_S_impl(f1, OP, FUNC, s1, s2, __restrict__)
// ------------
// Unary Member Function : f1 OP f2.FUNC(s)
// NB: the '.' is passed in the func parameter
#define TSEQ_FORALL_F_OP_F_FUNC_S_impl(f1, OP, f2, FUNC, s, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP f2 FUNC(s) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -339,25 +323,35 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_F_FUNC_S(f1, OP, f2, FUNC, s) \
TSEQ_FORALL_F_OP_F_FUNC_S_impl(f1, OP, f2, FUNC, s, __restrict__)
#define TSEQ_FORALL_F_OP_F_FUNC_S_inplace(f1, OP, f2, FUNC, s) \
TSEQ_FORALL_F_OP_F_FUNC_S_impl(f1, OP, f2, FUNC, s,)
// old-style
#define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s) \
TSEQ_FORALL_F_OP_F_FUNC_S_impl(f1, OP, f2, FUNC, s, __restrict__)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ------------
// Ternary Free Function : f1 OP FUNC(f2, f3, f4)
#define TFOR_ALL_F_OP_FUNC_F_F_F\
(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3, typeF4, f4) \
#define TSEQ_FORALL_F_OP_FUNC_F_F_F_impl(f1, OP, FUNC, f2, f3, f4, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, f3, f4, "f1 " #OP " " #FUNC "(f2, f3, f4)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
List_CONST_ACCESS(typeF3, f3, f3P); \
List_CONST_ACCESS(typeF4, f4, f4P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_CONST_ACCESS(f3, f3P, Restrict); \
TFOR_List_CONST_ACCESS(f4, f4P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP FUNC(f2, f3, f4) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -366,21 +360,32 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_F_F_F(f1, OP, FUNC, f2, f3, f4) \
TSEQ_FORALL_F_OP_FUNC_F_F_F_impl(f1, OP, FUNC, f2, f3, f4, __restrict__)
#define TSEQ_FORALL_F_OP_FUNC_F_F_F_inplace(f1, OP, FUNC, f2, f3, f4) \
TSEQ_FORALL_F_OP_FUNC_F_F_F_impl(f1, OP, FUNC, f2, f3, f4,)
// old-style
#define TFOR_ALL_F_OP_FUNC_F_F_F(type1, f1, OP, FUNC, type2, f2, type3, f3, type4, f4) \
TSEQ_FORALL_F_OP_FUNC_F_F_F_impl(f1, OP, FUNC, f2, f3, f4, __restrict__)
// ------------
// Ternary Free Function : f1 OP FUNC(f2, f3, s4)
#define TFOR_ALL_F_OP_FUNC_F_F_S\
(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3, typeF4, s4) \
#define TSEQ_FORALL_F_OP_FUNC_F_F_S_impl(f1, OP, FUNC, f2, f3, s4, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3, s)"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
List_CONST_ACCESS(typeF3, f3, f3P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_CONST_ACCESS(f3, f3P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP FUNC(f2, f3, s4) */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -389,23 +394,34 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_FUNC_F_F_S(f1, OP, FUNC, f2, f3, s4) \
TSEQ_FORALL_F_OP_FUNC_F_F_S_impl(f1, OP, FUNC, f2, f3, s4, __restrict__)
#define TSEQ_FORALL_F_OP_FUNC_F_F_S_inplace(f1, OP, FUNC, f2, f3, s4) \
TSEQ_FORALL_F_OP_FUNC_F_F_S_impl(f1, OP, FUNC, f2, f3, s4,)
// old-style
#define TFOR_ALL_F_OP_FUNC_F_F_S(type1, f1, OP, FUNC, type2, f2, type3, f3, type4, s4) \
TSEQ_FORALL_F_OP_FUNC_F_F_S_impl(f1, OP, FUNC, f2, f3, s4, __restrict__)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ------------
// Member operator : this field f1 OP1 f2 OP2 f3
#define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3) \
#define TSEQ_FORALL_F_OP_F_OP_F_impl(f1, OP1, f2, OP2, f3, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
List_CONST_ACCESS(typeF3, f3, f3P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_CONST_ACCESS(f3, f3P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP1 f2 OP2 f3 */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -414,20 +430,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_F_OP_F(f1, OP1, f2, OP2, f3) \
TSEQ_FORALL_F_OP_F_OP_F_impl(f1, OP1, f2, OP2, f3, __restrict__)
#define TSEQ_FORALL_F_OP_F_OP_F_inplace(f1, OP1, f2, OP2, f3) \
TSEQ_FORALL_F_OP_F_OP_F_impl(f1, OP1, f2, OP2, f3,)
// old-style
#define TFOR_ALL_F_OP_F_OP_F(type1, f1, OP1, type2, f2, OP2, type3, f3) \
TSEQ_FORALL_F_OP_F_OP_F_impl(f1, OP1, f2, OP2, f3, __restrict__)
// ------------
// Member operator : this field f1 OP1 s OP2 f2
#define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2) \
#define TSEQ_FORALL_F_OP_S_OP_F_impl(f1, OP1, s, OP2, f2, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP1 s OP2 f2 */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -436,20 +463,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_S_OP_F(f1, OP1, s, OP2, f2) \
TSEQ_FORALL_F_OP_S_OP_F_impl(f1, OP1, s, OP2, f2, __restrict__)
#define TSEQ_FORALL_F_OP_S_OP_F_inplace(f1, OP1, s, OP2, f2) \
TSEQ_FORALL_F_OP_S_OP_F_impl(f1, OP1, s, OP2, f2,)
// old-style
#define TFOR_ALL_F_OP_S_OP_F(type1, f1, OP1, typeS, s, OP2, type2, f2) \
TSEQ_FORALL_F_OP_S_OP_F_impl(f1, OP1, s, OP2, f2, __restrict__)
// ------------
// Member operator : this field f1 OP1 f2 OP2 s
#define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s) \
#define TSEQ_FORALL_F_OP_F_OP_S_impl(f1, OP1, f2, OP2, s, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop f1 OP1 s OP2 f2 */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -458,20 +496,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_F_OP_S(f1, OP1, f2, OP2, s) \
TSEQ_FORALL_F_OP_F_OP_S_impl(f1, OP1, f2, OP2, s, __restrict__)
#define TSEQ_FORALL_F_OP_F_OP_S_inplace(f1, OP1, f2, OP2, s) \
TSEQ_FORALL_F_OP_F_OP_S_impl(f1, OP1, f2, OP2, s,)
// old-style
#define TFOR_ALL_F_OP_F_OP_S(type1, f1, OP1, type2, f2, OP2, typeS, s) \
TSEQ_FORALL_F_OP_F_OP_S_impl(f1, OP1, f2, OP2, s, __restrict__)
// ------------
// Member operator : this field f1 OP f2
#define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2) \
#define TSEQ_FORALL_F_OP_F_impl(f1, OP, f2, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, "f1 " #OP " f2"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP f2 */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -480,20 +529,31 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_F(f1, OP, f2) \
TSEQ_FORALL_F_OP_F_impl(f1, OP, f2, __restrict__)
#define TSEQ_FORALL_F_OP_F_inplace(f1, OP, f2) \
TSEQ_FORALL_F_OP_F_impl(f1, OP, f2,)
// old-style
#define TFOR_ALL_F_OP_F(type1, f1, OP, type2, f2) \
TSEQ_FORALL_F_OP_F_impl(f1, OP, f2, __restrict__)
// ------------
// Member operator : this field f1 OP1 OP2 f2
#define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \
#define TSEQ_FORALL_F_OP_OP_F_impl(f1, OP1, OP2, f2, Restrict) \
{ \
/* Check fields have same size */ \
checkFields(f1, f2, #OP1 " " #OP2 " f2"); \
\
/* Field access */ \
List_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, Restrict); \
TFOR_List_CONST_ACCESS(f2, f2P, Restrict); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: f1 OP1 OP2 f2 */ \
const label loop_len = (f1).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -502,16 +562,27 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_OP_F(f1, OP1, OP2, f2) \
TSEQ_FORALL_F_OP_OP_F_impl(f1, OP1, OP2, f2, __restrict__)
#define TSEQ_FORALL_F_OP_OP_F_inplace(f1, OP1, OP2, f2) \
TSEQ_FORALL_F_OP_OP_F_impl(f1, OP1, OP2, f2,)
// old-style
#define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \
TSEQ_FORALL_F_OP_OP_F_impl(f1, OP1, OP2, f2, __restrict__)
// ------------
// Member operator : this field f OP s
#define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \
#define TSEQ_FORALL_F_OP_S_impl(f, OP, s, Unused) \
{ \
/* Field access */ \
List_ACCESS(typeF, f, fP); \
TFOR_List_ACCESS(f, fP, __restrict__); \
TFOR_List_LENGTH(f, loop_len); \
\
/* Loop: f OP s */ \
const label loop_len = (f).size(); \
\
/* pragmas... */ \
for (label i = 0; i < loop_len; ++i) \
@ -520,18 +591,29 @@ void checkFields
} \
}
#define TSEQ_FORALL_F_OP_S(f, OP, s) \
TSEQ_FORALL_F_OP_S_impl(f, OP, s, __restrict__)
#define TSEQ_FORALL_F_OP_S_inplace(f, OP, s) \
TSEQ_FORALL_F_OP_S_impl(f, OP, s,)
// old-style
#define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \
TSEQ_FORALL_F_OP_S_impl(f, OP, s, __restrict__)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Friend operator function : s OP f, allocates storage for s
// ------------
// Friend operator function : s OP f
#define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f) \
#define TSEQ_FORALL_S_OP_F_impl(s, OP, f, Unused) \
{ \
/* Field access */ \
List_CONST_ACCESS(typeF, f, fP); \
TFOR_List_CONST_ACCESS(f, fP, __restrict__); \
TFOR_List_LENGTH(f, loop_len); \
\
/* Loop: s OP f */ \
const label loop_len = (f).size(); \
\
/* pragmas, reduction... */ \
for (label i = 0; i < loop_len; ++i) \
@ -540,17 +622,28 @@ void checkFields
} \
}
#define TSEQ_FORALL_S_OP_F(s, OP, f) \
TSEQ_FORALL_S_OP_F_impl(s, OP, f, __restrict__)
// Friend operator function : s OP1 f1 OP2 f2, allocates storage for s
#define TSEQ_FORALL_S_OP_F_inplace(s, OP, f) \
TSEQ_FORALL_S_OP_F_impl(s, OP, f,)
#define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2) \
// old-style
#define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f) \
TSEQ_FORALL_S_OP_F_impl(s, OP, f, __restrict__)
// ------------
// Friend operator function : s OP1 f1 OP2 f2
#define TSEQ_FORALL_S_OP_F_OP_F_impl(s, OP1, f1, OP2, f2, Unused) \
{ \
/* Field access */ \
List_CONST_ACCESS(typeF1, f1, f1P); \
List_CONST_ACCESS(typeF2, f2, f2P); \
TFOR_List_ACCESS(f1, f1P, __restrict__); \
TFOR_List_CONST_ACCESS(f2, f2P, __restrict__); \
TFOR_List_LENGTH(f1, loop_len); \
\
/* Loop: s OP1 f1 OP2 f2 */ \
const label loop_len = (f1).size(); \
\
/* pragmas, reduction... */ \
for (label i = 0; i < loop_len; ++i) \
@ -559,15 +652,27 @@ void checkFields
} \
}
#define TSEQ_FORALL_S_OP_F_OP_F(s, OP1, f1, OP2, f2) \
TSEQ_FORALL_S_OP_F_OP_F_impl(s, OP1, f1, OP2, f2, __restrict__)
// Friend operator function : s OP FUNC(f), allocates storage for s
#define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f) \
#define TSEQ_FORALL_S_OP_F_OP_F_inplace(s, OP1, f1, OP2, f2) \
TSEQ_FORALL_S_OP_F_OP_F_impl(s, OP1, f1, OP2, f2,)
// old-style
#define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, type1, f1, OP2, type2, f2) \
TSEQ_FORALL_S_OP_F_OP_F_impl(s, OP1, f1, OP2, f2, __restrict__)
// ------------
// Friend operator function : s OP FUNC(f)
#define TSEQ_FORALL_S_OP_FUNC_F_impl(s, OP, FUNC, f, Unused) \
{ \
/* Field access */ \
List_CONST_ACCESS(typeF, f, fP); \
TFOR_List_CONST_ACCESS(f, fP, __restrict__); \
TFOR_List_LENGTH(f, loop_len); \
\
/* Loop: s OP FUNC(f) */ \
const label loop_len = (f).size(); \
\
/* pragmas, reduction... */ \
for (label i = 0; i < loop_len; ++i) \
@ -576,6 +681,16 @@ void checkFields
} \
}
#define TSEQ_FORALL_S_OP_FUNC_F(s, OP, FUNC, f) \
TSEQ_FORALL_S_OP_FUNC_F_impl(s, OP, FUNC, f, __restrict__)
#define TSEQ_FORALL_S_OP_FUNC_F_inplace(s, OP, FUNC, f) \
TSEQ_FORALL_S_OP_FUNC_F_impl(s, OP, FUNC, f,)
// old-style
#define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f) \
TSEQ_FORALL_S_OP_FUNC_F_impl(s, OP, FUNC, f, __restrict__)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,6 +40,15 @@ namespace Foam
template<class TypeR, class Type1>
struct reuseTmp
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<Field<Type1>>& tf1
)
{
return false;
}
//- Pass-through to tmp New
static tmp<Field<TypeR>> New(const Field<Type1>& f1)
{
@ -57,6 +66,15 @@ struct reuseTmp
template<class TypeR>
struct reuseTmp<TypeR, TypeR>
{
//- Identical types: possibly reusable
static bool reusable
(
const tmp<Field<TypeR>>& tf1
)
{
return tf1.movable();
}
//- Identical input and return types:
//- allow optional copy assignment of the initial content
static tmp<Field<TypeR>> New
@ -99,6 +117,16 @@ template<class TypeR> tmp<Field<TypeR>> New
template<class TypeR, class Type1, class Type12, class Type2>
struct reuseTmpTmp
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<Field<Type1>>& tf1,
const tmp<Field<Type2>>& tf2
)
{
return false;
}
//- Dissimilar types: just use size
static tmp<Field<TypeR>> New
(
@ -114,6 +142,16 @@ struct reuseTmpTmp
template<class TypeR, class Type1, class Type12>
struct reuseTmpTmp<TypeR, Type1, Type12, TypeR>
{
//- Second input has return type: possibly reusable
static bool reusable
(
const tmp<Field<Type1>>& tf1,
const tmp<Field<TypeR>>& tf2
)
{
return tf2.movable();
}
//- Second input has return type
static tmp<Field<TypeR>> New
(
@ -134,6 +172,16 @@ struct reuseTmpTmp<TypeR, Type1, Type12, TypeR>
template<class TypeR, class Type2>
struct reuseTmpTmp<TypeR, TypeR, TypeR, Type2>
{
//- First input has return type: possibly reusable
static bool reusable
(
const tmp<Field<TypeR>>& tf1,
const tmp<Field<Type2>>& tf2
)
{
return tf1.movable();
}
//- First input has return type
static tmp<Field<TypeR>> New
(
@ -154,6 +202,16 @@ struct reuseTmpTmp<TypeR, TypeR, TypeR, Type2>
template<class TypeR>
struct reuseTmpTmp<TypeR, TypeR, TypeR, TypeR>
{
//- Both inputs have return type: possibly reusable
static bool reusable
(
const tmp<Field<TypeR>>& tf1,
const tmp<Field<TypeR>>& tf2
)
{
return (tf1.movable() || tf2.movable());
}
//- Both inputs have return type
static tmp<Field<TypeR>> New
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,6 +32,22 @@ Description
#ifndef Foam_ListLoopM_H
#define Foam_ListLoopM_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Element access looping
// The List size
#define TFOR_List_LENGTH(f, n) \
const Foam::label n = (f).size()
// List begin, non-const access with __restrict__ (or not)
#define TFOR_List_ACCESS(f, fp, Restrict) \
auto* const Restrict fp = (f).begin()
// List begin, const access with __restrict__ (or not)
#define TFOR_List_CONST_ACCESS(f, fp, Restrict) \
const auto* const Restrict fp = (f).begin()
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Element access looping
@ -45,8 +61,8 @@ Description
// Loop over all elements
#define List_FOR_ALL(f, i) \
const label _n##i = (f).size(); \
for (label i=0; i<_n##i; ++i)
const Foam::label _n##i = (f).size(); \
for (Foam::label i = 0; i < _n##i; ++i)
// Current element (non-const access)
#define List_ELEM(fp, i) (fp[i])

View File

@ -0,0 +1,133 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2024 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/>.
Description
Field size checks for field operations
\*---------------------------------------------------------------------------*/
#ifndef Foam_errorCheckFields_H
#define Foam_errorCheckFields_H
#include "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type1, class Type2>
void checkFields
(
const UList<Type1>& f1,
const UList<Type2>& f2,
const char* op
)
{
#ifdef FULLDEBUG
if (f1.size() != f2.size())
{
FatalErrorInFunction
<< " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
<< " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
<< nl
<< " for operation " << op << endl
<< abort(FatalError);
}
#endif
}
template<class Type1, class Type2, class Type3>
void checkFields
(
const UList<Type1>& f1,
const UList<Type2>& f2,
const UList<Type3>& f3,
const char* op
)
{
#ifdef FULLDEBUG
if
(
f1.size() != f2.size()
|| f1.size() != f3.size()
)
{
FatalErrorInFunction
<< " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
<< ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
<< " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
<< nl
<< " for operation " << op << endl
<< abort(FatalError);
}
#endif
}
template<class Type1, class Type2, class Type3, class Type4>
void checkFields
(
const UList<Type1>& f1,
const UList<Type2>& f2,
const UList<Type3>& f3,
const UList<Type4>& f4,
const char* op
)
{
#ifdef FULLDEBUG
if
(
f1.size() != f2.size()
|| f1.size() != f3.size()
|| f1.size() != f4.size()
)
{
FatalErrorInFunction
<< " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
<< ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
<< ", Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
<< " and Field<"<<pTraits<Type4>::typeName<<"> f4("<<f4.size()<<')'
<< nl
<< " for operation " << op << endl
<< abort(FatalError);
}
#endif
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -45,7 +45,7 @@ template<>
void boolField::negate()
{
// std::for_each, std::logical_not
TFOR_ALL_F_OP_OP_F(bool, *this, =, !, bool, *this)
TSEQ_FORALL_F_OP_OP_F_inplace(*this, =, !, *this)
}

View File

@ -255,7 +255,7 @@ complex sumProd(const UList<complex>& f1, const UList<complex>& f2)
if (f1.size() && (f1.size() == f2.size()))
{
// std::inner_product
TFOR_ALL_S_OP_F_OP_F(complex, result, +=, complex, f1, *, complex, f2)
TSEQ_FORALL_S_OP_F_OP_F(result, +=, f1, *, f2)
}
return result;
}

View File

@ -68,11 +68,16 @@ void scalarField::replace(const direction, const scalar& s)
void stabilise(scalarField& res, const UList<scalar>& sf, const scalar s)
{
// std::transform
TFOR_ALL_F_OP_FUNC_S_F
(
scalar, res, =, ::Foam::stabilise, scalar, s, scalar, sf
)
if (res.cdata() == sf.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(res, =, ::Foam::stabilise, s, sf)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_S_F(res, =, ::Foam::stabilise, s, sf)
}
}
tmp<scalarField> stabilise(const UList<scalar>& sf, const scalar s)
@ -96,11 +101,11 @@ tmp<scalarField> stabilise(const tmp<scalarField>& tsf, const scalar s)
template<>
float sumProd(const UList<float>& f1, const UList<float>& f2)
{
float result = 0.0;
float result(0);
if (f1.size() && (f1.size() == f2.size()))
{
// std::inner_product
TFOR_ALL_S_OP_F_OP_F(float, result, +=, float, f1, *, float, f2)
TSEQ_FORALL_S_OP_F_OP_F(result, +=, f1, *, f2)
}
return result;
}
@ -109,11 +114,11 @@ float sumProd(const UList<float>& f1, const UList<float>& f2)
template<>
double sumProd(const UList<double>& f1, const UList<double>& f2)
{
double result = 0.0;
double result(0);
if (f1.size() && (f1.size() == f2.size()))
{
// std::inner_product
TFOR_ALL_S_OP_F_OP_F(double, result, +=, double, f1, *, double, f2)
TSEQ_FORALL_S_OP_F_OP_F(result, +=, f1, *, f2)
}
return result;
}
@ -188,7 +193,16 @@ UNARY_FUNCTION(scalar, scalar, paToBar)
#define BesselFunc(func) \
void func(scalarField& res, const int n, const UList<scalar>& sf) \
{ \
TFOR_ALL_F_OP_FUNC_S_F(scalar, res, =, ::Foam::func, int, n, scalar, sf) \
if (res.cdata() == sf.cdata()) \
{ \
/* std::for_each */ \
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(res, =, ::Foam::func, n, sf) \
} \
else \
{ \
/* std::transform */ \
TSEQ_FORALL_F_OP_FUNC_S_F(res, =, ::Foam::func, n, sf) \
} \
} \
\
tmp<scalarField> func(const int n, const UList<scalar>& sf) \

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -54,8 +54,16 @@ UNARY_FUNCTION(symmTensor, symmTensor, cof)
void inv(Field<symmTensor>& result, const UList<symmTensor>& f1)
{
// With 'failsafe' invert
// std::transform
TFOR_ALL_F_OP_F_FUNC(symmTensor, result, =, symmTensor, f1, safeInv)
if (result.cdata() == f1.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_F_FUNC_inplace(result, =, f1, safeInv)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_F_FUNC(result, =, f1, safeInv)
}
}
tmp<symmTensorField> inv(const UList<symmTensor>& tf)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
Copyright (C) 2023-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,11 +39,16 @@ void Foam::transform
const Field<Type>& fld
)
{
// std::transform
TFOR_ALL_F_OP_FUNC_S_F
(
Type, result, =, transform, symmTensor, rot, Type, fld
);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(result, =, transform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_S_F(result, =, transform, rot, fld)
}
}
@ -55,16 +60,23 @@ void Foam::transform
const Field<Type>& fld
)
{
// Does not handle corner case where result and rot are identical...
if (rot.size() == 1)
{
return transform(result, rot.front(), fld);
}
// std::transform
TFOR_ALL_F_OP_FUNC_F_F
(
Type, result, =, transform, symmTensor, rot, Type, fld
);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_F_inplace(result, =, transform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F_F(result, =, transform, rot, fld)
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -55,8 +55,16 @@ UNARY_FUNCTION(tensor, tensor, cof)
void inv(Field<tensor>& result, const UList<tensor>& f1)
{
// With 'failsafe' invert
// std::transform
TFOR_ALL_F_OP_F_FUNC(tensor, result, =, tensor, f1, safeInv)
if (result.cdata() == f1.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_F_FUNC_inplace(result, =, f1, safeInv)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_F_FUNC(result, =, f1, safeInv)
}
}
tmp<tensorField> inv(const UList<tensor>& tf)
@ -88,7 +96,7 @@ tmp<Field<tensor>> transformFieldMask<tensor>
{
auto tres = tmp<tensorField>::New(stf.size());
auto& res = tres.ref();
TFOR_ALL_F_OP_F(tensor, res, =, symmTensor, stf)
TSEQ_FORALL_F_OP_F(res, =, stf)
return tres;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,14 +34,22 @@ License
void Foam::transform
(
vectorField& rtf,
vectorField& result,
const quaternion& q,
const vectorField& tf
const vectorField& fld
)
{
const tensor rot = q.R();
// std::transform
TFOR_ALL_F_OP_FUNC_S_F(vector, rtf, =, transform, tensor, rot, vector, tf)
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(result, =, transform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_S_F(result, =, transform, rot, fld)
}
}
@ -82,8 +90,16 @@ void Foam::transformPoints
// Check if any translation
if (mag(trans) > VSMALL)
{
// std::transform
TFOR_ALL_F_OP_F_OP_S(vector, result, =, vector, fld, -, vector, trans);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_F_OP_S_inplace(result, =, fld, -, trans)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_F_OP_S(result, =, fld, -, trans)
}
}
else
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,11 +39,16 @@ void Foam::transform
const Field<Type>& fld
)
{
// std::transform
TFOR_ALL_F_OP_FUNC_S_F
(
Type, result, =, transform, tensor, rot, Type, fld
);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(result, =, transform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_S_F(result, =, transform, rot, fld)
}
}
@ -55,16 +60,23 @@ void Foam::transform
const Field<Type>& fld
)
{
// Does not handle corner case where result and rot are identical...
if (rot.size() == 1)
{
return transform(result, rot.front(), fld);
}
// std::transform
TFOR_ALL_F_OP_FUNC_F_F
(
Type, result, =, transform, tensor, rot, Type, fld
);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_F_inplace(result, =, transform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F_F(result, =, transform, rot, fld)
}
}
@ -165,11 +177,16 @@ void Foam::invTransform
const Field<Type>& fld
)
{
// std::transform
TFOR_ALL_F_OP_FUNC_S_F
(
Type, result, =, invTransform, tensor, rot, Type, fld
);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_S_F_inplace(result, =, invTransform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_S_F(result, =, invTransform, rot, fld)
}
}
@ -186,11 +203,16 @@ void Foam::invTransform
return invTransform(result, rot.front(), fld);
}
// std::transform
TFOR_ALL_F_OP_FUNC_F_F
(
Type, result, =, invTransform, tensor, rot, Type, fld
);
if (result.cdata() == fld.cdata())
{
// std::for_each
TSEQ_FORALL_F_OP_FUNC_F_F_inplace(result, =, invTransform, rot, fld)
}
else
{
// std::transform
TSEQ_FORALL_F_OP_FUNC_F_F(result, =, invTransform, rot, fld)
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,12 +37,12 @@ Foam::List<T> Foam::transform
const UList<T>& field
)
{
const label loopLen = field.size();
const label loop_len = field.size();
List<T> result(loopLen);
List<T> result(loop_len);
/* pragmas... */
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
result[i] = transform(rotTensor, field[i]);
}
@ -54,10 +54,10 @@ Foam::List<T> Foam::transform
template<class T>
void Foam::transformList(const tensor& rotTensor, UList<T>& field)
{
const label loopLen = field.size();
const label loop_len = field.size();
/* pragmas... */
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
field[i] = transform(rotTensor, field[i]);
}
@ -73,10 +73,10 @@ void Foam::transformList(const tensorField& rotTensor, UList<T>& field)
}
else if (rotTensor.size() == field.size())
{
const label loopLen = field.size();
const label loop_len = field.size();
/* pragmas... */
for (label i = 0; i < loopLen; ++i)
for (label i = 0; i < loop_len; ++i)
{
field[i] = transform(rotTensor[i], field[i]);
}
@ -96,7 +96,7 @@ void Foam::transformList(const tensor& rotTensor, Map<T>& field)
{
forAllIters(field, iter)
{
T& value = iter.val();
auto& value = iter.val();
value = transform(rotTensor, value);
}
}
@ -124,7 +124,7 @@ void Foam::transformList(const tensor& rotTensor, EdgeMap<T>& field)
{
forAllIters(field, iter)
{
T& value = iter.val();
auto& value = iter.val();
value = transform(rotTensor, value);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -87,6 +87,15 @@ template
>
struct reuseTmpGeometricField
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<GeometricField<Type1, PatchField, GeoMesh>>& tf1
)
{
return false;
}
//- Pass-through to New GeometricField
static tmp<GeometricField<TypeR, PatchField, GeoMesh>> New
(
@ -126,6 +135,15 @@ struct reuseTmpGeometricField
template<class TypeR, template<class> class PatchField, class GeoMesh>
struct reuseTmpGeometricField<TypeR, TypeR, PatchField, GeoMesh>
{
//- Identical types: possibly reusable
static bool reusable
(
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf1
)
{
return Detail::reusable(tf1);
}
//- Allow optional copy assignment of the initial content
//- for identical input and output types
static tmp<GeometricField<TypeR, PatchField, GeoMesh>> New
@ -156,7 +174,7 @@ struct reuseTmpGeometricField<TypeR, TypeR, PatchField, GeoMesh>
if (initCopy)
{
tresult.ref() == tf1();
tresult.ref() == f1;
}
return tresult;
@ -187,6 +205,9 @@ tmp
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Two-parameter versions
template
<
class TypeR,
@ -198,6 +219,16 @@ template
>
struct reuseTmpTmpGeometricField
{
//- Dissimilar types: non-reusable
static bool reusable
(
const tmp<GeometricField<Type1, PatchField, GeoMesh>>& tf1,
const tmp<GeometricField<Type2, PatchField, GeoMesh>>& tf2
)
{
return false;
}
static tmp<GeometricField<TypeR, PatchField, GeoMesh>> New
(
const tmp<GeometricField<Type1, PatchField, GeoMesh>>& tf1,
@ -231,6 +262,17 @@ struct reuseTmpTmpGeometricField
TypeR, Type1, Type12, TypeR, PatchField, GeoMesh
>
{
//- Second input has return type: possibly reusable
static bool reusable
(
const tmp<GeometricField<Type1, PatchField, GeoMesh>>& tf1,
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf2
)
{
return Detail::reusable(tf2);
}
//- Second input has return type
static tmp<GeometricField<TypeR, PatchField, GeoMesh>> New
(
const tmp<GeometricField<Type1, PatchField, GeoMesh>>& tf1,
@ -272,6 +314,17 @@ struct reuseTmpTmpGeometricField
TypeR, TypeR, TypeR, Type2, PatchField, GeoMesh
>
{
//- First input has return type: possibly reusable
static bool reusable
(
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf1,
const tmp<GeometricField<Type2, PatchField, GeoMesh>>& tf2
)
{
return Detail::reusable(tf2);
}
//- First input has return type
static tmp<GeometricField<TypeR, PatchField, GeoMesh>> New
(
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf1,
@ -307,6 +360,16 @@ struct reuseTmpTmpGeometricField
TypeR, TypeR, TypeR, TypeR, PatchField, GeoMesh
>
{
//- Both inputs have return type: possibly reusable
static bool reusable
(
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf1,
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf2
)
{
return (Detail::reusable(tf1) || Detail::reusable(tf2));
}
static tmp<GeometricField<TypeR, PatchField, GeoMesh>> New
(
const tmp<GeometricField<TypeR, PatchField, GeoMesh>>& tf1,

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -61,11 +60,11 @@ Type Foam::interpolateSplineXY
label n = xOld.size();
// early exit if out of bounds or only one value
if (n == 1 || x <= xOld[0])
if (n == 1 || x < xOld[0])
{
return yOld[0];
}
if (x >= xOld[n - 1])
if (x > xOld[n - 1])
{
return yOld[n - 1];
}

View File

@ -2443,45 +2443,26 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement
// Seed all boundary faces with owner value. This is to make sure that
// they are visited (probably only important for coupled faces since
// these need to be visited from both sides)
List<refinementData> nbrCellInfo;
syncTools::swapBoundaryCellList(mesh_, allCellInfo, nbrCellInfo);
for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
{
// Check if face already handled in loop above
if (!allFaceInfo[facei].valid(dummyTrackData))
{
const label own = faceOwner[facei];
const auto& nbrInfo = nbrCellInfo[facei-mesh_.nInternalFaces()];
label own = faceOwner[facei];
if (allCellInfo[own].count() > nbrInfo.count())
{
allFaceInfo[facei].updateFace
(
mesh_,
facei,
own,
allCellInfo[own],
FaceCellWave<refinementData, int>::propagationTol(),
dummyTrackData
);
seedFaces.append(facei);
seedFacesInfo.append(allFaceInfo[facei]);
}
else if (allCellInfo[own].count() < nbrInfo.count())
{
allFaceInfo[facei].updateFace
(
mesh_,
facei,
-1, // Lucky! neighbCelli not used!
nbrInfo,
FaceCellWave<refinementData, int>::propagationTol(),
dummyTrackData
);
seedFaces.append(facei);
seedFacesInfo.append(allFaceInfo[facei]);
}
// Seed face with transported data from owner.
refinementData faceData;
faceData.updateFace
(
mesh_,
facei,
own,
allCellInfo[own],
FaceCellWave<refinementData, int>::propagationTol(),
dummyTrackData
);
seedFaces.append(facei);
seedFacesInfo.append(faceData);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2019-2022,2024 OpenCFD Ltd.
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,13 +28,6 @@ License
#include "refinementData.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::refinementData Foam::transform(const tensor&, const refinementData val)
{
return val;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2020,2024 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -216,9 +216,6 @@ public:
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- No-op rotational transform for base types
refinementData transform(const tensor&, const refinementData val);
//- Contiguous data for refinementData
template<> struct is_contiguous<refinementData> : std::true_type {};

View File

@ -79,7 +79,7 @@ Foam::patchDistMethods::advectionDiffusion::advectionDiffusion
tolerance_(coeffs_.getOrDefault<scalar>("tolerance", 1e-3)),
maxIter_(coeffs_.getOrDefault<int>("maxIter", 10)),
predicted_(false),
checkAndWriteMesh_(coeffs_.getOrDefault("checkAndWriteMesh", false))
checkAndWriteMesh_(coeffs_.getOrDefault("checkAndWriteMesh", true))
{}

View File

@ -67,8 +67,7 @@ Foam::functionObjects::Curle::Curle
c0_(0),
rawFilePtrs_(),
inputSurface_(),
surfaceWriterPtr_(nullptr),
warnOnNoPatch_(true)
surfaceWriterPtr_(nullptr)
{
read(dict);
}
@ -86,10 +85,8 @@ bool Foam::functionObjects::Curle::read(const dictionary& dict)
}
dict.readIfPresent("p", pName_);
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
patchIDs_ =
pbm.patchSet(dict.get<wordRes>("patches"), warnOnNoPatch_).sortedToc();
patchIDs_ = pbm.patchSet(dict.get<wordRes>("patches")).sortedToc();
if (patchIDs_.empty())
{

View File

@ -181,9 +181,6 @@ class Curle
//- Ouput surface when sampling a surface
autoPtr<surfaceWriter> surfaceWriterPtr_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
public:

View File

@ -122,7 +122,6 @@ Foam::binModel::binModel
mesh_(mesh),
decomposePatchValues_(false),
cumulative_(false),
warnOnNoPatch_(true),
coordSysPtr_(nullptr),
nBin_(1)
{}
@ -139,11 +138,8 @@ bool Foam::binModel::read(const dictionary& dict)
return false;
}
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
// Can also use pbm.indices(), but no warnings...
patchIDs_ =
pbm.patchSet(dict.get<wordRes>("patches"), warnOnNoPatch_).sortedToc();
patchIDs_ = pbm.patchSet(dict.get<wordRes>("patches")).sortedToc();
fieldNames_ = dict.get<wordHashSet>("fields").sortedToc();
wordRes zoneNames;

View File

@ -77,9 +77,6 @@ protected:
//- increasing distance in binning direction
bool cumulative_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
//- Local coordinate system of bins
autoPtr<coordinateSystem> coordSysPtr_;

View File

@ -128,8 +128,7 @@ Foam::functionObjects::columnAverage::columnAverage
:
fvMeshFunctionObject(name, runTime, dict),
patchIDs_(),
fieldSet_(mesh_),
warnOnNoPatch_(true)
fieldSet_(mesh_)
{
read(dict);
}
@ -141,13 +140,10 @@ bool Foam::functionObjects::columnAverage::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
patchIDs_ =
mesh_.boundaryMesh().patchSet
(
dict.get<wordRes>("patches"),
warnOnNoPatch_
dict.get<wordRes>("patches")
).sortedToc();
fieldSet_.read(dict);

View File

@ -132,9 +132,6 @@ class columnAverage
mutable autoPtr<globalIndex> globalPoints_;
mutable autoPtr<meshStructure> meshStructurePtr_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
// Private Member Functions

View File

@ -51,8 +51,7 @@ Foam::heatTransferCoeffModel::heatTransferCoeffModel
:
mesh_(mesh),
TName_(TName),
qrName_("qr"),
warnOnNoPatch_(true)
qrName_("qr")
{}
@ -151,10 +150,8 @@ bool Foam::heatTransferCoeffModel::read(const dictionary& dict)
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
dict.readIfPresent("qr", qrName_);
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
patchIDs_ =
pbm.patchSet(dict.get<wordRes>("patches"), warnOnNoPatch_).sortedToc();
patchIDs_ = pbm.patchSet(dict.get<wordRes>("patches")).sortedToc();
return true;
}

View File

@ -76,9 +76,6 @@ protected:
//- Name of radiative heat flux field
word qrName_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
// Protected Member Functions

View File

@ -245,8 +245,7 @@ Foam::functionObjects::nearWallFields::nearWallFields
)
:
fvMeshFunctionObject(name, runTime, dict),
fieldSet_(),
warnOnNoPatch_(true)
fieldSet_()
{
read(dict);
}
@ -262,11 +261,9 @@ bool Foam::functionObjects::nearWallFields::read(const dictionary& dict)
dict.readEntry("fields", fieldSet_);
dict.readEntry("distance", distance_);
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
// Can also use pbm.indices(), but no warnings...
patchIDs_ =
pbm.patchSet(dict.get<wordRes>("patches"), warnOnNoPatch_).sortedToc();
patchIDs_ = pbm.patchSet(dict.get<wordRes>("patches")).sortedToc();
// Clear out any previously loaded fields

View File

@ -134,9 +134,6 @@ protected:
//- From resulting back to original field
HashTable<word> reverseFieldMap_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
// Calculated addressing

View File

@ -206,10 +206,7 @@ Foam::functionObjects::regionSizeDistribution::findPatchRegions
labelHashSet patchRegions(2*regions.nRegions());
labelHashSet patchSet
(
mesh_.boundaryMesh().patchSet(patchNames_, warnOnNoPatch_)
);
labelHashSet patchSet(mesh_.boundaryMesh().patchSet(patchNames_));
for (const label patchi : patchSet)
{
@ -372,8 +369,7 @@ Foam::functionObjects::regionSizeDistribution::regionSizeDistribution
writeFile(obr_, name),
alphaName_(dict.get<word>("field")),
patchNames_(dict.get<wordRes>("patches")),
isoPlanes_(dict.getOrDefault("isoPlanes", false)),
warnOnNoPatch_(true)
isoPlanes_(dict.getOrDefault("isoPlanes", false))
{
read(dict);
}
@ -420,8 +416,6 @@ bool Foam::functionObjects::regionSizeDistribution::read(const dictionary& dict)
direction_.normalise();
}
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
return true;
}

View File

@ -249,9 +249,6 @@ class regionSizeDistribution
//- Switch to enable iso-planes sampling
bool isoPlanes_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
// Private Member Functions

View File

@ -106,8 +106,7 @@ Foam::functionObjects::wallHeatFlux::wallHeatFlux
:
fvMeshFunctionObject(name, runTime, dict),
writeFile(obr_, name, typeName, dict),
qrName_("qr"),
warnOnNoPatch_(true)
qrName_("qr")
{
read(dict);
@ -145,13 +144,12 @@ bool Foam::functionObjects::wallHeatFlux::read(const dictionary& dict)
writeFile::read(dict);
dict.readIfPresent("qr", qrName_);
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
wordRes patchNames;
labelHashSet patchSet;
if (dict.readIfPresent("patches", patchNames) && !patchNames.empty())
{
patchSet = pbm.patchSet(patchNames, warnOnNoPatch_);
patchSet = pbm.patchSet(patchNames);
}
labelHashSet allWalls(pbm.findPatchIDs<wallPolyPatch>());

View File

@ -123,9 +123,6 @@ protected:
//- Name of radiative heat flux name
word qrName_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
// Protected Member Functions

View File

@ -90,8 +90,7 @@ Foam::functionObjects::wallShearStress::wallShearStress
:
fvMeshFunctionObject(name, runTime, dict),
writeFile(mesh_, name, typeName, dict),
writeFields_(true), // May change in the future
warnOnNoPatch_(true)
writeFields_(true) // May change in the future
{
read(dict);
@ -128,7 +127,6 @@ bool Foam::functionObjects::wallShearStress::read(const dictionary& dict)
writeFields_ = true; // May change in the future
dict.readIfPresent("writeFields", writeFields_);
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
@ -136,7 +134,7 @@ bool Foam::functionObjects::wallShearStress::read(const dictionary& dict)
labelHashSet patchSet;
if (dict.readIfPresent("patches", patchNames) && !patchNames.empty())
{
patchSet = pbm.patchSet(patchNames, warnOnNoPatch_);
patchSet = pbm.patchSet(patchNames);
}
labelHashSet allWalls(pbm.findPatchIDs<wallPolyPatch>());

View File

@ -133,9 +133,6 @@ class wallShearStress
//- Write the shear stress field ?
bool writeFields_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
protected:

View File

@ -550,8 +550,7 @@ Foam::functionObjects::forces::forces
directForceDensity_(false),
porosity_(false),
writeFields_(false),
initialised_(false),
warnOnNoPatch_(true)
initialised_(false)
{
if (readFields)
{
@ -590,8 +589,7 @@ Foam::functionObjects::forces::forces
directForceDensity_(false),
porosity_(false),
writeFields_(false),
initialised_(false),
warnOnNoPatch_(true)
initialised_(false)
{
if (readFields)
{
@ -615,13 +613,10 @@ bool Foam::functionObjects::forces::read(const dictionary& dict)
initialised_ = false;
dict.readIfPresent("warnOnNoPatch", warnOnNoPatch_);
Info<< type() << ' ' << name() << ':' << endl;
// Can also use pbm.indices(), but no warnings...
patchIDs_ =
pbm.patchSet(dict.get<wordRes>("patches"), warnOnNoPatch_).sortedToc();
patchIDs_ = pbm.patchSet(dict.get<wordRes>("patches")).sortedToc();
dict.readIfPresent("directForceDensity", directForceDensity_);
if (directForceDensity_)

View File

@ -264,9 +264,6 @@ protected:
//- Flag of initialisation (internal)
bool initialised_;
//- Flag to suppress warnings for missing patches
bool warnOnNoPatch_;
// Protected Member Functions

View File

@ -208,7 +208,6 @@ Foam::functionObjects::electricPotential::electricPotential
)
),
fvOptions_(mesh_),
tol_(1),
nCorr_(1),
writeDerivedFields_(false),
electricField_(false)
@ -259,7 +258,6 @@ bool Foam::functionObjects::electricPotential::read(const dictionary& dict)
dict.readIfPresent("sigma", sigma_);
dict.readIfPresent("epsilonr", epsilonr_);
dict.readIfPresent("nCorr", nCorr_);
dict.readIfPresent("tolerance", tol_);
dict.readIfPresent("writeDerivedFields", writeDerivedFields_);
dict.readIfPresent("electricField", electricField_);
@ -348,10 +346,6 @@ bool Foam::functionObjects::electricPotential::execute()
{
Log << type() << " execute: " << name() << endl;
// Convergence monitor parameters
bool converged = false;
label iter = 0;
tmp<volScalarField> tsigma = this->sigma();
const auto& sigma = tsigma();
@ -368,9 +362,7 @@ bool Foam::functionObjects::electricPotential::execute()
fvOptions_.constrain(eVEqn);
++iter;
converged = (eVEqn.solve().initialResidual() < tol_);
if (converged) break;
eVEqn.solve();
}
if (electricField_)
@ -379,14 +371,6 @@ bool Foam::functionObjects::electricPotential::execute()
E == -fvc::grad(eV);
}
if (converged)
{
Log << type() << ": " << name() << ": "
<< eV.name() << " is converged." << nl
<< tab << "initial-residual tolerance: " << tol_ << nl
<< tab << "outer iteration: " << iter << nl;
}
Log << endl;
return true;

View File

@ -124,7 +124,6 @@ Usage
electricField <bool>;
E <word>;
fvOptions <dict>;
tolerance <scalar>;
// Inherited entries
...
@ -144,7 +143,6 @@ Usage
electricField | Flag to calculate electric field | bool | no | false
E | Name of electric field | word | no | electricPotential:E
fvOptions | List of finite-volume options | dict | no | -
tolerance | Outer-loop initial-residual tolerance | scalar | no | 1
\endtable
The inherited entries are elaborated in:
@ -220,9 +218,6 @@ class electricPotential
//- Run-time selectable finite volume options
fv::optionList fvOptions_;
//- Outer-loop initial-residual tolerance
scalar tol_;
//- Number of corrector iterations
int nCorr_;

View File

@ -26,6 +26,11 @@ License
\*---------------------------------------------------------------------------*/
#include "energyTransport.H"
#include "surfaceFields.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvmLaplacian.H"
#include "fvmSup.H"
#include "turbulentTransportModel.H"
#include "turbulentFluidThermoModel.H"
#include "addToRunTimeSelectionTable.H"
@ -183,6 +188,23 @@ Foam::functionObjects::energyTransport::energyTransport
)
:
fvMeshFunctionObject(name, runTime, dict),
fieldName_(dict.getOrDefault<word>("field", "T")),
phiName_(dict.getOrDefault<word>("phi", "phi")),
rhoName_(dict.getOrDefault<word>("rho", "rho")),
nCorr_(0),
schemesField_("unknown-schemesField"),
fvOptions_(mesh_),
multiphaseThermo_(dict.subOrEmptyDict("phaseThermos")),
Cp_("Cp", dimEnergy/dimMass/dimTemperature, 0, dict),
kappa_
(
"kappa",
dimEnergy/dimTime/dimLength/dimTemperature,
0,
dict
),
rho_("rhoInf", dimDensity, 0, dict),
Prt_("Prt", dimless, 1, dict),
rhoCp_
(
IOobject
@ -196,25 +218,7 @@ Foam::functionObjects::energyTransport::energyTransport
),
mesh_,
dimensionedScalar(dimEnergy/dimTemperature/dimVolume, Zero)
),
fvOptions_(mesh_),
multiphaseThermo_(dict.subOrEmptyDict("phaseThermos")),
Cp_("Cp", dimEnergy/dimMass/dimTemperature, 0, dict),
kappa_
(
"kappa",
dimEnergy/dimTime/dimLength/dimTemperature,
0,
dict
),
rho_("rhoInf", dimDensity, 0, dict),
Prt_("Prt", dimless, 1, dict),
fieldName_(dict.getOrDefault<word>("field", "T")),
schemesField_("unknown-schemesField"),
phiName_(dict.getOrDefault<word>("phi", "phi")),
rhoName_(dict.getOrDefault<word>("rho", "rho")),
tol_(1),
nCorr_(0)
)
{
read(dict);
@ -301,14 +305,17 @@ Foam::functionObjects::energyTransport::energyTransport
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::energyTransport::~energyTransport()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::energyTransport::read(const dictionary& dict)
{
if (!fvMeshFunctionObject::read(dict))
{
return false;
}
fvMeshFunctionObject::read(dict);
dict.readIfPresent("phi", phiName_);
dict.readIfPresent("rho", rhoName_);
@ -316,7 +323,6 @@ bool Foam::functionObjects::energyTransport::read(const dictionary& dict)
schemesField_ = dict.getOrDefault("schemesField", fieldName_);
dict.readIfPresent("nCorr", nCorr_);
dict.readIfPresent("tolerance", tol_);
if (dict.found("fvOptions"))
{
@ -349,16 +355,12 @@ bool Foam::functionObjects::energyTransport::execute()
scalar relaxCoeff = 0;
mesh_.relaxEquation(schemesField_, relaxCoeff);
// Convergence monitor parameters
bool converged = false;
int iter = 0;
if (phi.dimensions() == dimMass/dimTime)
{
rhoCp_ = rho()*Cp();
const surfaceScalarField rhoCpPhi(fvc::interpolate(Cp())*phi);
for (int i = 0; i <= nCorr_; ++i)
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
@ -374,9 +376,7 @@ bool Foam::functionObjects::energyTransport::execute()
fvOptions_.constrain(sEqn);
++iter;
converged = (sEqn.solve(schemesField_).initialResidual() < tol_);
if (converged) break;
sEqn.solve(schemesField_);
}
}
else if (phi.dimensions() == dimVolume/dimTime)
@ -393,7 +393,7 @@ bool Foam::functionObjects::energyTransport::execute()
rhoCp
);
for (int i = 0; i <= nCorr_; ++i)
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
@ -408,9 +408,7 @@ bool Foam::functionObjects::energyTransport::execute()
fvOptions_.constrain(sEqn);
++iter;
converged = (sEqn.solve(schemesField_).initialResidual() < tol_);
if (converged) break;
sEqn.solve(schemesField_);
}
}
else
@ -421,14 +419,6 @@ bool Foam::functionObjects::energyTransport::execute()
<< dimVolume/dimTime << exit(FatalError);
}
if (converged)
{
Log << type() << ": " << name() << ": "
<< s.name() << " is converged." << nl
<< tab << "initial-residual tolerance: " << tol_ << nl
<< tab << "outer iteration: " << iter << nl;
}
Log << endl;
return true;

View File

@ -30,180 +30,151 @@ Group
grpSolversFunctionObjects
Description
Computes the simplified energy transport equation in single-phase or
two-phase flow, considering incompressible cases:
Evolves a simplified energy transport equation for incompressible flows.
It takes into account the inertia, conduction and convection terms plus
a source.
\f[
\frac{\partial \rho \, C_p \, T}{\partial t}
+ \nabla \cdot \left(\rho \, C_p \, \phi \, T \right)
- \nabla \cdot \left(\rho \, C_p \, \phi \right) \, T
- \nabla \cdot \left(\kappa_{eff} \, \nabla T \right)
= S_T
\f]
- The field name must be temperature and its BC's specified in the time
directory.
- The turbulence model should be incompressible
- In order to use in a incompressible multi phase a list of thermal
properties are needed. See below
where:
\vartable
T | Scalar field
\rho | (Generic) Fluid density which is unity when not specified
C_p | Specific heat capacity at constant pressure
\phi | (Generic) Flux field
\kappa_{eff} | Effective thermal conductivity
S_T | Scalar field source term
\endvartable
Usage
Minimal example in \c system/controlDict.functions:
Example of function object specification to solve a energy transport
equation for a single phase flow plus a source term
\verbatim
energyTransport1
functions
{
// Mandatory entries
type energyTransport;
libs (solverFunctionObjects);
energy
{
type energyTransport;
libs (energyTransportFunctionObjects);
// Optional entries
field <word>;
phi <word>;
rho <word>;
Cp <scalar>;
kappa <scalar>;
rhoInf <scalar>;
Prt <scalar>;
schemesField <word>;
tolerance <scalar>;
nCorr <int>;
fvOptions <dict>;
phaseThermos <dict>;
enabled true;
writeControl writeTime;
writeInterval 1;
// Inherited entries
...
field T;
// volumetric Flux
phi phi;
// Thermal properties
Cp Cp [J/kg/K] 1e3;
kappa kappa [W/m/K] 0.0257;
rhoInf rho [kg/m^3] 1.2;
write true;
fvOptions
{
viscousDissipation
{
type viscousDissipation;
enabled true;
viscousDissipationCoeffs
{
fields (T);
rhoInf $....rhoInf;
}
}
}
}
}
\endverbatim
where:
Example of function object specification to solve a energy transport
equation for a multiphase phase flow plus a source term
equation:
\verbatim
functions
{
energy
{
type energyTransport;
libs (energyTransportFunctionObjects);
enabled true;
writeControl writeTime;
writeInterval 1;
field T;
// rho field name
rho rho;
// mass flux for multiphase
phi rhoPhi;
write true;
// Thermal properties of the phases
phaseThermos
{
alpha.air
{
Cp 1e3;
kappa 0.0243;
}
alpha.mercury
{
Cp 140;
kappa 8.2;
}
alpha.oil
{
Cp 2e3;
kappa 0.2;
}
alpha.water
{
Cp 4e3;
kappa 0.6;
}
}
fvOptions
{
viscousDissipation
{
type viscousDissipation;
enabled true;
viscousDissipationCoeffs
{
fields (T);
rho rho; //rho Field
}
}
}
}
}
\endverbatim
Where the entries comprise:
\table
Property | Description | Type | Reqd | Deflt
type | Type name: energyTransport | word | yes | -
libs | Library name: solverFunctionObjects | word | yes | -
field | Name of the passive-scalar field | word | no | s
phi | Name of flux field | word | no | phi
rho | Name of density field | word | no | rho
Cp | Specific heat capacity at constant pressure | scalar | no | 0
kappa | Thermal conductivity | scalar | no | 0
rhoInf | Fluid density | scalar | no | 0
Prt | Turbulent Prandtl number | scalar | no | 1
schemesField | Name of field to specify schemes | word | no | field
tolerance | Outer-loop initial-residual tolerance | scalar | no | 1
nCorr | Number of outer-loop correctors | int | no | 0
fvOptions | List of finite-volume options | dict | no | -
phaseThermos | Dictionary for multi-phase thermo | dict | no | null
Property | Description | Required | Default value
type | Type name: energyTransport | yes |
field | Name of the scalar field | no | T
phi | Name of flux field | no | phi
rho | Name of density field | no | rho
nCorr | Number of correctors | no | 0
schemesField | Name of field to specify schemes | no | field name
fvOptions | List of scalar sources | no |
Cp | Heat capacity for single phase | no | 0
rhoInf | Density for single phase | no | 0
kappa | Thermal conductivity for single phase | no | 0
Prt | Turbulent Prandlt number | no | 1.0
phaseThermos | Dictionary for multi-phase thermo |no | null
fvOptions | Opotional extra sources | no | null
\endtable
The inherited entries are elaborated in:
- \link fvMeshFunctionObject.H \endlink
- \link fvOption.H \endlink
An example of function object specification to solve a energy transport
equation for a single phase flow plus a source term:
\verbatim
energyTransport1
{
// Mandatory entries
type energyTransport;
libs (solverFunctionObjects);
// Optional entries
field T;
phi phi;
Cp Cp [J/kg/K] 1e3;
kappa kappa [W/m/K] 0.0257;
rhoInf rho [kg/m^3] 1.2;
fvOptions
{
viscousDissipation
{
type viscousDissipation;
enabled true;
viscousDissipationCoeffs
{
fields (T);
rhoInf $....rhoInf;
}
}
}
// Inherited entries
enabled true;
writeControl writeTime;
writeInterval 1;
}
\endverbatim
An example of function object specification to solve a energy transport
equation for a multiphase phase flow plus a source term:
\verbatim
energyTransport1
{
// Mandatory entries
type energyTransport;
libs (solverFunctionObjects);
// Optional entries
field T;
rho rho;
phi rhoPhi;
// Thermal properties of the phases
phaseThermos
{
alpha.air
{
Cp 1e3;
kappa 0.0243;
}
alpha.mercury
{
Cp 140;
kappa 8.2;
}
alpha.oil
{
Cp 2e3;
kappa 0.2;
}
alpha.water
{
Cp 4e3;
kappa 0.6;
}
}
fvOptions
{
viscousDissipation
{
type viscousDissipation;
enabled true;
viscousDissipationCoeffs
{
fields (T);
rho rho;
}
}
}
// Inherited entries
enabled true;
writeControl writeTime;
writeInterval 1;
}
\endverbatim
Note
- The field name must be temperature and its boundary conditions
specified in the time directory.
- The turbulence model should be incompressible.
See also
Foam::functionObjects::fvMeshFunctionObject
SourceFiles
energyTransport.C
@ -232,10 +203,22 @@ class energyTransport
:
public fvMeshFunctionObject
{
// Private Data
// Private data
//- Volumetric heat capacity field [J/m^3/K]
volScalarField rhoCp_;
//- Name of the transport field.
word fieldName_;
//- Name of flux field
word phiName_;
//- Name of density field
word rhoName_;
//- Number of corrector iterations (optional)
label nCorr_;
//- Name of field whose schemes are used (optional)
word schemesField_;
//- Run-time selectable finite volume options, e.g. sources, constraints
fv::optionList fvOptions_;
@ -246,7 +229,7 @@ class energyTransport
//- List of phase names
wordList phaseNames_;
//- List of phase specific heat capacities at constant pressure
//- List of phase heat capacities
PtrList<dimensionedScalar> Cps_;
//- List of phase thermal diffusivity for temperature [J/m/s/K]
@ -255,7 +238,7 @@ class energyTransport
//- Unallocated phase list
UPtrList<volScalarField> phases_;
//- Specific heat capacity at constant pressure for single phase flows
//- Heat capacity for single phase flows
dimensionedScalar Cp_;
//- Thermal diffusivity for temperature for single phase flows
@ -267,23 +250,8 @@ class energyTransport
//- Turbulent Prandt number
dimensionedScalar Prt_;
//- Name of the transport field
word fieldName_;
//- Name of field whose schemes are used
word schemesField_;
//- Name of flux field
word phiName_;
//- Name of density field
word rhoName_;
//- Outer-loop initial-residual tolerance
scalar tol_;
//- Number of corrector iterations
int nCorr_;
//- rhoCp
volScalarField rhoCp_;
// Private Member Functions
@ -294,15 +262,21 @@ class energyTransport
//- Return the diffusivity field
tmp<volScalarField> kappaEff() const;
//- Return the density field, rho
//- Return rho field
tmp<volScalarField> rho() const;
//- Return the specific heat capacity at constant pressure field, Cp
//- Return Cp
tmp<volScalarField> Cp() const;
//- Return the thermal diffusivity field
//- Return kappa
tmp<volScalarField> kappa() const;
//- No copy construct
energyTransport(const energyTransport&) = delete;
//- No copy assignment
void operator=(const energyTransport&) = delete;
public:
@ -322,7 +296,7 @@ public:
//- Destructor
virtual ~energyTransport() = default;
virtual ~energyTransport();
// Member Functions

View File

@ -27,6 +27,11 @@ License
\*---------------------------------------------------------------------------*/
#include "scalarTransport.H"
#include "surfaceFields.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvmLaplacian.H"
#include "fvmSup.H"
#include "CMULES.H"
#include "turbulentTransportModel.H"
#include "turbulentFluidThermoModel.H"
@ -167,9 +172,7 @@ Foam::functionObjects::scalarTransport::scalarTransport
)
:
fvMeshFunctionObject(name, runTime, dict),
fvOptions_(mesh_),
fieldName_(dict.getOrDefault<word>("field", "s")),
schemesField_("unknown-schemesField"),
phiName_(dict.getOrDefault<word>("phi", "phi")),
rhoName_(dict.getOrDefault<word>("rho", "rho")),
nutName_(dict.getOrDefault<word>("nut", "none")),
@ -179,12 +182,11 @@ Foam::functionObjects::scalarTransport::scalarTransport
dict.getOrDefault<word>("phasePhiCompressed", "alphaPhiUn")
),
D_(0),
alphaD_(1),
alphaDt_(1),
tol_(1),
constantD_(false),
nCorr_(0),
resetOnStartUp_(false),
constantD_(false),
schemesField_("unknown-schemesField"),
fvOptions_(mesh_),
bounded01_(dict.getOrDefault("bounded01", true))
{
read(dict);
@ -200,30 +202,31 @@ Foam::functionObjects::scalarTransport::scalarTransport
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::scalarTransport::~scalarTransport()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::scalarTransport::read(const dictionary& dict)
{
if (!fvMeshFunctionObject::read(dict))
{
return false;
}
fvMeshFunctionObject::read(dict);
dict.readIfPresent("phi", phiName_);
dict.readIfPresent("rho", rhoName_);
dict.readIfPresent("nut", nutName_);
dict.readIfPresent("phase", phaseName_);
dict.readIfPresent("phasePhiCompressed", phasePhiCompressedName_);
dict.readIfPresent("bounded01", bounded01_);
schemesField_ = dict.getOrDefault("schemesField", fieldName_);
constantD_ = dict.readIfPresent("D", D_);
alphaD_ = dict.getOrDefault<scalar>("alphaD", 1);
alphaDt_ = dict.getOrDefault<scalar>("alphaDt", 1);
dict.readIfPresent("alphaD", alphaD_);
dict.readIfPresent("alphaDt", alphaDt_);
dict.readIfPresent("tolerance", tol_);
dict.readIfPresent("nCorr", nCorr_);
dict.readIfPresent("resetOnStartUp", resetOnStartUp_);
constantD_ = dict.readIfPresent("D", D_);
dict.readIfPresent("bounded01", bounded01_);
if (dict.found("fvOptions"))
{
@ -253,10 +256,6 @@ bool Foam::functionObjects::scalarTransport::execute()
scalar relaxCoeff = 0;
mesh_.relaxEquation(schemesField_, relaxCoeff);
// Convergence monitor parameters
bool converged = false;
int iter = 0;
// Two phase scalar transport
if (phaseName_ != "none")
{
@ -273,7 +272,7 @@ bool Foam::functionObjects::scalarTransport::execute()
// Solve
tmp<surfaceScalarField> tTPhiUD;
for (int i = 0; i <= nCorr_; ++i)
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
@ -286,13 +285,9 @@ bool Foam::functionObjects::scalarTransport::execute()
sEqn.relax(relaxCoeff);
fvOptions_.constrain(sEqn);
++iter;
converged = (sEqn.solve(schemesField_).initialResidual() < tol_);
sEqn.solve(schemesField_);
tTPhiUD = sEqn.flux();
if (converged) break;
}
if (bounded01_)
@ -312,8 +307,9 @@ bool Foam::functionObjects::scalarTransport::execute()
{
const volScalarField& rho = lookupObject<volScalarField>(rhoName_);
for (int i = 0; i <= nCorr_; ++i)
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
fvm::ddt(rho, s)
@ -327,14 +323,12 @@ bool Foam::functionObjects::scalarTransport::execute()
fvOptions_.constrain(sEqn);
++iter;
converged = (sEqn.solve(schemesField_).initialResidual() < tol_);
if (converged) break;
sEqn.solve(schemesField_);
}
}
else if (phi.dimensions() == dimVolume/dimTime)
{
for (int i = 0; i <= nCorr_; ++i)
for (label i = 0; i <= nCorr_; i++)
{
fvScalarMatrix sEqn
(
@ -349,9 +343,7 @@ bool Foam::functionObjects::scalarTransport::execute()
fvOptions_.constrain(sEqn);
++iter;
converged = (sEqn.solve(schemesField_).initialResidual() < tol_);
if (converged) break;
sEqn.solve(schemesField_);
}
}
else
@ -362,14 +354,6 @@ bool Foam::functionObjects::scalarTransport::execute()
<< dimVolume/dimTime << exit(FatalError);
}
if (converged)
{
Log << type() << ": " << name() << ": "
<< s.name() << " is converged." << nl
<< tab << "initial-residual tolerance: " << tol_ << nl
<< tab << "outer iteration: " << iter << nl;
}
Log << endl;
return true;

View File

@ -31,134 +31,110 @@ Group
grpSolversFunctionObjects
Description
Computes the transport equation for a passive scalar in single-phase or
two-phase flow, considering both incompressible and compressible cases:
Evolves a passive scalar transport equation.
\f[
\frac{\partial \rho \, T}{\partial t}
+ \nabla \cdot \left( \phi_\alpha \, T \right)
- \nabla \cdot (D_T \, \nabla T)
= \alpha \, S_T
\f]
where:
\vartable
T | Passive scalar field
\rho | (Generic) Fluid density which is unity when not specified
\phi_\alpha | (Generic) Flux field
\alpha | Phase fraction which is unity for single-phase flows
D_T | Diffusivity representing the diffusive transport of T
S_T | Passive-scalar field source term
\endvartable
- To specify the field name set the \c field entry
- To employ the same numerical schemes as another field set
the \c schemesField entry,
- The diffusivity can be set manually using the 'D' entry, retrieved
from the turbulence model or specified nut
- Alternatively if a turbulence model is available a turbulent diffusivity
may be constructed from the laminar and turbulent viscosities using the
optional diffusivity coefficients \c alphaD and \c alphaDt (which default
to 1):
\verbatim
D = alphaD*nu + alphaDt*nut
\endverbatim
- To specify a transport quantity within a phase enter phase.
- bounded01 bounds the transported scalar within 0 and 1.
Usage
Minimal example in \c system/controlDict.functions:
Example of function object specification to solve a scalar transport
equation:
\verbatim
scalarTransport1
functions
{
// Mandatory entries
type scalarTransport;
libs (solverFunctionObjects);
// Optional entries
field <word>;
phi <word>;
rho <word>;
nut <word>;
phase <word>;
phasePhiCompressed <word>;
schemesField <word>;
bounded01 <bool>;
D <scalar>;
alphaD <scalar>;
alphaDt <scalar>;
tolerance <scalar>;
nCorr <int>;
resetOnStartUp <bool>;
fvOptions <dict>;
// Inherited entries
...
}
where:
\table
Property | Description | Type | Reqd | Deflt
type | Type name: scalarTransport | word | yes | -
libs | Library name: solverFunctionObjects | word | yes | -
field | Name of the passive-scalar field | word | no | s
phi | Name of flux field | word | no | phi
rho | Name of density field | word | no | rho
nut | Name of the turbulence viscosity | word | no | none
phase | Name of the phase | word | no | none
phasePhiCompressed | Name of compressed VOF flux | word | no | alphaPhiUn
schemesField | Name of field to specify schemes | word | no | field
bounded01 | Bounds scalar between 0-1 for multiphase | bool | no | true
D | Diffusion coefficient | scalar | no | -
alphaD | Laminar diffusivity coefficient | scalar | no | 1
alphaDt | Turbulent diffusivity coefficient | scalar | no | 1
tolerance | Outer-loop initial-residual tolerance | scalar | no | 1
nCorr | Number of outer-loop correctors | int | no | 0
resetOnStartUp | Flag to reset field to zero on start-up | bool | no | no
fvOptions | List of finite-volume options | dict | no | -
\endtable
The inherited entries are elaborated in:
- \link fvMeshFunctionObject.H \endlink
- \link fvOption.H \endlink
An example of function object specification to solve a residence time
in a two-phase flow:
\verbatim
scalarTransport1
{
// Mandatory entries
type scalarTransport;
libs (solverFunctionObjects);
// Optional entries
field s;
bounded01 false;
phase alpha.water;
tolerance 1e-5;
resetOnStartUp false;
fvOptions
scalar1
{
unitySource
type scalarTransport;
libs (solverFunctionObjects);
resetOnStartUp no;
region cabin;
field H2O;
fvOptions
{
type scalarSemiImplicitSource;
enabled true;
selectionMode all;
volumeMode specific;
sources
{
s (1 0);
}
...
}
}
// Inherited entries
enabled true;
writeControl writeTime;
writeInterval 1;
}
\endverbatim
Note
- To use the same numerical schemes as another field,
set the \c schemesField entry.
- The diffusivity can be set manually using the \c D entry, obtained
from the turbulence model or specified as `nut`.
- Alternatively, if a turbulence model is available, turbulent diffusivity
can be constructed from the laminar and turbulent viscosities using the
optional diffusivity coefficients \c alphaD and \c alphaDt
(which default to 1):
Example of function object specification to solve a residence time
in a two phase flow:
equation:
\verbatim
functions
{
sTransport
{
type scalarTransport;
libs (solverFunctionObjects);
\f[
D = \alpha_D \, \nu + \alpha_{Dt} \, \nu_t
\f]
enabled true;
writeControl writeTime;
writeInterval 1;
field s;
bounded01 false;
phase alpha.water;
write true;
fvOptions
{
unitySource
{
type scalarSemiImplicitSource;
enabled true;
selectionMode all;
volumeMode specific;
sources
{
s (1 0);
}
}
}
resetOnStartUp false;
}
}
\endverbatim
Where the entries comprise:
\table
Property | Description | Required | Default value
type | Type name: scalarTransport | yes |
field | Name of the scalar field | no | s
phi | Name of flux field | no | phi
rho | Name of density field | no | rho
phase | Name of the phase | no | none
nut | Name of the turbulence viscosity | no | none
D | Diffusion coefficient | no | auto generated
nCorr | Number of correctors | no | 0
resetOnStartUp | Reset scalar to zero on start-up | no | no
schemesField | Name of field to specify schemes | no | field name
fvOptions | List of scalar sources | no |
bounded01 | Bounds scalar between 0-1 for multiphase | no | true
phasePhiCompressed | Compressed flux for VOF | no | alphaPhiUn
\endtable
See also
Foam::functionObjects::fvMeshFunctionObject
SourceFiles
scalarTransport.C
@ -187,52 +163,49 @@ class scalarTransport
:
public fvMeshFunctionObject
{
// Private Data
//- Run-time selectable finite volume options, e.g. sources, constraints
fv::optionList fvOptions_;
// Private data
//- Name of the transport field.
word fieldName_;
//- Name of field whose schemes are used
word schemesField_;
//- Name of flux field
//- Name of flux field (optional)
word phiName_;
//- Name of density field
//- Name of density field (optional)
word rhoName_;
//- Name of turbulent viscosity field
//- Name of turbulent viscosity field (optional)
word nutName_;
//- Name of phase field
//- Name of phase field (optional)
word phaseName_;
//- Name of phase field compressed flux
//- Name of phase field compressed flux (optional)
word phasePhiCompressedName_;
//- Diffusion coefficient
//- Diffusion coefficient (optional)
scalar D_;
//- Laminar diffusion coefficient
//- Flag to indicate whether a constant, uniform D_ is specified
bool constantD_;
//- Laminar diffusion coefficient (optional)
scalar alphaD_;
//- Turbulent diffusion coefficient
//- Turbulent diffusion coefficient (optional)
scalar alphaDt_;
//- Outer-loop initial-residual tolerance
scalar tol_;
//- Number of corrector iterations
int nCorr_;
//- Number of corrector iterations (optional)
label nCorr_;
//- Flag to reset the scalar to zero on start-up
bool resetOnStartUp_;
//- Flag to indicate whether a constant, uniform D_ is specified
bool constantD_;
//- Name of field whose schemes are used (optional)
word schemesField_;
//- Run-time selectable finite volume options, e.g. sources, constraints
fv::optionList fvOptions_;
//- Bound scalar between 0-1 using MULES for multiphase case
bool bounded01_;
@ -250,6 +223,12 @@ class scalarTransport
const surfaceScalarField& phi
) const;
//- No copy construct
scalarTransport(const scalarTransport&) = delete;
//- No copy assignment
void operator=(const scalarTransport&) = delete;
public:
@ -269,7 +248,7 @@ public:
//- Destructor
virtual ~scalarTransport() = default;
virtual ~scalarTransport();
// Member Functions

View File

@ -2054,6 +2054,7 @@ Foam::labelList Foam::meshRefinement::intersectedPoints() const
// Mark all points on faces that will become baffles
bitSet isBoundaryPoint(mesh_.nPoints());
label nBoundaryPoints = 0;
const labelList& surfIndex = surfaceIndex();
@ -2061,7 +2062,15 @@ Foam::labelList Foam::meshRefinement::intersectedPoints() const
{
if (surfIndex[facei] != -1)
{
isBoundaryPoint.set(faces[facei]);
const face& f = faces[facei];
forAll(f, fp)
{
if (isBoundaryPoint.set(f[fp]))
{
nBoundaryPoints++;
}
}
}
}
@ -2074,17 +2083,37 @@ Foam::labelList Foam::meshRefinement::intersectedPoints() const
// if (patchi != -1)
// {
// const polyPatch& pp = mesh_.boundaryMesh()[patchi];
//
// label facei = pp.start();
//
// forAll(pp, i)
// {
// isBoundaryPoint.set(faces[pp.start()+i]);
// const face& f = faces[facei];
//
// forAll(f, fp)
// {
// if (isBoundaryPoint.set(f[fp]))
// nBoundaryPoints++;
// }
// }
// facei++;
// }
// }
//}
// Make sure all processors have the same data
syncTools::syncPointList(mesh_, isBoundaryPoint, orEqOp<unsigned int>(), 0);
return isBoundaryPoint.sortedToc();
// Pack
labelList boundaryPoints(nBoundaryPoints);
nBoundaryPoints = 0;
forAll(isBoundaryPoint, pointi)
{
if (isBoundaryPoint.test(pointi))
{
boundaryPoints[nBoundaryPoints++] = pointi;
}
}
return boundaryPoints;
}

View File

@ -256,7 +256,7 @@ void Foam::cellDistFuncs::correctBoundaryFaceCells
{
if (areaFraction && (areaFraction()[patchFacei] <= 0.5))
{
// For cyclicACMI: more cyclic than wall
// is mostly coupled
continue;
}
@ -311,9 +311,9 @@ void Foam::cellDistFuncs::correctBoundaryPointCells
// Check cells with face on wall
forAll(patch, patchFacei)
{
if (areaFraction && (areaFraction()[patchFacei] <= 0.5))
if (!areaFraction || (areaFraction()[patchFacei] <= 0.5))
{
// For cyclicACMI: more cyclic than wall
// face mostly coupled
isWallPoint.unset(localFaces[patchFacei]);
}
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017,2024 OpenCFD Ltd.
Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,7 +26,7 @@ License
\*---------------------------------------------------------------------------*/
#include "cellCellStencilObject.H"
#include "dynamicOversetFvMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -36,25 +36,4 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::cellCellStencilObject::movePoints()
{
// Update (if needed) underlying stencil
const bool changed = stencilPtr_().update();
if (changed)
{
const auto* oversetMeshPtr = isA<oversetFvMeshBase>(mesh());
if (oversetMeshPtr)
{
// Clear out any additional (ldu)addressing
const_cast<oversetFvMeshBase&>(*oversetMeshPtr).clearOut();
}
}
return changed;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2019,2024 OpenCFD Ltd.
Copyright (C) 2017-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -54,9 +54,19 @@ typedef MeshObject<fvMesh, MoveableMeshObject, cellCellStencilObject> Stencil;
class cellCellStencilObject
:
public Stencil,
public MeshObject<fvMesh, MoveableMeshObject, cellCellStencilObject>,
public cellCellStencil
{
// Private Typedefs
typedef MeshObject
<
fvMesh,
MoveableMeshObject,
cellCellStencilObject
> MeshObject_type;
// Private Data
autoPtr<cellCellStencil> stencilPtr_;
@ -76,7 +86,8 @@ public:
const bool update = true
)
:
Stencil(mesh),
MeshObject_type(mesh),
cellCellStencil(mesh),
stencilPtr_
(
@ -100,7 +111,10 @@ public:
// Member Functions
//- Callback for geometry motion
virtual bool movePoints();
virtual bool movePoints()
{
return stencilPtr_().update();
}
//- Update stencils. Return false if nothing changed.
virtual bool update()

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022,2024 OpenCFD Ltd.
Copyright (C) 2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -65,10 +65,6 @@ bool Foam::dynamicOversetFvMesh::update()
return false;
}
//Note: too late to do oversetFvMeshBase::clearOut() to get it
// consistent with any new cell-cell stencil since
// dynamicMotionSolverListFvMesh already triggers
// meshObject::movePoints on cellCellStencilObject
oversetFvMeshBase::update();
return true;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2022,2024 OpenCFD Ltd.
Copyright (C) 2014-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -578,14 +578,6 @@ Foam::oversetFvMeshBase::primitiveLduAddr() const
}
void Foam::oversetFvMeshBase::clearOut()
{
// Cell-cell stencil is already mesh object. Clear out local
// addressing to force rebuilding addressing
lduPtr_.clear();
}
bool Foam::oversetFvMeshBase::update()
{
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015-2022,2024 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,6 +37,7 @@ SourceFiles
#ifndef oversetFvMeshBase_H
#define oversetFvMeshBase_H
#include "fvMeshPrimitiveLduAddressing.H"
#include "fvMeshPrimitiveLduAddressing.H"
#include "lduInterfaceFieldPtrsList.H"
#include "volFieldsFwd.H"
@ -237,9 +238,6 @@ public:
) const;
//- Clear out local storage
void clearOut();
//- Update the mesh for both mesh motion and topology change
virtual bool update();

View File

@ -75,7 +75,6 @@ void Foam::RBD::rigidBodySolvers::symplectic::solve
qDot() = qDot0() + 0.5*deltaT0()*qDdot();
q() = q0() + deltaT()*qDot();
// Update joints from new locations (q, q0)
correctQuaternionJoints();
// Update the body-state prior to the evaluation of the restraints

View File

@ -35,7 +35,7 @@ geometry
}
// Box size
vo #eval{ $outerRadius/sqrt(3) };
vo #eval{ sqrt($outerRadius/3) };
vertices
(

View File

@ -38,7 +38,7 @@ geometry
}
// Outer box size
vo #eval{ $outerRadius/sqrt(3) };
vo #eval{ sqrt($outerRadius/3) };
// Inner box size - % of overall dimension
vi #eval{ $vo * $innerRatio };

View File

@ -45,7 +45,7 @@ geometry
// Outer box size (approximate)
vo #eval{ $outerRadius/sqrt(3) };
vo #eval{ sqrt($outerRadius/3) };
// Inner box size - % of overall dimension
vi #eval{ $vo * $innerRatio };