FieldFieldFunctions.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019-2025 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "PstreamReduceOps.H"
31 
32 #define TEMPLATE template<template<class> class Field, class Type>
33 #include "FieldFieldFunctionsM.C"
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 /* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */
41 
42 template<template<class> class Field, class Type>
43 void component
44 (
47  const direction d
48 )
49 {
50  const label loopLen = (sf).size();
51 
52  for (label i = 0; i < loopLen; ++i)
53  {
54  component(sf[i], f[i], d);
55  }
56 }
57 
58 
59 template<template<class> class Field, class Type>
60 void T(FieldField<Field, Type>& f1, const FieldField<Field, Type>& f2)
61 {
62  const label loopLen = (f1).size();
63 
64  for (label i = 0; i < loopLen; ++i)
65  {
66  T(f1[i], f2[i]);
67  }
68 }
69 
70 
71 template<template<class> class Field, class Type, direction r>
72 void pow
73 (
74  FieldField<Field, typename powProduct<Type, r>::type>& f,
75  const FieldField<Field, Type>& vf
76 )
77 {
78  const label loopLen = (f).size();
79 
80  for (label i = 0; i < loopLen; ++i)
81  {
82  pow(f[i], vf[i]);
83  }
84 }
85 
86 template<template<class> class Field, class Type, direction r>
88 pow
89 (
90  const FieldField<Field, Type>& f, typename powProduct<Type, r>::type
91 )
92 {
93  typedef typename powProduct<Type, r>::type resultType;
94 
96 
97  pow<Type, r>(tres.ref(), f);
98  return tres;
99 }
100 
101 template<template<class> class Field, class Type, direction r>
103 pow
104 (
105  const tmp<FieldField<Field, Type>>& tf, typename powProduct<Type, r>::type
106 )
107 {
108  typedef typename powProduct<Type, r>::type resultType;
109 
111 
112  pow<Type, r>(tres.ref(), tf());
113  tf.clear();
114  return tres;
115 }
116 
117 
118 template<template<class> class Field, class Type>
119 void sqr
120 (
121  FieldField<Field, typename outerProduct<Type, Type>::type>& f,
122  const FieldField<Field, Type>& vf
123 )
124 {
125  const label loopLen = (f).size();
126 
127  for (label i = 0; i < loopLen; ++i)
128  {
129  sqr(f[i], vf[i]);
130  }
131 }
132 
133 template<template<class> class Field, class Type>
135 sqr(const FieldField<Field, Type>& f)
136 {
137  typedef typename outerProduct<Type, Type>::type resultType;
138 
141  sqr(tres.ref(), f);
142  return tres;
143 }
144 
145 template<template<class> class Field, class Type>
147 sqr(const tmp<FieldField<Field, Type>>& tf)
148 {
149  typedef typename outerProduct<Type, Type>::type resultType;
150 
152 
153  sqr(tres.ref(), tf());
154  tf.clear();
155  return tres;
156 }
157 
158 
159 template<template<class> class Field, class Type>
160 void magSqr
161 (
162  FieldField<Field, typename typeOfMag<Type>::type>& sf,
163  const FieldField<Field, Type>& f
164 )
165 {
166  const label loopLen = (sf).size();
167 
168  for (label i = 0; i < loopLen; ++i)
169  {
170  magSqr(sf[i], f[i]);
171  }
172 }
173 
174 template<template<class> class Field, class Type>
176 magSqr(const FieldField<Field, Type>& f)
177 {
178  typedef typename typeOfMag<Type>::type resultType;
179 
182  magSqr(tres.ref(), f);
183  return tres;
184 }
185 
186 template<template<class> class Field, class Type>
188 magSqr(const tmp<FieldField<Field, Type>>& tf)
189 {
190  typedef typename typeOfMag<Type>::type resultType;
191 
193 
194  magSqr(tres.ref(), tf());
195  tf.clear();
196  return tres;
197 }
198 
199 
200 template<template<class> class Field, class Type>
201 void mag
202 (
203  FieldField<Field, typename typeOfMag<Type>::type>& sf,
204  const FieldField<Field, Type>& f
205 )
206 {
207  const label loopLen = (sf).size();
208 
209  for (label i = 0; i < loopLen; ++i)
210  {
211  mag(sf[i], f[i]);
212  }
213 }
214 
215 template<template<class> class Field, class Type>
217 mag(const FieldField<Field, Type>& f)
218 {
219  typedef typename typeOfMag<Type>::type resultType;
220 
223  mag(tres.ref(), f);
224  return tres;
225 }
226 
227 template<template<class> class Field, class Type>
229 mag(const tmp<FieldField<Field, Type>>& tf)
230 {
231  typedef typename typeOfMag<Type>::type resultType;
232 
234 
235  mag(tres.ref(), tf());
236  tf.clear();
237  return tres;
238 }
239 
240 
241 template<template<class> class Field, class Type>
242 void cmptMax
243 (
244  FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
245  const FieldField<Field, Type>& f
246 )
247 {
248  const label loopLen = (cf).size();
249 
250  for (label i = 0; i < loopLen; ++i)
251  {
252  cmptMax(cf[i], f[i]);
253  }
254 }
255 
256 template<template<class> class Field, class Type>
257 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> cmptMax
258 (
259  const FieldField<Field, Type>& f
260 )
261 {
262  typedef typename FieldField<Field, Type>::cmptType resultType;
263 
266  cmptMax(tres.ref(), f);
267  return tres;
268 }
269 
270 template<template<class> class Field, class Type>
271 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> cmptMax
272 (
273  const tmp<FieldField<Field, Type>>& tf
274 )
275 {
276  typedef typename FieldField<Field, Type>::cmptType resultType;
277 
279 
280  cmptMax(tres.ref(), tf());
281  tf.clear();
282  return tres;
283 }
284 
285 
286 template<template<class> class Field, class Type>
287 void cmptMin
288 (
289  FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
290  const FieldField<Field, Type>& f
291 )
292 {
293  const label loopLen = (cf).size();
294 
295  for (label i = 0; i < loopLen; ++i)
296  {
297  cmptMin(cf[i], f[i]);
298  }
299 }
300 
301 template<template<class> class Field, class Type>
302 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> cmptMin
303 (
304  const FieldField<Field, Type>& f
305 )
306 {
307  typedef typename FieldField<Field, Type>::cmptType resultType;
308 
311  cmptMin(tres.ref(), f);
312  return tres;
313 }
314 
315 template<template<class> class Field, class Type>
316 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> cmptMin
317 (
318  const tmp<FieldField<Field, Type>>& tf
319 )
320 {
321  typedef typename FieldField<Field, Type>::cmptType resultType;
322 
324 
325  cmptMin(tres.ref(), tf());
326  tf.clear();
327  return tres;
328 }
329 
330 
331 template<template<class> class Field, class Type>
332 void cmptAv
333 (
334  FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
335  const FieldField<Field, Type>& f
336 )
337 {
338  const label loopLen = (cf).size();
339 
340  for (label i = 0; i < loopLen; ++i)
341  {
342  cmptAv(cf[i], f[i]);
343  }
344 }
345 
346 template<template<class> class Field, class Type>
347 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> cmptAv
348 (
349  const FieldField<Field, Type>& f
350 )
351 {
352  typedef typename FieldField<Field, Type>::cmptType resultType;
353 
356  cmptAv(tres.ref(), f);
357  return tres;
358 }
359 
360 template<template<class> class Field, class Type>
361 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>> cmptAv
362 (
363  const tmp<FieldField<Field, Type>>& tf
364 )
365 {
366  typedef typename FieldField<Field, Type>::cmptType resultType;
367 
369 
370  cmptAv(tres.ref(), tf());
371  tf.clear();
372  return tres;
373 }
374 
375 
376 template<template<class> class Field, class Type>
377 void cmptMag
378 (
379  FieldField<Field, Type>& cf,
380  const FieldField<Field, Type>& f
381 )
382 {
383  const label loopLen = (cf).size();
384 
385  for (label i = 0; i < loopLen; ++i)
386  {
387  cmptMag(cf[i], f[i]);
388  }
389 }
390 
391 template<template<class> class Field, class Type>
392 tmp<FieldField<Field, Type>> cmptMag
393 (
394  const FieldField<Field, Type>& f
395 )
396 {
399  cmptMag(tres.ref(), f);
400  return tres;
401 }
402 
403 template<template<class> class Field, class Type>
404 tmp<FieldField<Field, Type>> cmptMag
405 (
406  const tmp<FieldField<Field, Type>>& tf
407 )
408 {
409  tmp<FieldField<Field, Type>> tres(New(tf));
410  cmptMag(tres.ref(), tf());
411  tf.clear();
412  return tres;
413 }
414 
415 
416 #define TMP_UNARY_FUNCTION(ReturnType, Func) \
417  \
418 template<template<class> class Field, class Type> \
419 ReturnType Func(const tmp<FieldField<Field, Type>>& tf1) \
420 { \
421  ReturnType res = Func(tf1()); \
422  tf1.clear(); \
423  return res; \
424 }
425 
426 template<template<class> class Field, class Type>
427 Type max(const FieldField<Field, Type>& f)
428 {
429  Type result = pTraits<Type>::min;
430 
431  const label loopLen = (f).size();
432 
433  for (label i = 0; i < loopLen; ++i)
434  {
435  if (f[i].size())
436  {
437  result = max(max(f[i]), result);
438  }
439 
440  }
441 
442  return result;
443 }
444 
445 TMP_UNARY_FUNCTION(Type, max)
446 
447 
448 template<template<class> class Field, class Type>
449 Type min(const FieldField<Field, Type>& f)
450 {
451  Type result = pTraits<Type>::max;
452 
453  const label loopLen = (f).size();
454 
455  for (label i = 0; i < loopLen; ++i)
456  {
457  if (f[i].size())
458  {
459  result = min(min(f[i]), result);
460  }
461  }
462 
463  return result;
464 }
465 
466 TMP_UNARY_FUNCTION(Type, min)
467 
468 
469 template<template<class> class Field, class Type>
470 Type sum(const FieldField<Field, Type>& f)
471 {
472  Type result = Zero;
473 
474  const label loopLen = (f).size();
475 
476  for (label i = 0; i < loopLen; ++i)
477  {
478  result += sum(f[i]);
479  }
481  return result;
482 }
483 
484 TMP_UNARY_FUNCTION(Type, sum)
485 
486 template<template<class> class Field, class Type>
487 typename typeOfMag<Type>::type sumMag(const FieldField<Field, Type>& f)
488 {
489  typedef typename typeOfMag<Type>::type resultType;
490 
491  resultType result = Zero;
492 
493  const label loopLen = (f).size();
494 
495  for (label i = 0; i < loopLen; ++i)
496  {
497  result += sumMag(f[i]);
498  }
500  return result;
501 }
502 
504 
505 template<template<class> class Field, class Type>
506 Type average(const FieldField<Field, Type>& f)
507 {
508  label count(0);
509  Type result = Zero;
510 
511  const label loopLen = (f).size();
512 
513  for (label i = 0; i < loopLen; ++i)
514  {
515  const label n = f[i].size();
516  if (n)
517  {
518  count += n;
519  result += sum(f[i]);
520  }
521  }
522 
523  if (count > 0)
524  {
525  return result/count;
526  }
529  << "empty fieldField, returning zero" << endl;
530 
531  return Zero;
532 }
533 
535 
536 
537 template<template<class> class Field, class Type>
538 MinMax<Type> minMax(const FieldField<Field, Type>& f)
539 {
540  MinMax<Type> result;
541 
542  const label loopLen = (f).size();
543 
544  for (label i = 0; i < loopLen; ++i)
545  {
546  result += minMax(f[i]);
547  }
549  return result;
550 }
551 
552 TMP_UNARY_FUNCTION(MinMax<Type>, minMax)
553 
554 template<template<class> class Field, class Type>
555 scalarMinMax minMaxMag(const FieldField<Field, Type>& f)
556 {
557  scalarMinMax result;
558 
559  const label loopLen = (f).size();
560 
561  for (label i = 0; i < loopLen; ++i)
562  {
563  result += minMaxMag(f[i]);
564  }
565 
566  return result;
567 }
568 
570 
571 
572 // With reduction on ReturnType
573 #define G_UNARY_FUNCTION(ReturnType, gFunc, Func, rFunc) \
574  \
575 template<template<class> class Field, class Type> \
576 ReturnType gFunc(const FieldField<Field, Type>& f) \
577 { \
578  ReturnType res = Func(f); \
579  reduce(res, rFunc##Op<ReturnType>()); \
580  return res; \
581 } \
582 TMP_UNARY_FUNCTION(ReturnType, gFunc)
584 G_UNARY_FUNCTION(Type, gMax, max, max)
585 G_UNARY_FUNCTION(Type, gMin, min, min)
586 G_UNARY_FUNCTION(Type, gSum, sum, sum)
589 
591 
592 #undef G_UNARY_FUNCTION
593 
594 
595 template<template<class> class Field, class Type>
596 Type gAverage
597 (
598  const FieldField<Field, Type>& f,
599  const label comm
600 )
601 {
602  label count(0);
603  Type result = Zero;
604 
605  const label loopLen = (f).size();
606 
607  for (label i = 0; i < loopLen; ++i)
608  {
609  const label n = f[i].size();
610  if (n)
611  {
612  count += n;
613  result += sum(f[i]);
614  }
615  }
616 
617  // Communicator is not disabled
618  if (comm >= 0)
619  {
620  Foam::sumReduce(result, count, UPstream::msgType(), comm);
621  }
622 
623  if (count > 0)
624  {
625  return result/count;
626  }
629  << "Empty FieldField, returning zero" << endl;
630 
631  return Zero;
632 }
633 
635 
636 #undef TMP_UNARY_FUNCTION
637 
638 
639 BINARY_FUNCTION(Type, Type, Type, max)
640 BINARY_FUNCTION(Type, Type, Type, min)
641 BINARY_FUNCTION(Type, Type, Type, cmptMultiply)
642 BINARY_FUNCTION(Type, Type, Type, cmptDivide)
643 
644 BINARY_TYPE_FUNCTION(Type, Type, Type, max)
645 BINARY_TYPE_FUNCTION(Type, Type, Type, min)
646 BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
647 BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
648 
649 // Note: works with zero_one through implicit conversion to MinMax
650 BINARY_TYPE_FUNCTION_FS(Type, Type, MinMax<Type>, clamp)
651 
652 
653 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
654 
655 TERNARY_FUNCTION(Type, Type, Type, scalar, lerp)
656 TERNARY_TYPE_FUNCTION_FFS(Type, Type, Type, scalar, lerp)
657 
658 
659 /* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */
660 
661 UNARY_OPERATOR(Type, Type, -, negate)
662 
663 BINARY_OPERATOR(Type, Type, scalar, *, multiply)
664 BINARY_OPERATOR(Type, scalar, Type, *, multiply)
665 BINARY_OPERATOR(Type, Type, scalar, /, divide)
666 
667 BINARY_TYPE_OPERATOR_SF(Type, scalar, Type, *, multiply)
668 BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, *, multiply)
669 
670 BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, /, divide)
671 
672 
673 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
674 
675 #define PRODUCT_OPERATOR(product, Op, OpFunc) \
676  \
677 template \
678 < \
679  template<class> class Field1, \
680  template<class> class Field2, \
681  class Type1, \
682  class Type2 \
683 > \
684 void OpFunc \
685 ( \
686  FieldField<Field1, typename product<Type1, Type2>::type>& f, \
687  const FieldField<Field1, Type1>& f1, \
688  const FieldField<Field2, Type2>& f2 \
689 ) \
690 { \
691  const label loopLen = (f).size(); \
692  \
693  for (label i = 0; i < loopLen; ++i) \
694  { \
695  OpFunc(f[i], f1[i], f2[i]); \
696  } \
697 } \
698  \
699 template \
700 < \
701  template<class> class Field1, \
702  template<class> class Field2, \
703  class Type1, \
704  class Type2 \
705 > \
706 tmp<FieldField<Field1, typename product<Type1, Type2>::type>> \
707 operator Op \
708 ( \
709  const FieldField<Field1, Type1>& f1, \
710  const FieldField<Field2, Type2>& f2 \
711 ) \
712 { \
713  typedef typename product<Type1, Type2>::type resultType; \
714  auto tres = FieldField<Field1, resultType>::NewCalculatedType(f1); \
715  OpFunc(tres.ref(), f1, f2); \
716  return tres; \
717 } \
718  \
719 template<template<class> class Field, class Type1, class Type2> \
720 tmp<FieldField<Field, typename product<Type1, Type2>::type>> \
721 operator Op \
722 ( \
723  const FieldField<Field, Type1>& f1, \
724  const tmp<FieldField<Field, Type2>>& tf2 \
725 ) \
726 { \
727  typedef typename product<Type1, Type2>::type resultType; \
728  auto tres = reuseTmpFieldField<Field, resultType, Type2>::New(tf2); \
729  OpFunc(tres.ref(), f1, tf2()); \
730  tf2.clear(); \
731  return tres; \
732 } \
733  \
734 template \
735 < \
736  template<class> class Field1, \
737  template<class> class Field2, \
738  class Type1, \
739  class Type2 \
740 > \
741 tmp<FieldField<Field, typename product<Type1, Type2>::type>> \
742 operator Op \
743 ( \
744  const FieldField<Field1, Type1>& f1, \
745  const tmp<FieldField<Field2, Type2>>& tf2 \
746 ) \
747 { \
748  typedef typename product<Type1, Type2>::type resultType; \
749  auto tres = FieldField<Field1, resultType>::NewCalculatedType(f1); \
750  OpFunc(tres.ref(), f1, tf2()); \
751  tf2.clear(); \
752  return tres; \
753 } \
754  \
755 template \
756 < \
757  template<class> class Field1, \
758  template<class> class Field2, \
759  class Type1, \
760  class Type2 \
761 > \
762 tmp<FieldField<Field1, typename product<Type1, Type2>::type>> \
763 operator Op \
764 ( \
765  const tmp<FieldField<Field1, Type1>>& tf1, \
766  const FieldField<Field2, Type2>& f2 \
767 ) \
768 { \
769  typedef typename product<Type1, Type2>::type resultType; \
770  auto tres = reuseTmpFieldField<Field1, resultType, Type1>::New(tf1); \
771  OpFunc(tres.ref(), tf1(), f2); \
772  tf1.clear(); \
773  return tres; \
774 } \
775  \
776 template \
777 < \
778  template<class> class Field1, \
779  template<class> class Field2, \
780  class Type1, \
781  class Type2 \
782 > \
783 tmp<FieldField<Field1, typename product<Type1, Type2>::type>> \
784 operator Op \
785 ( \
786  const tmp<FieldField<Field1, Type1>>& tf1, \
787  const tmp<FieldField<Field2, Type2>>& tf2 \
788 ) \
789 { \
790  typedef typename product<Type1, Type2>::type resultType; \
791  auto tres \
792  ( \
793  reuseTmpTmpFieldField<Field1, resultType, Type1, Type1, Type2>::New \
794  (tf1, tf2) \
795  ); \
796  OpFunc(tres.ref(), tf1(), tf2()); \
797  tf1.clear(); \
798  tf2.clear(); \
799  return tres; \
800 } \
801  \
802 template \
803 < \
804  template<class> class Field, \
805  class Type, \
806  class Form, \
807  class Cmpt, \
808  direction nCmpt \
809 > \
810 void OpFunc \
811 ( \
812  FieldField<Field, typename product<Type, Form>::type>& result, \
813  const FieldField<Field, Type>& f1, \
814  const VectorSpace<Form,Cmpt,nCmpt>& vs \
815 ) \
816 { \
817  const label loopLen = (result).size(); \
818  \
819  for (label i = 0; i < loopLen; ++i) \
820  { \
821  OpFunc(result[i], f1[i], vs); \
822  } \
823 } \
824  \
825 template \
826 < \
827  template<class> class Field, \
828  class Type, \
829  class Form, \
830  class Cmpt, \
831  direction nCmpt \
832 > \
833 tmp<FieldField<Field, typename product<Type, Form>::type>> \
834 operator Op \
835 ( \
836  const FieldField<Field, Type>& f1, \
837  const VectorSpace<Form,Cmpt,nCmpt>& vs \
838 ) \
839 { \
840  typedef typename product<Type, Form>::type resultType; \
841  auto tres = FieldField<Field, resultType>::NewCalculatedType(f1); \
842  OpFunc(tres.ref(), f1, static_cast<const Form&>(vs)); \
843  return tres; \
844 } \
845  \
846 template \
847 < \
848  template<class> class Field, \
849  class Type, \
850  class Form, \
851  class Cmpt, \
852  direction nCmpt \
853 > \
854 tmp<FieldField<Field, typename product<Type, Form>::type>> \
855 operator Op \
856 ( \
857  const tmp<FieldField<Field, Type>>& tf1, \
858  const VectorSpace<Form,Cmpt,nCmpt>& vs \
859 ) \
860 { \
861  typedef typename product<Type, Form>::type resultType; \
862  auto tres = reuseTmpFieldField<Field, resultType, Type>::New(tf1); \
863  OpFunc(tres.ref(), tf1(), static_cast<const Form&>(vs)); \
864  tf1.clear(); \
865  return tres; \
866 } \
867  \
868 template \
869 < \
870  template<class> class Field, \
871  class Type, \
872  class Form, \
873  class Cmpt, \
874  direction nCmpt \
875 > \
876 void OpFunc \
877 ( \
878  FieldField<Field, typename product<Form, Type>::type>& result, \
879  const VectorSpace<Form,Cmpt,nCmpt>& vs, \
880  const FieldField<Field, Type>& f1 \
881 ) \
882 { \
883  const label loopLen = (result).size(); \
884  \
885  for (label i = 0; i < loopLen; ++i) \
886  { \
887  OpFunc(result[i], vs, f1[i]); \
888  } \
889 } \
890  \
891 template \
892 < \
893  template<class> class Field, \
894  class Type, \
895  class Form, \
896  class Cmpt, \
897  direction nCmpt \
898 > \
899 tmp<FieldField<Field, typename product<Form, Type>::type>> \
900 operator Op \
901 ( \
902  const VectorSpace<Form,Cmpt,nCmpt>& vs, \
903  const FieldField<Field, Type>& f1 \
904 ) \
905 { \
906  typedef typename product<Form, Type>::type resultType; \
907  auto tres = FieldField<Field, resultType>::NewCalculatedType(f1); \
908  OpFunc(tres.ref(), static_cast<const Form&>(vs), f1); \
909  return tres; \
910 } \
911  \
912 template \
913 < \
914  template<class> class Field, \
915  class Type, \
916  class Form, \
917  class Cmpt, \
918  direction nCmpt \
919 > \
920 tmp<FieldField<Field, typename product<Form, Type>::type>> \
921 operator Op \
922 ( \
923  const VectorSpace<Form,Cmpt,nCmpt>& vs, \
924  const tmp<FieldField<Field, Type>>& tf1 \
925 ) \
926 { \
927  typedef typename product<Form, Type>::type resultType; \
928  auto tres = reuseTmpFieldField<Field, resultType, Type>::New(tf1); \
929  OpFunc(tres.ref(), static_cast<const Form&>(vs), tf1()); \
930  tf1.clear(); \
931  return tres; \
932 }
936 
941 
942 #undef PRODUCT_OPERATOR
943 
944 
945 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
946 
947 } // End namespace Foam
948 
949 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
950 
951 #include "undefFieldFunctionsM.H"
952 
953 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
void cmptMax(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
#define BINARY_OPERATOR(ReturnType, Type1, Type2, Op, OpName, OpFunc)
type
Types of root.
Definition: Roots.H:52
void divide(DimensionedField< Type, GeoMesh > &result, const DimensionedField< Type, GeoMesh > &f1, const DimensionedField< scalar, GeoMesh > &f2)
uint8_t direction
Definition: direction.H:46
Inter-processor communication reduction functions.
MinMax< scalar > scalarMinMax
A scalar min/max range.
Definition: MinMax.H:97
tmp< DimensionedField< typename DimensionedField< Type, GeoMesh >::cmptType, GeoMesh >> cmptAv(const DimensionedField< Type, GeoMesh > &f1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Type gMin(const FieldField< Field, Type > &f)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
dimensionedSymmTensor sqr(const dimensionedVector &dv)
A min/max value pair with additional methods. In addition to conveniently storing values...
Definition: HashSet.H:72
#define BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpName, OpFunc)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:529
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:61
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
#define BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpName, OpFunc)
The magnitude type for given argument.
Definition: products.H:92
void cross(FieldField< Field1, typename crossProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1787
typeOfRank< typename pTraits< arg1 >::cmptType, direction(pTraits< arg1 >::rank)+direction(pTraits< arg2 >::rank) >::type type
Definition: products.H:118
#define BINARY_TYPE_FUNCTION(ReturnType, Type1, Type2, Func)
void dotdot(FieldField< Field1, typename scalarProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
void subtract(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
void outer(FieldField< Field1, typename outerProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
void dot(FieldField< Field1, typename innerProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:51
dimensioned< Type > cmptDivide(const dimensioned< Type > &, const dimensioned< Type > &)
MinMax< label > minMax(const labelHashSet &set)
Find the min/max values of labelHashSet.
Definition: hashSets.C:54
#define BINARY_FUNCTION(ReturnType, Type1, Type2, Func)
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1, const label comm)
dimensioned< scalarMinMax > minMaxMag(const DimensionedField< Type, GeoMesh > &f1, const label comm)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:801
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
Type gSum(const FieldField< Field, Type > &f)
Generic templated field type.
Definition: Field.H:63
Type max(const tmp< FieldField< Field, Type >> &tf1)
#define BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func)
#define TMP_UNARY_FUNCTION(ReturnType, Func)
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
void negate(DimensionedField< Type, GeoMesh > &result, const DimensionedField< Type, GeoMesh > &f1)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
static tmp< FieldField< Field, Type > > NewCalculatedType(const FieldField< Field, Type2 > &ff)
Return a pointer to a new calculatedFvPatchFieldField created on.
Definition: FieldField.C:191
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Type gAverage(const FieldField< Field, Type > &f, const label comm)
The global arithmetic average of a FieldField.
Type gMax(const FieldField< Field, Type > &f)
#define G_UNARY_FUNCTION(ReturnType, gFunc, Func, rFunc)
scalarMinMax gMinMaxMag(const FieldField< Field, Type > &f)
labelList f(nPoints)
dimensioned< Type > lerp(const dimensioned< Type > &a, const dimensioned< Type > &b, const scalar t)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
typeOfMag< Type >::type gSumMag(const FieldField< Field, Type > &f)
symmTypeOfRank< typename pTraits< arg1 >::cmptType, arg2 *direction(pTraits< arg1 >::rank) >::type type
Definition: products.H:176
#define PRODUCT_OPERATOR(product, Op, OpFunc)
dimensioned< typename typeOfMag< Type >::type > sumMag(const DimensionedField< Type, GeoMesh > &f1, const label comm)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
pTraits< Type >::cmptType cmptType
Component type.
Definition: FieldField.H:83
#define WarningInFunction
Report a warning using Foam::Warning.
void sumReduce(T &value, CountType &count, [[maybe_unused]] const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) the sum of value and counter (eg, for averaging) ...
label n
static tmp< FieldField< Field, TypeR > > New(const FieldField< Field, Type1 > &f1)
Pass-through to NewCalculatedType.
#define UNARY_OPERATOR(ReturnType, Type1, Op, OpFunc, Dfunc)
#define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func)
void cmptMin(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
void multiply(DimensionedField< Type, GeoMesh > &result, const DimensionedField< Type, GeoMesh > &f1, const DimensionedField< scalar, GeoMesh > &f2)
#define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func)
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Namespace for OpenFOAM.
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
Definition: dimensionSet.C:271
pTraits< typename pTraits< arg1 >::cmptType >::magType type
Definition: products.H:96
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127