diff --git a/applications/test/speed/vectorSpeed/Test-vectorSpeed.C b/applications/test/speed/vectorSpeed/Test-vectorSpeed.C index 2ab430d34a..0acdc5d84c 100644 --- a/applications/test/speed/vectorSpeed/Test-vectorSpeed.C +++ b/applications/test/speed/vectorSpeed/Test-vectorSpeed.C @@ -1,3 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2023 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 . + +Application + Test-vectorSpeed + +Description + Test speeds, usability of some field operations + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" #include "primitiveFields.H" #include "cpuTime.H" #include "IOstreams.H" @@ -5,12 +40,22 @@ using namespace Foam; -int main() -{ - const label nIter = 100; - const label size = 1000000; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - Info<< "Initialising fields" << endl; +int main(int argc, char *argv[]) +{ + argList::noParallel(); + argList::addBoolOption("lerp"); + + argList args(argc, argv); + + const label nIter = 1000; + const label size = (1000000); + + Info<< "Initialising fields. size:" << size + << " max:" << labelMax << endl; + + scalarField onet(size); vectorField vf1(size, vector::one), @@ -18,11 +63,14 @@ int main() vf3(size, vector::one), vf4(size); - Info<< "Done\n" << endl; + Info<< "Start loop: " << nIter << endl; + cpuTime timing; + + // Timing is mostly malloc anyhow... + + if (!args.found("lerp")) { - cpuTime executionTime; - Info<< "vectorField algebra" << endl; for (int j=0; j, clamp) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + + // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // UNARY_OPERATOR(Type, Type, -, negate, transform) diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H index 537c736624..e444690399 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctions.H @@ -169,6 +169,12 @@ clamp BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clamp) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + + // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // UNARY_OPERATOR(Type, Type, -, negate, transform) diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.C index e8ee293203..c748949715 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.C @@ -694,4 +694,378 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpName, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + DimensionedField& result, \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const DimensionedField& f3 \ +) \ +{ \ + /* TBD: reset dimensions? */ \ + Func(result.field(), f1.field(), f2.field(), f3.field()); \ + result.oriented() = Func(f1.oriented(), f2.oriented()); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const DimensionedField& f3 \ +) \ +{ \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + f1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const DimensionedField& f3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + tf1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const DimensionedField& f3 \ +) \ +{ \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + tf2, \ + #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + tf3, \ + #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf3.clear(); \ + return tres; \ +} \ + \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const DimensionedField& f3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpTmpDimensionedField \ + ::New \ + ( \ + tf1, \ + tf2, \ + #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpTmpDimensionedField \ + ::New \ + ( \ + tf1, \ + tf3, \ + #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f2 = tf2(); \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpTmpDimensionedField \ + ::New \ + ( \ + tf2, \ + tf3, \ + #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f2 = tf2(); \ + const auto& f3 = tf3(); \ + \ + /* TBD: check all three types? */ \ + auto tres = \ + reuseTmpTmpDimensionedField \ + ::New \ + ( \ + tf1, \ + tf2, \ + #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + DimensionedField& result, \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const dimensioned& dt3 \ +) \ +{ \ + /* TBD: reset dimensions? */ \ + Func(result.field(), f1.field(), f2.field(), dt3.value()); \ + result.oriented() = Func(f1.oriented(), f2.oriented()); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const dimensioned& dt3 \ +) \ +{ \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + f1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, dt3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const Type3& s3 \ +) \ +{ \ + return Func(f1, f2, dimensioned(s3)); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const dimensioned& dt3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + tf1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, dt3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const Type3& s3 \ +) \ +{ \ + return Func(tf1, f2, dimensioned(s3)); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +) \ +{ \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpDimensionedField::New \ + ( \ + tf2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, dt3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + return Func(f1, tf2, dimensioned(s3)); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpTmpDimensionedField \ + ::New \ + ( \ + tf1, \ + tf2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Func(tres.ref(), f1, f2, dt3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + return Func(tf1, tf2, dimensioned(s3)); \ +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.H index a3157242f2..7c1d81c6df 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.H +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldFunctionsM.H @@ -326,4 +326,158 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpName, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + DimensionedField& result, \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const DimensionedField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const DimensionedField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const DimensionedField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const DimensionedField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const DimensionedField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + DimensionedField& result, \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const DimensionedField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const DimensionedField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const DimensionedField& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); + + // ************************************************************************* // diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C index dfda7e3602..54a489deac 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.C @@ -634,6 +634,12 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide) BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clamp) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + + /* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */ UNARY_OPERATOR(Type, Type, -, negate) diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H index 9776c63c37..843bf67c58 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctions.H @@ -290,6 +290,11 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide) // Note: works with zero_one through implicit conversion to MinMax BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clamp) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + /* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */ diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.C index d2dc88ce0b..5becaa4753 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.C +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.C @@ -459,4 +459,239 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + FieldField& result, \ + const FieldField& f1, \ + const FieldField& f2, \ + const FieldField& f3 \ +) \ +{ \ + const label loopLen = (result).size(); \ + \ + for (label i = 0; i < loopLen; ++i) \ + { \ + Func(result[i], f1[i], f2[i], f3[i]); \ + } \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const FieldField& f2, \ + const FieldField& f3 \ +) \ +{ \ + auto tres = FieldField::NewCalculatedType(f1); \ + Func(tres.ref(), f1, f2, f3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const FieldField& f2, \ + const FieldField& f3 \ +) \ +{ \ + auto tres = reuseTmpFieldField::New(tf1); \ + Func(tres.ref(), tf1(), f2, f3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const tmp>& tf2, \ + const FieldField& f3 \ +) \ +{ \ + auto tres = reuseTmpFieldField::New(tf2); \ + Func(tres.ref(), f1, tf2(), f3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const FieldField& f2, \ + const tmp>& tf3 \ +) \ +{ \ + auto tres = reuseTmpFieldField::New(tf3); \ + Func(tres.ref(), f1, f2, tf3()); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const FieldField& f3 \ +) \ +{ \ + tmp> tres \ + ( \ + reuseTmpTmpFieldField:: \ + New(tf1, tf2) \ + ); \ + Func(tres.ref(), tf1(), tf2(), f3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const FieldField& f2, \ + const tmp>& tf3 \ +) \ +{ \ + tmp> tres \ + ( \ + reuseTmpTmpFieldField:: \ + New(tf1, tf3) \ + ); \ + Func(tres.ref(), tf1(), f2, tf3()); \ + tf1.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + tmp> tres \ + ( \ + reuseTmpTmpFieldField:: \ + New(tf2, tf3) \ + ); \ + Func(tres.ref(), f1, tf2(), tf3()); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + /* TBD: check all three types? */ \ + tmp> tres \ + ( \ + reuseTmpTmpFieldField:: \ + New(tf1, tf2) \ + ); \ + Func(tres.ref(), tf1(), tf2(), tf3()); \ + tf1.clear(); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + FieldField& result, \ + const FieldField& f1, \ + const FieldField& f2, \ + const Type3& s3 \ +) \ +{ \ + const label loopLen = (result).size(); \ + \ + for (label i = 0; i < loopLen; ++i) \ + { \ + Func(result[i], f1[i], f2[i], s3); \ + } \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const FieldField& f2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = FieldField::NewCalculatedType(f1); \ + Func(tres.ref(), f1, f2, s3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const FieldField& f2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = reuseTmpFieldField::New(tf1); \ + Func(tres.ref(), tf1(), f2, s3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = reuseTmpFieldField::New(tf2); \ + Func(tres.ref(), f1, tf2(), s3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + tmp> tres \ + ( \ + reuseTmpTmpFieldField:: \ + New(tf1, tf2) \ + ); \ + Func(tres.ref(), tf1(), tf2(), s3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.H index 1e3b0501e8..81aac62600 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.H +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldFunctionsM.H @@ -273,4 +273,126 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + FieldField& result, \ + const FieldField& f1, \ + const FieldField& f2, \ + const FieldField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const FieldField& f2, \ + const FieldField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const FieldField& f2, \ + const FieldField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const tmp>& tf2, \ + const FieldField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const FieldField& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const FieldField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const FieldField& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + FieldField& result, \ + const FieldField& f1, \ + const FieldField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const FieldField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const FieldField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const FieldField& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); + + // ************************************************************************* // diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C index 4a4e8d1177..583c443971 100644 --- a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C +++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.C @@ -741,6 +741,11 @@ BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide) BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clip) // Same as clamp +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + /* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */ diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H index 9307b9d155..6ed4076872 100644 --- a/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H +++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctions.H @@ -317,6 +317,11 @@ BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clamp) BINARY_TYPE_FUNCTION_FS(Type, Type, Foam::zero_one, clamp) BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clip) // Same as clamp +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.C b/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.C index e82f2e6345..39829843ab 100644 --- a/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.C +++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.C @@ -438,4 +438,215 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + Field& result, \ + const UList& f1, \ + const UList& f2, \ + const UList& f3 \ +) \ +{ \ + TFOR_ALL_F_OP_FUNC_F_F_F \ + ( \ + ReturnType, result, =, ::Foam::Func, Type1, f1, Type2, f2, Type3, f3 \ + ) \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const UList& f2, \ + const UList& f3 \ +) \ +{ \ + auto tres = tmp>::New(f1.size()); \ + Func(tres.ref(), f1, f2, f3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const UList& f2, \ + const UList& f3 \ +) \ +{ \ + auto tres = reuseTmp::New(tf1); \ + Func(tres.ref(), tf1(), f2, f3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const tmp>& tf2, \ + const UList& f3 \ +) \ +{ \ + auto tres = reuseTmp::New(tf2); \ + Func(tres.ref(), f1, tf2(), f3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const UList& f2, \ + const tmp>& tf3 \ +) \ +{ \ + auto tres = reuseTmp::New(tf3); \ + Func(tres.ref(), f1, f2, tf3()); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const UList& f3 \ +) \ +{ \ + auto tres = reuseTmpTmp::New(tf1, tf2); \ + Func(tres.ref(), tf1(), tf2(), f3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const UList& f2, \ + const tmp>& tf3 \ +) \ +{ \ + auto tres = reuseTmpTmp::New(tf1, tf3); \ + Func(tres.ref(), tf1(), f2, tf3()); \ + tf1.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + auto tres = reuseTmpTmp::New(tf2, tf3); \ + Func(tres.ref(), f1, tf2(), tf3()); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + /* TBD: check all three types? */ \ + auto tres = reuseTmpTmp::New(tf1, tf2); \ + Func(tres.ref(), tf1(), tf2(), tf3()); \ + tf1.clear(); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + Field& result, \ + const UList& f1, \ + const UList& f2, \ + const Type3& s3 \ +) \ +{ \ + TFOR_ALL_F_OP_FUNC_F_F_S \ + ( \ + ReturnType, result, =, ::Foam::Func, Type1, f1, Type2, f2, Type3, s3 \ + ) \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const UList& f2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = tmp>::New(f1.size()); \ + Func(tres.ref(), f1, f2, s3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const UList& f2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = reuseTmp::New(tf1); \ + Func(tres.ref(), tf1(), f2, s3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = reuseTmp::New(tf2); \ + Func(tres.ref(), f1, tf2(), s3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + auto tres = reuseTmpTmp::New(tf1, tf2); \ + Func(tres.ref(), tf1(), tf2(), s3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.H b/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.H index 1730ad22ba..e8fcb52c5e 100644 --- a/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.H +++ b/src/OpenFOAM/fields/Fields/Field/FieldFunctionsM.H @@ -270,4 +270,136 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + Field& result, \ + const UList& f1, \ + const UList& f2, \ + const UList& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const UList& f2, \ + const UList& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const UList& f2, \ + const UList& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const tmp>& tf2, \ + const UList& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const UList& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const UList& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const UList& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Permutations of ternary functions taking non-field argument(s) +// +// FFS (defined) +// FSF (not defined) +// SFF (not defined) +// SSF (not defined) +// SFS (not defined) +// FSS (not defined) + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + Field& result, \ + const UList& f1, \ + const UList& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const UList& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const UList& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const UList& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); + + // ************************************************************************* // diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C index a62fd98b54..18d2b0cdeb 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.C @@ -548,6 +548,12 @@ clamp BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clamp) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + + // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // UNARY_OPERATOR(Type, Type, -, negate, transform) diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H index 937a07e443..65863a90c0 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctions.H @@ -304,6 +304,12 @@ clamp BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax, clamp) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +TERNARY_FUNCTION(Type, Type, Type, scalar, lerp) +TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp) + + // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // UNARY_OPERATOR(Type, Type, -, negate, transform) diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.C index 97b916586a..d8e5ec5b92 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.C @@ -732,6 +732,407 @@ tmp> operator Op \ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + GeometricField& result, \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const GeometricField& f3 \ +) \ +{ \ + Foam::Func \ + ( \ + result.primitiveFieldRef(), \ + f1.primitiveField(), \ + f2.primitiveField(), \ + f3.primitiveField() \ + ); \ + Foam::Func \ + ( \ + result.boundaryFieldRef(), \ + f1.boundaryField(), \ + f2.boundaryField(), \ + f3.boundaryField() \ + ); \ + result.oriented() = Func(f1.oriented(), f2.oriented()); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const GeometricField& f3 \ +) \ +{ \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + f1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const GeometricField& f3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + f1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const GeometricField& f3 \ +) \ +{ \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + f2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + f3, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const GeometricField& f3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpTmpGeometricField \ + \ + ::New \ + ( \ + tf1, \ + tf2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpTmpGeometricField \ + \ + ::New \ + ( \ + tf1, \ + tf3, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f2 = tf2(); \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpTmpGeometricField \ + \ + ::New \ + ( \ + tf2, \ + tf3, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f2 = tf2(); \ + const auto& f3 = tf3(); \ + \ + auto tres = \ + reuseTmpTmpGeometricField \ + \ + ::New \ + ( \ + tf1, \ + tf2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, f3); \ + tf1.clear(); \ + tf2.clear(); \ + tf3.clear(); \ + return tres; \ +} + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + GeometricField& result, \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const dimensioned& dt3 \ +) \ +{ \ + Foam::Func \ + ( \ + result.primitiveFieldRef(), \ + f1.primitiveField(), \ + f2.primitiveField(), \ + dt3.value() \ + ); \ + Foam::Func \ + ( \ + result.boundaryFieldRef(), \ + f1.boundaryField(), \ + f2.boundaryField(), \ + dt3.value() \ + ); \ + result.oriented() = Func(f1.oriented(), f2.oriented()); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const dimensioned& dt3 \ +) \ +{ \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + f1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, dt3.value()); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const Type3& s3 \ +) \ +{ \ + return Foam::Func(f1, f2, dimensioned(s3)); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const dimensioned& dt3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + f1, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, dt3.value()); \ + tf1.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const Type3& s3 \ +) \ +{ \ + return Foam::Func(tf1, f2, dimensioned(s3)); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +) \ +{ \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpGeometricField::New \ + ( \ + tf2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, dt3.value()); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + return Foam::Func(f1, tf2, dimensioned(s3)); \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +) \ +{ \ + const auto& f1 = tf1(); \ + const auto& f2 = tf2(); \ + \ + auto tres = \ + reuseTmpTmpGeometricField \ + \ + ::New \ + ( \ + tf1, \ + tf2, \ + #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \ + Func(f1.dimensions(), f2.dimensions()) \ + ); \ + \ + Foam::Func(tres.ref(), f1, f2, dt3.value()); \ + tf1.clear(); \ + tf2.clear(); \ + return tres; \ +} \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +) \ +{ \ + return Foam::Func(tf1, tf2, dimensioned(s3)); \ +} + + +// ************************************************************************* // + } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.H index 0af9f5159d..259e1cbea0 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.H +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldFunctionsM.H @@ -326,4 +326,158 @@ tmp> operator Op \ BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpName, OpFunc) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + GeometricField& result, \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const GeometricField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const GeometricField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const GeometricField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const GeometricField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const GeometricField& f3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const tmp>& tf3 \ +); + + +#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \ + \ +TEMPLATE \ +void Func \ +( \ + GeometricField& result, \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const GeometricField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const GeometricField& f2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const GeometricField& f1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const dimensioned& dt3 \ +); \ + \ +TEMPLATE \ +tmp> Func \ +( \ + const tmp>& tf1, \ + const tmp>& tf2, \ + const Type3& s3 \ +); + + // ************************************************************************* //