/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2019-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 . \*---------------------------------------------------------------------------*/ #include "PstreamReduceOps.H" #include "FieldFieldReuseFunctions.H" #define TEMPLATE template class Field, class Type> #include "FieldFieldFunctionsM.C" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ template class Field, class Type> void component ( FieldField::cmptType>& sf, const FieldField& f, const direction d ) { const label loopLen = (sf).size(); for (label i = 0; i < loopLen; ++i) { component(sf[i], f[i], d); } } template class Field, class Type> void T(FieldField& f1, const FieldField& f2) { const label loopLen = (f1).size(); for (label i = 0; i < loopLen; ++i) { T(f1[i], f2[i]); } } template class Field, class Type, direction r> void pow ( FieldField::type>& f, const FieldField& vf ) { const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { pow(f[i], vf[i]); } } template class Field, class Type, direction r> tmp::type>> pow ( const FieldField& f, typename powProduct::type ) { typedef typename powProduct::type resultType; auto tres = FieldField::NewCalculatedType(f); pow(tres.ref(), f); return tres; } template class Field, class Type, direction r> tmp::type>> pow ( const tmp>& tf, typename powProduct::type ) { typedef typename powProduct::type resultType; auto tres = reuseTmpFieldField::New(tf); pow(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void sqr ( FieldField::type>& f, const FieldField& vf ) { const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { sqr(f[i], vf[i]); } } template class Field, class Type> tmp::type>> sqr(const FieldField& f) { typedef typename outerProduct::type resultType; auto tres = FieldField::NewCalculatedType(f); sqr(tres.ref(), f); return tres; } template class Field, class Type> tmp::type>> sqr(const tmp>& tf) { typedef typename outerProduct::type resultType; auto tres = reuseTmpFieldField::New(tf); sqr(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void magSqr ( FieldField::type>& sf, const FieldField& f ) { const label loopLen = (sf).size(); for (label i = 0; i < loopLen; ++i) { magSqr(sf[i], f[i]); } } template class Field, class Type> tmp::type>> magSqr(const FieldField& f) { typedef typename typeOfMag::type resultType; auto tres = FieldField::NewCalculatedType(f); magSqr(tres.ref(), f); return tres; } template class Field, class Type> tmp::type>> magSqr(const tmp>& tf) { typedef typename typeOfMag::type resultType; auto tres = reuseTmpFieldField::New(tf); magSqr(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void mag ( FieldField::type>& sf, const FieldField& f ) { const label loopLen = (sf).size(); for (label i = 0; i < loopLen; ++i) { mag(sf[i], f[i]); } } template class Field, class Type> tmp::type>> mag(const FieldField& f) { typedef typename typeOfMag::type resultType; auto tres = FieldField::NewCalculatedType(f); mag(tres.ref(), f); return tres; } template class Field, class Type> tmp::type>> mag(const tmp>& tf) { typedef typename typeOfMag::type resultType; auto tres = reuseTmpFieldField::New(tf); mag(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void cmptMax ( FieldField::cmptType>& cf, const FieldField& f ) { const label loopLen = (cf).size(); for (label i = 0; i < loopLen; ++i) { cmptMax(cf[i], f[i]); } } template class Field, class Type> tmp::cmptType>> cmptMax ( const FieldField& f ) { typedef typename FieldField::cmptType resultType; auto tres = FieldField::NewCalculatedType(f); cmptMax(tres.ref(), f); return tres; } template class Field, class Type> tmp::cmptType>> cmptMax ( const tmp>& tf ) { typedef typename FieldField::cmptType resultType; auto tres = reuseTmpFieldField::New(tf); cmptMax(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void cmptMin ( FieldField::cmptType>& cf, const FieldField& f ) { const label loopLen = (cf).size(); for (label i = 0; i < loopLen; ++i) { cmptMin(cf[i], f[i]); } } template class Field, class Type> tmp::cmptType>> cmptMin ( const FieldField& f ) { typedef typename FieldField::cmptType resultType; auto tres = FieldField::NewCalculatedType(f); cmptMin(tres.ref(), f); return tres; } template class Field, class Type> tmp::cmptType>> cmptMin ( const tmp>& tf ) { typedef typename FieldField::cmptType resultType; auto tres = reuseTmpFieldField::New(tf); cmptMin(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void cmptAv ( FieldField::cmptType>& cf, const FieldField& f ) { const label loopLen = (cf).size(); for (label i = 0; i < loopLen; ++i) { cmptAv(cf[i], f[i]); } } template class Field, class Type> tmp::cmptType>> cmptAv ( const FieldField& f ) { typedef typename FieldField::cmptType resultType; auto tres = FieldField::NewCalculatedType(f); cmptAv(tres.ref(), f); return tres; } template class Field, class Type> tmp::cmptType>> cmptAv ( const tmp>& tf ) { typedef typename FieldField::cmptType resultType; auto tres = reuseTmpFieldField::New(tf); cmptAv(tres.ref(), tf()); tf.clear(); return tres; } template class Field, class Type> void cmptMag ( FieldField& cf, const FieldField& f ) { const label loopLen = (cf).size(); for (label i = 0; i < loopLen; ++i) { cmptMag(cf[i], f[i]); } } template class Field, class Type> tmp> cmptMag ( const FieldField& f ) { auto tres = FieldField::NewCalculatedType(f); cmptMag(tres.ref(), f); return tres; } template class Field, class Type> tmp> cmptMag ( const tmp>& tf ) { tmp> tres(New(tf)); cmptMag(tres.ref(), tf()); tf.clear(); return tres; } #define TMP_UNARY_FUNCTION(ReturnType, Func) \ \ template class Field, class Type> \ ReturnType Func(const tmp>& tf1) \ { \ ReturnType res = Func(tf1()); \ tf1.clear(); \ return res; \ } template class Field, class Type> Type max(const FieldField& f) { Type result = pTraits::min; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { if (f[i].size()) { result = max(max(f[i]), result); } } return result; } TMP_UNARY_FUNCTION(Type, max) template class Field, class Type> Type min(const FieldField& f) { Type result = pTraits::max; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { if (f[i].size()) { result = min(min(f[i]), result); } } return result; } TMP_UNARY_FUNCTION(Type, min) template class Field, class Type> Type sum(const FieldField& f) { Type result = Zero; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { result += sum(f[i]); } return result; } TMP_UNARY_FUNCTION(Type, sum) template class Field, class Type> typename typeOfMag::type sumMag(const FieldField& f) { typedef typename typeOfMag::type resultType; resultType result = Zero; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { result += sumMag(f[i]); } return result; } TMP_UNARY_FUNCTION(typename typeOfMag::type, sumMag) template class Field, class Type> Type average(const FieldField& f) { label n = 0; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { n += f[i].size(); } if (n) { Type avrg = sum(f)/n; return avrg; } WarningInFunction << "empty fieldField, returning zero" << endl; return Zero; } TMP_UNARY_FUNCTION(Type, average) template class Field, class Type> MinMax minMax(const FieldField& f) { MinMax result; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { result += minMax(f[i]); } return result; } TMP_UNARY_FUNCTION(MinMax, minMax) template class Field, class Type> scalarMinMax minMaxMag(const FieldField& f) { scalarMinMax result; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { result += minMaxMag(f[i]); } return result; } TMP_UNARY_FUNCTION(scalarMinMax, minMaxMag) // With reduction on ReturnType #define G_UNARY_FUNCTION(ReturnType, gFunc, Func, rFunc) \ \ template class Field, class Type> \ ReturnType gFunc(const FieldField& f) \ { \ ReturnType res = Func(f); \ reduce(res, rFunc##Op()); \ return res; \ } \ TMP_UNARY_FUNCTION(ReturnType, gFunc) G_UNARY_FUNCTION(Type, gMax, max, max) G_UNARY_FUNCTION(Type, gMin, min, min) G_UNARY_FUNCTION(Type, gSum, sum, sum) G_UNARY_FUNCTION(MinMax, gMinMax, minMax, sum) G_UNARY_FUNCTION(scalarMinMax, gMinMaxMag, minMaxMag, sum) G_UNARY_FUNCTION(typename typeOfMag::type, gSumMag, sumMag, sum) #undef G_UNARY_FUNCTION template class Field, class Type> Type gAverage(const FieldField& f) { label n = 0; const label loopLen = (f).size(); for (label i = 0; i < loopLen; ++i) { n += f[i].size(); } reduce(n, sumOp