Compare commits

..

4 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
dce009cef1 ENH: make Nastran PLOAD2,PLOAD4 field mappings optional
- PLOAD2 is a reasonable default and PLOAD4 output
  (currently misused for vectors/tensors) is the exception.

- simplify the specification by using optional PLOAD4, PLOAD2 wordRes
  lists to act as allow/deny selectors. In the regular case won't need
  to specify anything or perhaps only the PLOAD4 list.

ENH: atomic creation of Nastran files

FIX: inconsistent Nastran surface output format

- use FREE format by default. Previously had an odd mix of SHORT
  format when created without options and LONG format (as default)
  when created with format options.
2024-06-26 16:53:13 +02:00
d8d3e34d5c COMP: fix dangling references (gcc13+: -Wdangling-reference) 2024-06-26 16:53:05 +02:00
d300fab63a ENH: reduce some allocations in rawTopoChangerFvMesh
- cache and reuse the zero field

STYLE: use templated form of objectRegistry::names<..>
2024-06-26 16:51:12 +02:00
57 changed files with 1538 additions and 836 deletions

View File

@ -1,15 +1,13 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
# Run from OPENFOAM top-level directory only
cd "${0%/*}" || exit
wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || {
echo "Error (${0##*/}) : not located in \$WM_PROJECT_DIR"
echo " Check your OpenFOAM environment and installation"
exit 1
}
if [ -f "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments ]
then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments || \
then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments -no-recursion "$@" || \
echo "Argument parse error"
else
echo "Error (${0##*/}) : WM_PROJECT_DIR appears to be incorrect"

View File

@ -1,15 +1,13 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
# Run from OPENFOAM top-level directory only
cd "${0%/*}" || exit
wmake -check-dir "$WM_PROJECT_DIR" 2>/dev/null || {
echo "Error (${0##*/}) : not located in \$WM_PROJECT_DIR"
echo " Check your OpenFOAM environment and installation"
exit 1
}
if [ -f "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments ]
then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments || \
then . "$WM_PROJECT_DIR"/wmake/scripts/AllwmakeParseArguments -no-recursion "$@" || \
echo "Argument parse error"
else
echo "Error (${0##*/}) : WM_PROJECT_DIR appears to be incorrect"

View File

@ -1,2 +1,2 @@
api=2406
patch=241212
patch=0

View File

@ -8,11 +8,13 @@
volVectorField& U1 = phase1.URef();
surfaceScalarField& phi1 = phase1.phiRef();
const surfaceScalarField& alphaPhi1 = phase1.alphaPhi();
const tmp<surfaceScalarField> talphaPhi1 = phase1.alphaPhi();
const auto& alphaPhi1 = talphaPhi1();
volVectorField& U2 = phase2.URef();
surfaceScalarField& phi2 = phase2.phiRef();
const surfaceScalarField& alphaPhi2 = phase2.alphaPhi();
const tmp<surfaceScalarField> talphaPhi2 = phase2.alphaPhi();
const auto& alphaPhi2 = talphaPhi2();
surfaceScalarField& phi = fluid.phi();

View File

@ -74,8 +74,11 @@ Foam::compressibleInterPhaseTransportModel::compressibleInterPhaseTransportModel
const volScalarField& alpha1(mixture_.alpha1());
const volScalarField& alpha2(mixture_.alpha2());
const volScalarField& rho1 = mixture_.thermo1().rho();
const volScalarField& rho2 = mixture_.thermo2().rho();
const tmp<volScalarField> trho1 = mixture_.thermo1().rho();
const tmp<volScalarField> trho2 = mixture_.thermo2().rho();
const auto& rho1 = trho1();
const auto& rho2 = trho2();
alphaRhoPhi1_ =
(
@ -185,8 +188,8 @@ void Foam::compressibleInterPhaseTransportModel::correctPhasePhi()
{
if (twoPhaseTransport_)
{
const volScalarField& rho1 = mixture_.thermo1().rho();
const volScalarField& rho2 = mixture_.thermo2().rho();
const tmp<volScalarField> rho1 = mixture_.thermo1().rho();
const tmp<volScalarField> rho2 = mixture_.thermo2().rho();
alphaRhoPhi1_.ref() = fvc::interpolate(rho1)*alphaPhi10_;
alphaRhoPhi2_.ref() = fvc::interpolate(rho2)*(phi_ - alphaPhi10_);

View File

@ -12,8 +12,11 @@ for (int Ecorr=0; Ecorr<nEnergyCorrectors; Ecorr++)
phaseModel& phase = fluid.anisothermalPhases()[anisothermalPhasei];
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
const volVectorField& U = phase.U();
const tmp<volScalarField> trho = phase.rho();
const tmp<volVectorField> tU = phase.U();
const auto& rho = trho();
const auto& U = tU();
fvScalarMatrix EEqn
(

View File

@ -11,7 +11,9 @@
UPtrList<volScalarField>& Y = phase.YActiveRef();
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
const tmp<volScalarField> trho = phase.rho();
const auto& rho = trho();
forAll(Y, i)
{

View File

@ -14,9 +14,11 @@ PtrList<fvVectorMatrix> UEqns(phases.size());
phaseModel& phase = fluid.movingPhases()[movingPhasei];
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
const tmp<volScalarField> trho = phase.rho();
volVectorField& U = phase.URef();
const auto& rho = trho();
UEqns.set
(
phase.index(),

View File

@ -17,9 +17,11 @@ PtrList<fvVectorMatrix> UEqns(phases.size());
phaseModel& phase = fluid.movingPhases()[movingPhasei];
const volScalarField& alpha = phase;
const volScalarField& rho = phase.rho();
const tmp<volScalarField> trho = phase.rho();
volVectorField& U = phase.URef();
const auto& rho = trho();
UEqns.set
(
phase.index(),

View File

@ -6,11 +6,13 @@ const volScalarField& alpha2 = phase2;
volVectorField& U1 = phase1.URef();
surfaceScalarField& phi1 = phase1.phiRef();
const surfaceScalarField& alphaPhi1 = phase1.alphaPhi();
const tmp<surfaceScalarField> talphaPhi1 = phase1.alphaPhi();
const auto& alphaPhi1 = talphaPhi1();
volVectorField& U2 = phase2.URef();
surfaceScalarField& phi2 = phase2.phiRef();
const surfaceScalarField& alphaPhi2 = phase2.alphaPhi();
const tmp<surfaceScalarField> talphaPhi2 = phase2.alphaPhi();
const auto& alphaPhi2 = talphaPhi2();
surfaceScalarField& phi = fluid.phi();

View File

@ -1,7 +1,6 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments -no-recursion "$@"
. ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions
#------------------------------------------------------------------------------

View File

@ -743,12 +743,12 @@ Foam::label Foam::cellShapeControlMesh::estimateCellCount
cit->vertex(3)->point()
);
pointFromPoint centre = topoint(CGAL::centroid(tet));
const auto tetCentre = CGAL::centroid(tet);
if
(
Pstream::parRun()
&& !decomposition().positionOnThisProcessor(centre)
UPstream::parRun()
&& !decomposition().positionOnThisProcessor(topoint(tetCentre))
)
{
continue;

View File

@ -176,7 +176,7 @@ autoPtr<labelIOList> procAddressing
const objectRegistry& procRegistry,
const word& name,
const word& instance,
const word& local = fvMesh::meshSubDir
const word& local = polyMesh::meshSubDir
)
{
return autoPtr<labelIOList>::New
@ -218,17 +218,22 @@ const labelIOList& procAddressing
PtrList<labelIOList>& procAddressingList
)
{
const fvMesh& procMesh = procMeshList[proci];
const auto& procMesh = procMeshList[proci];
if (!procAddressingList.set(proci))
{
procAddressingList.set
return procAddressingList.try_emplace
(
proci,
IOobject
(
proci,
procAddressing(procMesh, name, procMesh.facesInstance())
);
}
return procAddressingList[proci];
name,
procMesh.facesInstance(),
polyMesh::meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
)
);
}

View File

@ -119,10 +119,10 @@ public:
#if __cplusplus >= 201703L
//- Construct (shallow copy) from std::string_view content
explicit ispanstream(std::string_view s)
:
{
buffer_type(const_cast<char*>(s.data()), s.size()),
stream_type(static_cast<buffer_type*>(this))
{}
stream_type(static_cast<buffer_type*>(this));
}
#endif
//- Construct (shallow copy) from span character content

View File

@ -157,10 +157,7 @@ Foam::error::error(const error& err)
throwing_(err.throwing_),
messageStreamPtr_(nullptr)
{
// FIXME: OStringStream copy construct does not adjust tellp and
// thus the count is wrong! (#3281)
// // if (err.messageStreamPtr_ && (err.messageStreamPtr_->count() > 0))
if (err.messageStreamPtr_)
if (err.messageStreamPtr_ && (err.messageStreamPtr_->count() > 0))
{
messageStreamPtr_.reset(new OStringStream(*err.messageStreamPtr_));
}

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

@ -888,7 +888,7 @@ boundaryInternalField() const
*this
);
auto& result = tresult.ref();
auto& result = tresult;
forAll(result, patchi)
{

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

@ -1,7 +1,6 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments -no-recursion "$@"
. ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions
#------------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -136,8 +136,7 @@ std::string Foam::fileFormats::NASCore::nextNasField
(
const std::string& str,
std::string::size_type& pos,
const std::string::size_type width,
const bool free_format
std::string::size_type len
)
{
const auto beg = pos;
@ -145,23 +144,15 @@ std::string Foam::fileFormats::NASCore::nextNasField
if (end == std::string::npos)
{
if (free_format)
{
// Nothing left
pos = str.size();
return str.substr(beg);
}
// Fixed format - continue after field width
pos = beg + width;
return str.substr(beg, width);
pos = beg + len; // Continue after field width
}
else
{
// Free format - continue after comma
pos = end + 1;
return str.substr(beg, (end - beg));
len = (end - beg); // Efffective width
pos = end + 1; // Continue after comma
}
return str.substr(beg, len);
}
@ -258,8 +249,8 @@ void Foam::fileFormats::NASCore::writeCoord
// 2 ID : point ID - requires starting index of 1
// 3 CP : coordinate system ID (blank)
// 4 X1 : point x coordinate
// 5 X2 : point y coordinate
// 6 X3 : point z coordinate
// 5 X2 : point x coordinate
// 6 X3 : point x coordinate
// 7 CD : coordinate system for displacements (blank)
// 8 PS : single point constraints (blank)
// 9 SEID : super-element ID

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,6 +47,7 @@ SourceFiles
namespace Foam
{
namespace fileFormats
{
@ -78,18 +79,18 @@ public:
//- Output load format
enum loadFormat
{
PLOAD2, //!< Face load (eg, pressure)
PLOAD4 //!< Vertex load
PLOAD2,
PLOAD4
};
//- Selection names for the NASTRAN load formats
//- Selection names for the NASTRAN file field formats
static const Enum<loadFormat> loadFormatNames;
// Constructors
//- Default construct
NASCore() noexcept = default;
NASCore() = default;
// Public Static Member Functions
@ -97,20 +98,18 @@ public:
//- Extract numbers from things like "-2.358-8" (same as "-2.358e-8")
static scalar readNasScalar(const std::string& str);
//- A std::string::substr() variant to handle fixed-format and
//- free-format NASTRAN.
// Returns the substr until the next comma (if found)
// or the given fixed width
//- A string::substr() to handle fixed-format and free-format NASTRAN.
// Returns the substr to the next comma (if found) or the given length
//
// \param str The string to extract from
// \param pos On input, the position of the first character of the
// substring. On output, advances to the next position to use.
// \param len The fixed-format length to use if a comma is not found.
static std::string nextNasField
(
//! The string to extract from
const std::string& str,
//! [in,out] The parse position within \p str
std::string::size_type& pos,
//! The fixed-format width to use (if comma is not found)
const std::string::size_type width,
//! The input is known to be free-format
const bool free_format = false
std::string::size_type len
);

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) 2018-2022 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -250,12 +250,12 @@ Foam::fileName Foam::coordSetWriters::nastranWriter::writeTemplate
Info<< "Writing nastran geometry to " << outputFile << endl;
}
if (!isDir(outputFile.path()))
if (!Foam::isDir(outputFile.path()))
{
mkDir(outputFile.path());
Foam::mkDir(outputFile.path());
}
OFstream os(outputFile);
OFstream os(IOstreamOption::ATOMIC, outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
os << "TITLE=OpenFOAM " << outputFile.stem()
@ -293,12 +293,12 @@ Foam::fileName Foam::coordSetWriters::nastranWriter::writeTemplate
Info<< "Writing nastran geometry to " << outputFile << endl;
}
if (!isDir(outputFile.path()))
if (!Foam::isDir(outputFile.path()))
{
mkDir(outputFile.path());
Foam::mkDir(outputFile.path());
}
OFstream os(outputFile);
OFstream os(IOstreamOption::ATOMIC, outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
os << "TITLE=OpenFOAM " << outputFile.stem()

View File

@ -62,17 +62,13 @@ bool Foam::fileFormats::NASedgeFormat::read
while (is.good())
{
string::size_type linei = 0; // parsing position within current line
string line;
is.getLine(line);
if (line.empty())
if (line.empty() || line[0] == '$')
{
continue; // Ignore empty
}
else if (line[0] == '$')
{
// Ignore comment
continue;
continue; // Skip empty or comment
}
// Check if character 72 is continuation
@ -98,69 +94,41 @@ bool Foam::fileFormats::NASedgeFormat::read
}
// Parsing position within current line
std::string::size_type linei = 0;
// Is free format if line contains a comma
const bool freeFormat = line.contains(',');
// First word (column 0-8)
const word cmd(word::validate(nextNasField(line, linei, 8)));
if (cmd == "CBEAM" || cmd == "CROD")
{
// Fixed format:
// 8-16 : element id
// 16-24 : group id
// 24-32 : vertex
// 32-40 : vertex
// discard elementId (8-16)
(void) nextNasField(line, linei, 8); // 8-16
// discard groupId (16-24)
(void) nextNasField(line, linei, 8); // 16-24
// discard elementId
(void) nextNasField(line, linei, 8, freeFormat);
// discard groupId
(void) nextNasField(line, linei, 8, freeFormat);
label a = readLabel(nextNasField(line, linei, 8)); // 24-32
label b = readLabel(nextNasField(line, linei, 8)); // 32-40
label a = readLabel(nextNasField(line, linei, 8, freeFormat));
label b = readLabel(nextNasField(line, linei, 8, freeFormat));
dynEdges.emplace_back(a,b);
dynEdges.append(edge(a,b));
}
else if (cmd == "PLOTEL")
{
// Fixed format:
// 8-16 : element id
// 16-24 : vertex
// 24-32 : vertex
// 32-40 : vertex
// discard elementId (8-16)
(void) nextNasField(line, linei, 8, freeFormat);
(void) nextNasField(line, linei, 8); // 8-16
label a = readLabel(nextNasField(line, linei, 8, freeFormat));
label b = readLabel(nextNasField(line, linei, 8, freeFormat));
label a = readLabel(nextNasField(line, linei, 8)); // 16-24
label b = readLabel(nextNasField(line, linei, 8)); // 24-32
dynEdges.emplace_back(a,b);
dynEdges.append(edge(a,b));
}
else if (cmd == "GRID")
{
// Fixed (short) format:
// 8-16 : point id
// 16-24 : coordinate system (unsupported)
// 24-32 : point x coordinate
// 32-40 : point y coordinate
// 40-48 : point z coordinate
// 48-56 : displacement coordinate system (optional, unsupported)
// 56-64 : single point constraints (optional, unsupported)
// 64-70 : super-element id (optional, unsupported)
label index = readLabel(nextNasField(line, linei, 8)); // 8-16
(void) nextNasField(line, linei, 8); // 16-24
scalar x = readNasScalar(nextNasField(line, linei, 8)); // 24-32
scalar y = readNasScalar(nextNasField(line, linei, 8)); // 32-40
scalar z = readNasScalar(nextNasField(line, linei, 8)); // 40-48
label index = readLabel(nextNasField(line, linei, 8, freeFormat));
(void) nextNasField(line, linei, 8, freeFormat);
scalar x = readNasScalar(nextNasField(line, linei, 8, freeFormat));
scalar y = readNasScalar(nextNasField(line, linei, 8, freeFormat));
scalar z = readNasScalar(nextNasField(line, linei, 8, freeFormat));
pointId.push_back(index);
dynPoints.emplace_back(x, y, z);
pointId.append(index);
dynPoints.append(point(x, y, z));
}
else if (cmd == "GRID*")
{
@ -170,8 +138,6 @@ bool Foam::fileFormats::NASedgeFormat::read
// GRID* 126 0 -5.55999875E+02 -5.68730474E+02
// * 2.14897901E+02
// Cannot be long format and free format at the same time!
label index = readLabel(nextNasField(line, linei, 16)); // 8-24
(void) nextNasField(line, linei, 16); // 24-40
scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56
@ -191,8 +157,8 @@ bool Foam::fileFormats::NASedgeFormat::read
(void) nextNasField(line, linei, 8); // 0-8
scalar z = readNasScalar(nextNasField(line, linei, 16)); // 8-16
pointId.push_back(index);
dynPoints.emplace_back(x, y, z);
pointId.append(index);
dynPoints.append(point(x, y, z));
}
}

View File

@ -136,6 +136,82 @@ void Foam::designVariablesUpdate::writeToCostFile(bool zeroAdjointSolns)
}
void Foam::designVariablesUpdate::checkConvergence
(
const scalarField& oldCorrection
)
{
bool converged(false);
// Design variables convergence check
if (designVarsThreshold_)
{
const labelList& activeVarIDs =
designVars_->activeDesignVariables();
const scalarField correction(oldCorrection, activeVarIDs);
const scalarField activeVars(designVars_->getVars(), activeVarIDs);
const scalar scaledCorrection =
gMax(mag(correction)/(mag(activeVars) + SMALL));
DebugInfo
<< "Current correction " << correction << nl
<< "Active vars " << activeVars << endl;
Info<< "Max. scaled correction of the design variables = "
<< scaledCorrection
<< endl;
if (scaledCorrection < designVarsThreshold_())
{
Info<< tab << "Design variables have converged " << endl;
converged = true;
}
}
// Objective convergence check
if (objectiveThreshold_)
{
const scalar newObjective = computeObjectiveValue();
const scalar oldObjective = updateMethod_->getObjectiveValueOld();
const scalar relativeUpdate =
mag(newObjective - oldObjective)/(mag(oldObjective) + SMALL);
Info<< "Relative change of the objective value = "
<< relativeUpdate
<< endl;
if (relativeUpdate < objectiveThreshold_())
{
Info<< tab << "Objective function has converged " << endl;
converged = true;
}
}
// Feasibility check
const scalarField& constraints = updateMethod_->getConstraintValues();
const scalar feasibility = sum(pos(constraints)*constraints);
Info<< "Feasibility = " << feasibility << endl;
if (converged && feasibility < feasibilityThreshold_)
{
Info<< "Stopping criteria met and all constraints satisfied." << nl
<< "Optimisation has converged, stopping ..." << nl << nl
<< "End" << nl
<< endl;
// Force writing of all objective and constraint functions, to get
// the converged results to files
for (adjointSolverManager& am : adjointSolvManagers_)
{
for (adjointSolver& as : am.adjointSolvers())
{
// Use dummy weighted objective
as.getObjectiveManager().writeObjectives();
}
}
writeToCostFile(true);
if (UPstream::parRun())
{
UPstream::exit(0);
}
else
{
std::exit(0);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::designVariablesUpdate::designVariablesUpdate
@ -494,86 +570,10 @@ void Foam::designVariablesUpdate::postUpdate(const scalarField& oldCorrection)
}
}
}
checkConvergence();
}
}
void Foam::designVariablesUpdate::checkConvergence()
{
if (!convergenceCriteriaDefined_)
if (convergenceCriteriaDefined_)
{
return;
}
bool converged(false);
const scalarField& oldCorrection = updateMethod_->returnCorrection();
// Design variables convergence check
if (designVarsThreshold_)
{
const labelList& activeVarIDs =
designVars_->activeDesignVariables();
const scalarField correction(oldCorrection, activeVarIDs);
const scalarField activeVars(designVars_->getVars(), activeVarIDs);
const scalar scaledCorrection =
gMax(mag(correction)/(mag(activeVars) + SMALL));
DebugInfo
<< "Current correction " << correction << nl
<< "Active vars " << activeVars << endl;
Info<< "Max. scaled correction of the design variables = "
<< scaledCorrection
<< endl;
if (scaledCorrection < designVarsThreshold_())
{
Info<< tab << "Design variables have converged " << endl;
converged = true;
}
}
// Objective convergence check
if (objectiveThreshold_ && updateMethod_->getObjectiveValueOld())
{
const scalar newObjective = computeObjectiveValue();
const scalar oldObjective = updateMethod_->getObjectiveValueOld()();
const scalar relativeUpdate =
mag(newObjective - oldObjective)/(mag(oldObjective) + SMALL);
Info<< "Relative change of the objective value = "
<< relativeUpdate
<< endl;
if (relativeUpdate < objectiveThreshold_())
{
Info<< tab << "Objective function has converged " << endl;
converged = true;
}
}
// Feasibility check
const scalarField& constraints = updateMethod_->getConstraintValues();
const scalar feasibility = sum(pos(constraints)*constraints);
Info<< "Feasibility = " << feasibility << endl;
if (converged && feasibility < feasibilityThreshold_)
{
Info<< "Stopping criteria met and all constraints satisfied." << nl
<< "Optimisation has converged, stopping ..." << nl << nl
<< "End" << nl
<< endl;
// Force writing of all objective and constraint functions, to get
// the converged results to files
for (adjointSolverManager& am : adjointSolvManagers_)
{
for (adjointSolver& as : am.adjointSolvers())
{
// Use dummy weighted objective
as.getObjectiveManager().writeObjectives();
}
}
writeToCostFile(true);
if (UPstream::parRun())
{
UPstream::exit(0);
}
else
{
std::exit(0);
}
checkConvergence(oldCorrection);
}
}

View File

@ -138,6 +138,11 @@ protected:
//- Write to cost file
void writeToCostFile(bool zeroAdjointSolns = false);
//- Check if the optimisation loop has converged based on the provided
//- criteria
// May terminate the program
void checkConvergence(const scalarField& oldCorrection);
private:
@ -211,11 +216,6 @@ public:
//- in the fixedStep approach
void postUpdate(const scalarField& oldCorrection);
//- Check if the optimisation loop has converged based on the provided
//- criteria
// May terminate the program
void checkConvergence();
//- Get access to design variables
inline autoPtr<designVariables>& getDesignVariables()
{

View File

@ -172,9 +172,6 @@ void Foam::optimisationManager::fixedStepUpdate()
// Solve primal equations
solvePrimalEquations();
// Check the convergence criteria of the optimisation loop
dvUpdate_->checkConvergence();
// Reset adjoint sensitivities in all adjoint solver managers
clearSensitivities();

View File

@ -237,7 +237,7 @@ Foam::updateMethod::updateMethod
objectiveDerivatives_(designVars().getVars().size(), Zero),
constraintDerivatives_(0),
objectiveValue_(0),
objectiveValueOld_(nullptr),
objectiveValueOld_(0),
cValues_(0),
correction_(readOrZeroField("correction", designVars().getVars().size())),
cumulativeCorrection_(0),
@ -334,11 +334,7 @@ void Foam::updateMethod::setObjectiveValue(const scalar value)
void Foam::updateMethod::setObjectiveValueOld(const scalar value)
{
if (!objectiveValueOld_)
{
objectiveValueOld_.reset(new scalar(Zero));
}
objectiveValueOld_.ref() = value;
objectiveValueOld_ = value;
}
@ -354,8 +350,7 @@ Foam::scalar Foam::updateMethod::getObjectiveValue() const
}
const Foam::autoPtr<Foam::scalar>&
Foam::updateMethod::getObjectiveValueOld() const
Foam::scalar Foam::updateMethod::getObjectiveValueOld() const
{
return objectiveValueOld_;
}

View File

@ -84,7 +84,7 @@ protected:
//- Old objective value
// Used for convergence checking
autoPtr<scalar> objectiveValueOld_;
scalar objectiveValueOld_;
//- Constraint values
scalarField cValues_;
@ -239,7 +239,7 @@ public:
scalar getObjectiveValue() const;
//- Get old objective value
const autoPtr<scalar>& getObjectiveValueOld() const;
scalar getObjectiveValueOld() const;
//- Get values of constraints
const scalarField& getConstraintValues() const;

View File

@ -1,7 +1,6 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
set -- -no-recursion "$@" # Parse arguments only
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments -no-recursion "$@"
. ${WM_PROJECT_DIR:?}/wmake/scripts/wmakeFunctions # Require wmake functions
. ${WM_PROJECT_DIR:?}/wmake/scripts/have_scotch

View File

@ -183,6 +183,8 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
while (is.good())
{
// Parsing position within current line
std::string::size_type linei = 0;
is.getLine(line);
if (NASCore::debug > 1) Info<< "Process: " << line << nl;
@ -318,30 +320,16 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
}
}
// Parsing position within current line
std::string::size_type linei = 0;
// Is free format if line contains a comma
const bool freeFormat = line.contains(',');
// First word (column 0-8)
const word cmd(word::validate(nextNasField(line, linei, 8)));
if (cmd == "CTRIA3")
{
// Fixed format:
// 8-16 : element id
// 16-24 : group id
// 24-32 : vertex
// 32-40 : vertex
// 40-48 : vertex
label elemId = readLabel(nextNasField(line, linei, 8, freeFormat));
label groupId = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto a = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto b = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto c = readLabel(nextNasField(line, linei, 8, freeFormat));
label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16
label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48
// Convert groupId into zoneId
const auto iterZone = zoneLookup.cfind(groupId);
@ -370,20 +358,12 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
}
else if (cmd == "CQUAD4")
{
// Fixed format:
// 8-16 : element id
// 16-24 : group id
// 24-32 : vertex
// 32-40 : vertex
// 40-48 : vertex
// 48-56 : vertex
label elemId = readLabel(nextNasField(line, linei, 8, freeFormat));
label groupId = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto a = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto b = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto c = readLabel(nextNasField(line, linei, 8, freeFormat));
const auto d = readLabel(nextNasField(line, linei, 8, freeFormat));
label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16
label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24
const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32
const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40
const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48
const auto d = readLabel(nextNasField(line, linei, 8)); // 48-56
// Convert groupId into zoneId
const auto iterZone = zoneLookup.cfind(groupId);
@ -427,21 +407,11 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
}
else if (cmd == "GRID")
{
// Fixed (short) format:
// 8-16 : point id
// 16-24 : coordinate system (not supported)
// 24-32 : point x coordinate
// 32-40 : point y coordinate
// 40-48 : point z coordinate
// 48-56 : displacement coordinate system (optional, unsupported)
// 56-64 : single point constraints (optional, unsupported)
// 64-70 : super-element id (optional, unsupported)
label index = readLabel(nextNasField(line, linei, 8, freeFormat));
(void) nextNasField(line, linei, 8, freeFormat);
scalar x = readNasScalar(nextNasField(line, linei, 8, freeFormat));
scalar y = readNasScalar(nextNasField(line, linei, 8, freeFormat));
scalar z = readNasScalar(nextNasField(line, linei, 8, freeFormat));
label index = readLabel(nextNasField(line, linei, 8)); // 8-16
(void) nextNasField(line, linei, 8); // 16-24
scalar x = readNasScalar(nextNasField(line, linei, 8)); // 24-32
scalar y = readNasScalar(nextNasField(line, linei, 8)); // 32-40
scalar z = readNasScalar(nextNasField(line, linei, 8)); // 40-48
pointId.push_back(index);
dynPoints.emplace_back(x, y, z);
@ -454,8 +424,6 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
// GRID* 126 0 -5.55999875E+02 -5.68730474E+02
// * 2.14897901E+02
// Cannot be long format and free format at the same time!
label index = readLabel(nextNasField(line, linei, 16)); // 8-24
(void) nextNasField(line, linei, 16); // 24-40
scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56
@ -485,10 +453,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
// have the 'weird' format where the immediately preceeding
// comment contains the information.
// Fixed format:
// 8-16 : pshell id
label groupId = readLabel(nextNasField(line, linei, 8, freeFormat));
label groupId = readLabel(nextNasField(line, linei, 8)); // 8-16
if (lastComment.size() > 1 && !nameLookup.contains(groupId))
{

View File

@ -335,17 +335,30 @@ Foam::surfaceWriters::nastranWriter::nastranWriter
separator_ = ",";
}
// Explicit PLOAD2, PLOAD4 field specification
options.readIfPresent("PLOAD2", pload2_);
options.readIfPresent("PLOAD4", pload4_);
// Compatibility:
// Optional pairs of (field name => load format)
// Could make conditional on (pload2_.empty() && pload4_.empty())
List<Pair<word>> fieldPairs;
options.readEntry("fields", fieldPairs);
options.readIfPresent("fields", fieldPairs);
for (const Pair<word>& item : fieldPairs)
{
// (field name => load format)
fieldMap_.insert
(
item.first(),
fileFormats::NASCore::loadFormatNames[item.second()]
);
const loadFormat format =
fileFormats::NASCore::loadFormatNames[item.second()];
if (format == loadFormat::PLOAD2)
{
pload2_.push_back(item.first());
}
else if (format == loadFormat::PLOAD4)
{
pload4_.push_back(item.first());
}
}
}
@ -406,12 +419,12 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::write()
if (UPstream::master() || !parallel_)
{
if (!isDir(outputFile.path()))
if (!Foam::isDir(outputFile.path()))
{
mkDir(outputFile.path());
Foam::mkDir(outputFile.path());
}
OFstream os(outputFile);
OFstream os(IOstreamOption::ATOMIC, outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
os << "TITLE=OpenFOAM " << outputPath_.name() << " geometry" << nl

View File

@ -39,7 +39,9 @@ Description
fieldLevel | Subtract field level before scaling | no | empty dict
fieldScale | Output field scaling | no | empty dict
commonGeometry | use separate geometry files | no | false
fields | Field pairs for PLOAD2/PLOAD4 | yes |
PLOAD2 | Field selection (words/regex) for PLOAD2 | no |
PLOAD4 | Field selection (words/regex) for PLOAD4 | no |
fields | Compat: Field pairs for PLOAD2/PLOAD4 | no |
\endtable
For example,
@ -56,7 +58,11 @@ Description
"p.*" 0.01; // [Pa] -> [mbar]
}
// OpenFOAM field name to NASTRAN load types
// Specific NASTRAN load types
PLOAD2 ( pMean );
PLOAD4 ( "p.*" );
// old style specification
fields
(
(pMean PLOAD2)
@ -66,6 +72,12 @@ Description
}
\endverbatim
Unless otherwise specified, all fields will be treated as PLOAD2
output. Can optionally specify PLOAD4 output using a combination
of \c PLOAD4 (accept) and \c PLOAD2 (deny) entries. The older \c fields
specification is also accepted and will be transcribed to
corresponding PLOAD4, PLOAD2 entries.
\section Output file locations
The \c rootdir normally corresponds to something like
@ -105,7 +117,7 @@ SourceFiles
#include "surfaceWriter.H"
#include "NASCore.H"
#include "HashTable.H"
#include "wordRes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -138,15 +150,18 @@ private:
//- Field format (width and separator)
fieldFormat writeFormat_;
//- Mapping from field name to data format enumeration
HashTable<loadFormat> fieldMap_;
//- Use common geometry file
bool commonGeometry_;
//- Separator (used for free format)
word separator_;
//- Explicit selection for PLOAD2 output (deselects for PLOAD4)
wordRes pload2_;
//- Explicit selection for PLOAD4 output
wordRes pload4_;
// Private Member Functions

View File

@ -103,13 +103,13 @@ Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue
{
case loadFormat::PLOAD2 :
{
if (pTraits<Type>::nComponents == 1)
if (pTraits<Type>::nComponents > 1)
{
writeValue(os, value);
writeValue(os, Foam::mag(value));
}
else
{
writeValue(os, mag(value));
writeValue(os, value);
}
os << separator_;
@ -121,6 +121,9 @@ Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue
{
writeValue(os, elemId);
// NOTE: these should actually be vertex values,
// but misused here to provide vector quantities!
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
{
os << separator_;
@ -156,43 +159,23 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
checkOpen();
const loadFormat format
(
fieldMap_.lookup
(
fieldName,
// Default format
(
pTraits<Type>::nComponents == 1
? loadFormat::PLOAD2
: loadFormat::PLOAD4
)
)
);
// Default is PLOAD2
loadFormat format = loadFormat::PLOAD2;
if
(
!std::is_integral<Type>::value // Handle 'Ids' etc silently
&& !fieldMap_.empty()
&& !fieldMap_.found(fieldName)
&& !pload4_.empty()
)
{
WarningInFunction
<< "No mapping found between field " << fieldName
<< " and corresponding Nastran field. Available types:"
<< fieldMap_ << nl;
}
const wordRes::filter matcher(pload4_, pload2_);
// Emit any common warnings
if (format == loadFormat::PLOAD2 && pTraits<Type>::nComponents != 1)
{
WarningInFunction
<< fileFormats::NASCore::loadFormatNames[format]
<< " cannot be used for higher rank values"
<< " - reverting to mag()" << endl;
if (matcher(fieldName))
{
format = loadFormat::PLOAD4;
}
}
// Common geometry
// Field: rootdir/<TIME>/<field>_surfaceName.bdf
@ -239,9 +222,9 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
{
const auto& values = tfield();
if (!isDir(outputFile.path()))
if (!Foam::isDir(outputFile.path()))
{
mkDir(outputFile.path());
Foam::mkDir(outputFile.path());
}
const scalar timeValue(0);
@ -251,7 +234,7 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
DynamicList<face> decompFaces;
OFstream os(outputFile);
OFstream os(IOstreamOption::ATOMIC, outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
os << "TITLE=OpenFOAM " << outputFile.name()

View File

@ -65,12 +65,6 @@ Foam::rawTopoChangerFvMesh::rawTopoChangerFvMesh
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::rawTopoChangerFvMesh::~rawTopoChangerFvMesh()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::rawTopoChangerFvMesh::update()
@ -121,30 +115,24 @@ bool Foam::rawTopoChangerFvMesh::update()
}
}
const List<objectMap>& fromFaces = topoChangeMap().facesFromFacesMap();
forAll(fromFaces, i)
for (const auto& map : topoChangeMap().facesFromFacesMap())
{
mappedFace.set(fromFaces[i].index());
mappedFace.set(map.index());
}
const List<objectMap>& fromEdges = topoChangeMap().facesFromEdgesMap();
forAll(fromEdges, i)
for (const auto& map : topoChangeMap().facesFromEdgesMap())
{
mappedFace.set(fromEdges[i].index());
mappedFace.set(map.index());
}
const List<objectMap>& fromPts = topoChangeMap().facesFromPointsMap();
forAll(fromPts, i)
for (const auto& map : topoChangeMap().facesFromPointsMap())
{
mappedFace.set(fromPts[i].index());
mappedFace.set(map.index());
}
// Set unmapped faces to zero
Info<< "rawTopoChangerFvMesh : zeroing unmapped boundary values."
<< endl;
Info<< "rawTopoChangerFvMesh : zeroing unmapped boundary values." << nl;
zeroUnmappedValues<scalar, fvPatchField, volMesh>(mappedFace);
zeroUnmappedValues<vector, fvPatchField, volMesh>(mappedFace);
zeroUnmappedValues<sphericalTensor, fvPatchField, volMesh>(mappedFace);
@ -155,8 +143,8 @@ bool Foam::rawTopoChangerFvMesh::update()
Info<< "rawTopoChangerFvMesh :"
<< " recreating phi for unmapped boundary values." << endl;
const volVectorField& U = lookupObject<volVectorField>("U");
surfaceScalarField& phi = lookupObjectRef<surfaceScalarField>("phi");
const auto& U = lookupObject<volVectorField>("U");
auto& phi = lookupObjectRef<surfaceScalarField>("phi");
setUnmappedValues
(

View File

@ -38,8 +38,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef rawTopoChangerFvMesh_H
#define rawTopoChangerFvMesh_H
#ifndef Foam_rawTopoChangerFvMesh_H
#define Foam_rawTopoChangerFvMesh_H
#include "topoChangerFvMesh.H"
#include "bitSet.H"
@ -49,8 +49,6 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
/*---------------------------------------------------------------------------*\
Class rawTopoChangerFvMesh Declaration
\*---------------------------------------------------------------------------*/
@ -94,8 +92,9 @@ public:
const bool doInit=true
);
//- Destructor
virtual ~rawTopoChangerFvMesh();
virtual ~rawTopoChangerFvMesh() = default;
// Member Functions

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,9 +26,6 @@ License
\*---------------------------------------------------------------------------*/
#include "rawTopoChangerFvMesh.H"
#include "Time.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
@ -42,10 +40,7 @@ void Foam::rawTopoChangerFvMesh::setUnmappedValues
forAll(fld.boundaryField(), patchi)
{
PatchField<Type>& fvp = const_cast<PatchField<Type>&>
(
fld.boundaryField()[patchi]
);
auto& fvp = const_cast<PatchField<Type>&>(fld.boundaryField()[patchi]);
const label start = fvp.patch().start();
forAll(fvp, i)
@ -71,33 +66,27 @@ void Foam::rawTopoChangerFvMesh::zeroUnmappedValues
{
typedef GeometricField<Type, PatchField, GeoMesh> FieldType;
const wordList fldNames(names(FieldType::typeName));
std::unique_ptr<FieldType> zeroFieldPtr;
forAll(fldNames, i)
for (const word& fldName : names<FieldType>())
{
//Pout<< "Checking field " << fldNames[i] << endl;
FieldType& fld = lookupObjectRef<FieldType>(fldName);
//Pout<< "Checking field " << fld.name() << endl;
FieldType& fld = lookupObjectRef<FieldType>(fldNames[i]);
setUnmappedValues
(
fld,
mappedFace,
FieldType
if (!zeroFieldPtr)
{
zeroFieldPtr = std::make_unique<FieldType>
(
IOobject
(
"zero",
time().timeName(),
*this,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
this->newIOobject("zero"),
*this,
dimensioned<Type>(fld.dimensions(), Zero)
)
);
Foam::zero{},
dimless
);
}
zeroFieldPtr->dimensions().reset(fld.dimensions());
setUnmappedValues(fld, mappedFace, *zeroFieldPtr);
}
}

View File

@ -1,7 +1,7 @@
#------------------------------------------------------------------------------
include $(GENERAL_RULES)/Icx/c++
c++ARCH := -pthread -fp-model precise
c++ARCH := -fp-model precise
ifneq (,$(strip $(WM_COMPILE_OPTION)))
sinclude $(DEFAULT_RULES)/c++$(WM_COMPILE_OPTION)