BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OpenFOAM / fields / FieldFields / FieldField / FieldFieldFunctions.C
blobfd79d3835ad671233d47b1b93671c3aab57be7b6
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "PstreamReduceOps.H"
27 #include "FieldFieldReuseFunctions.H"
29 #define TEMPLATE template<template<class> class Field, class Type>
30 #include "FieldFieldFunctionsM.C"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 namespace Foam
37 /* * * * * * * * * * * * * * * * Global functions  * * * * * * * * * * * * * */
39 template<template<class> class Field, class Type>
40 void component
42     FieldField<Field, typename FieldField<Field, Type>::cmptType>& sf,
43     const FieldField<Field, Type>& f,
44     const direction d
47     forAll(sf, i)
48     {
49         component(sf[i], f[i], d);
50     }
54 template<template<class> class Field, class Type>
55 void T(FieldField<Field, Type>& f1, const FieldField<Field, Type>& f2)
57     forAll(f1, i)
58     {
59         T(f1[i], f2[i]);
60     }
64 template<template<class> class Field, class Type, int r>
65 void pow
67     FieldField<Field, typename powProduct<Type, r>::type>& f,
68     const FieldField<Field, Type>& vf
71     forAll(f, i)
72     {
73         pow(f[i], vf[i]);
74     }
77 template<template<class> class Field, class Type, int r>
78 tmp<FieldField<Field, typename powProduct<Type, r>::type> >
79 pow
81     const FieldField<Field, Type>& f, typename powProduct<Type, r>::type
84     typedef typename powProduct<Type, r>::type powProductType;
85     tmp<FieldField<Field, powProductType> > tRes
86     (
87         FieldField<Field, powProductType>::NewCalculatedType(f)
88     );
89     pow<Type, r>(tRes(), f);
90     return tRes;
93 template<template<class> class Field, class Type, int r>
94 tmp<FieldField<Field, typename powProduct<Type, r>::type> >
95 pow
97     const tmp<FieldField<Field, Type> >& tf, typename powProduct<Type, r>::type
100     typedef typename powProduct<Type, r>::type powProductType;
101     tmp<FieldField<Field, powProductType> > tRes
102     (
103         reuseTmpFieldField<Field, powProductType, Type>::New(tf)
104     );
105     pow<Type, r>(tRes(), tf());
106     reuseTmpFieldField<Field, powProductType, Type>::clear(tf);
107     return tRes;
111 template<template<class> class Field, class Type>
112 void sqr
114     FieldField<Field, typename outerProduct<Type, Type>::type>& f,
115     const FieldField<Field, Type>& vf
118     forAll(f, i)
119     {
120         sqr(f[i], vf[i]);
121     }
124 template<template<class> class Field, class Type>
125 tmp<FieldField<Field, typename outerProduct<Type, Type>::type> >
126 sqr(const FieldField<Field, Type>& f)
128     typedef typename outerProduct<Type, Type>::type outerProductType;
129     tmp<FieldField<Field, outerProductType> > tRes
130     (
131         FieldField<Field, outerProductType>::NewCalculatedType(f)
132     );
133     sqr(tRes(), f);
134     return tRes;
137 template<template<class> class Field, class Type>
138 tmp<FieldField<Field, typename outerProduct<Type, Type>::type> >
139 sqr(const tmp<FieldField<Field, Type> >& tf)
141     typedef typename outerProduct<Type, Type>::type outerProductType;
142     tmp<FieldField<Field, outerProductType> > tRes
143     (
144         reuseTmpFieldField<Field, outerProductType, Type>::New(tf)
145     );
146     sqr(tRes(), tf());
147     reuseTmpFieldField<Field, outerProductType, Type>::clear(tf);
148     return tRes;
152 template<template<class> class Field, class Type>
153 void magSqr(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
155     forAll(sf, i)
156     {
157         magSqr(sf[i], f[i]);
158     }
161 template<template<class> class Field, class Type>
162 tmp<FieldField<Field, scalar> > magSqr(const FieldField<Field, Type>& f)
164     tmp<FieldField<Field, scalar> > tRes
165     (
166         FieldField<Field, scalar>::NewCalculatedType(f)
167     );
169     magSqr(tRes(), f);
170     return tRes;
173 template<template<class> class Field, class Type>
174 tmp<FieldField<Field, scalar> > magSqr(const tmp<FieldField<Field, Type> >& tf)
176     tmp<FieldField<Field, scalar> > tRes
177     (
178         reuseTmpFieldField<Field, scalar, Type>::New(tf)
179     );
181     magSqr(tRes(), tf());
182     reuseTmpFieldField<Field, scalar, Type>::clear(tf);
183     return tRes;
187 template<template<class> class Field, class Type>
188 void mag(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
190     forAll(sf, i)
191     {
192         mag(sf[i], f[i]);
193     }
196 template<template<class> class Field, class Type>
197 tmp<FieldField<Field, scalar> > mag(const FieldField<Field, Type>& f)
199     tmp<FieldField<Field, scalar> > tRes
200     (
201         FieldField<Field, scalar>::NewCalculatedType(f)
202     );
204     mag(tRes(), f);
205     return tRes;
208 template<template<class> class Field, class Type>
209 tmp<FieldField<Field, scalar> > mag(const tmp<FieldField<Field, Type> >& tf)
211     tmp<FieldField<Field, scalar> > tRes
212     (
213         reuseTmpFieldField<Field, scalar, Type>::New(tf)
214     );
216     mag(tRes(), tf());
217     reuseTmpFieldField<Field, scalar, Type>::clear(tf);
218     return tRes;
222 template<template<class> class Field, class Type>
223 void cmptMax
225     FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
226     const FieldField<Field, Type>& f
229     forAll(cf, i)
230     {
231         cmptMax(cf[i], f[i]);
232     }
235 template<template<class> class Field, class Type>
236 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMax
238     const FieldField<Field, Type>& f
241     typedef typename FieldField<Field, Type>::cmptType cmptType;
242     tmp<FieldField<Field, cmptType> > tRes
243     (
244         FieldField<Field, cmptType>::NewCalculatedType(f)
245     );
246     cmptMax(tRes(), f);
247     return tRes;
250 template<template<class> class Field, class Type>
251 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMax
253     const tmp<FieldField<Field, Type> >& tf
256     typedef typename FieldField<Field, Type>::cmptType cmptType;
257     tmp<FieldField<Field, cmptType> > tRes
258     (
259         reuseTmpFieldField<Field, cmptType, Type>::New(tf)
260     );
261     cmptMax(tRes(), tf());
262     reuseTmpFieldField<Field, cmptType, Type>::clear(tf);
263     return tRes;
267 template<template<class> class Field, class Type>
268 void cmptMin
270     FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
271     const FieldField<Field, Type>& f
274     forAll(cf, i)
275     {
276         cmptMin(cf[i], f[i]);
277     }
280 template<template<class> class Field, class Type>
281 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMin
283     const FieldField<Field, Type>& f
286     typedef typename FieldField<Field, Type>::cmptType cmptType;
287     tmp<FieldField<Field, cmptType> > tRes
288     (
289         FieldField<Field, cmptType>::NewCalculatedType(f)
290     );
291     cmptMin(tRes(), f);
292     return tRes;
295 template<template<class> class Field, class Type>
296 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMin
298     const tmp<FieldField<Field, Type> >& tf
301     typedef typename FieldField<Field, Type>::cmptType cmptType;
302     tmp<FieldField<Field, cmptType> > tRes
303     (
304         reuseTmpFieldField<Field, cmptType, Type>::New(tf)
305     );
306     cmptMin(tRes(), tf());
307     reuseTmpFieldField<Field, cmptType, Type>::clear(tf);
308     return tRes;
312 template<template<class> class Field, class Type>
313 void cmptAv
315     FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
316     const FieldField<Field, Type>& f
319     forAll(cf, i)
320     {
321         cmptAv(cf[i], f[i]);
322     }
325 template<template<class> class Field, class Type>
326 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptAv
328     const FieldField<Field, Type>& f
331     typedef typename FieldField<Field, Type>::cmptType cmptType;
332     tmp<FieldField<Field, cmptType> > tRes
333     (
334         FieldField<Field, cmptType>::NewCalculatedType(f)
335     );
336     cmptAv(tRes(), f);
337     return tRes;
340 template<template<class> class Field, class Type>
341 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptAv
343     const tmp<FieldField<Field, Type> >& tf
346     typedef typename FieldField<Field, Type>::cmptType cmptType;
347     tmp<FieldField<Field, cmptType> > tRes
348     (
349         reuseTmpFieldField<Field, cmptType, Type>::New(tf)
350     );
351     cmptAv(tRes(), tf());
352     reuseTmpFieldField<Field, cmptType, Type>::clear(tf);
353     return tRes;
357 template<template<class> class Field, class Type>
358 void cmptMag
360     FieldField<Field, Type>& cf,
361     const FieldField<Field, Type>& f
364     forAll(cf, i)
365     {
366         cmptMag(cf[i], f[i]);
367     }
370 template<template<class> class Field, class Type>
371 tmp<FieldField<Field, Type> > cmptMag
373     const FieldField<Field, Type>& f
376     tmp<FieldField<Field, Type> > tRes
377     (
378         FieldField<Field, Type>::NewCalculatedType(f)
379     );
380     cmptMag(tRes(), f);
381     return tRes;
384 template<template<class> class Field, class Type>
385 tmp<FieldField<Field, Type> > cmptMag
387     const tmp<FieldField<Field, Type> >& tf
390     tmp<FieldField<Field, Type> > tRes
391     (
392         reuseTmpFieldField<Field, Type, Type>::New(tf)
393     );
394     cmptMag(tRes(), tf());
395     reuseTmpFieldField<Field, Type, Type>::clear(tf);
396     return tRes;
400 #define TMP_UNARY_FUNCTION(returnType, func)                                  \
401                                                                               \
402 template<template<class> class Field, class Type>                             \
403 returnType func(const tmp<FieldField<Field, Type> >& tf1)                     \
404 {                                                                             \
405     returnType res = func(tf1());                                             \
406     tf1.clear();                                                              \
407     return res;                                                               \
410 template<template<class> class Field, class Type>
411 Type max(const FieldField<Field, Type>& f)
413     label i = 0;
414     while (i < f.size() && !f[i].size()) i++;
416     if (i < f.size())
417     {
418         Type Max(max(f[i]));
420         for (label j=i+1; j<f.size(); j++)
421         {
422             if (f[j].size())
423             {
424                 Max = max(max(f[j]), Max);
425             }
426         }
428         return Max;
429     }
430     else
431     {
432         return pTraits<Type>::min;
433     }
436 TMP_UNARY_FUNCTION(Type, max)
438 template<template<class> class Field, class Type>
439 Type min(const FieldField<Field, Type>& f)
441     label i = 0;
442     while (i < f.size() && !f[i].size()) i++;
444     if (i < f.size())
445     {
446         label i = 0;
447         while (!f[i].size()) i++;
449         Type Min(min(f[i]));
451         for (label j=i+1; j<f.size(); j++)
452         {
453             if (f[j].size())
454             {
455                 Min = min(min(f[j]), Min);
456             }
457         }
459         return Min;
460     }
461     else
462     {
463         return pTraits<Type>::max;
464     }
467 TMP_UNARY_FUNCTION(Type, min)
469 template<template<class> class Field, class Type>
470 Type sum(const FieldField<Field, Type>& f)
472     if (f.size())
473     {
474         Type Sum = pTraits<Type>::zero;
476         forAll(f, i)
477         {
478             Sum += sum(f[i]);
479         }
481         return Sum;
482     }
483     else
484     {
485         return pTraits<Type>::zero;
486     }
489 TMP_UNARY_FUNCTION(Type, sum)
491 template<template<class> class Field, class Type>
492 scalar sumMag(const FieldField<Field, Type>& f)
494     if (f.size())
495     {
496         scalar SumMag = 0.0;
498         forAll(f, i)
499         {
500             SumMag += sumMag(f[i]);
501         }
503         return SumMag;
504     }
505     else
506     {
507         return 0.0;
508     }
511 TMP_UNARY_FUNCTION(scalar, sumMag)
513 template<template<class> class Field, class Type>
514 Type average(const FieldField<Field, Type>& f)
516     if (f.size())
517     {
518         label n = 0;
520         forAll(f, i)
521         {
522             n += f[i].size();
523         }
525         if (n == 0)
526         {
527             WarningIn("average(const FieldField<Field, Type>&) const")
528                 << "empty fieldField, returning zero" << endl;
530             return pTraits<Type>::zero;
531         }
533         Type avrg = sum(f)/n;
535         return avrg;
536     }
537     else
538     {
539         WarningIn("average(const FieldField<Field, Type>&) const")
540             << "empty fieldField, returning zero" << endl;
542         return pTraits<Type>::zero;
543     }
546 TMP_UNARY_FUNCTION(Type, average)
549 #include "PstreamReduceOps.H"
551 #define G_UNARY_FUNCTION(returnType, gFunc, func, rFunc)                      \
552                                                                               \
553 template<template<class> class Field, class Type>                             \
554 returnType gFunc(const FieldField<Field, Type>& f)                            \
555 {                                                                             \
556     returnType res = func(f);                                                 \
557     reduce(res, rFunc##Op<Type>());                                           \
558     return res;                                                               \
559 }                                                                             \
560 TMP_UNARY_FUNCTION(returnType, gFunc)
562 G_UNARY_FUNCTION(Type, gMax, max, max)
563 G_UNARY_FUNCTION(Type, gMin, min, min)
564 G_UNARY_FUNCTION(Type, gSum, sum, sum)
565 G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
567 #undef G_UNARY_FUNCTION
570 template<template<class> class Field, class Type>
571 Type gAverage(const FieldField<Field, Type>& f)
573     label n = 0;
575     forAll(f, i)
576     {
577         n += f[i].size();
578     }
580     reduce(n, sumOp<label>());
582     if (n > 0)
583     {
584         Type avrg = gSum(f)/n;
586         return avrg;
587     }
588     else
589     {
590         WarningIn("gAverage(const FieldField<Field, Type>&) const")
591             << "empty fieldField, returning zero" << endl;
593         return pTraits<Type>::zero;
594     }
597 TMP_UNARY_FUNCTION(Type, gAverage)
599 #undef TMP_UNARY_FUNCTION
602 BINARY_FUNCTION(Type, Type, Type, max)
603 BINARY_FUNCTION(Type, Type, Type, min)
604 BINARY_FUNCTION(Type, Type, Type, cmptMultiply)
605 BINARY_FUNCTION(Type, Type, Type, cmptDivide)
607 BINARY_TYPE_FUNCTION(Type, Type, Type, max)
608 BINARY_TYPE_FUNCTION(Type, Type, Type, min)
609 BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
610 BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
613 /* * * * * * * * * * * * * * * * Global operators  * * * * * * * * * * * * * */
615 UNARY_OPERATOR(Type, Type, -, negate)
617 #ifndef __INTEL_COMPILER
618 BINARY_OPERATOR(Type, Type, scalar, *, multiply)
619 BINARY_OPERATOR(Type, scalar, Type, *, multiply)
620 #endif
621 BINARY_OPERATOR(Type, Type, scalar, /, divide)
623 BINARY_TYPE_OPERATOR_SF(Type, scalar, Type, *, multiply)
624 BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, *, multiply)
626 BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, /, divide)
629 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
631 #define PRODUCT_OPERATOR(product, op, opFunc)                                 \
632                                                                               \
633 template<template<class> class Field, class Type1, class Type2>               \
634 void opFunc                                                                   \
635 (                                                                             \
636     FieldField<Field, typename product<Type1, Type2>::type>& f,               \
637     const FieldField<Field, Type1>& f1,                                       \
638     const FieldField<Field, Type2>& f2                                        \
639 )                                                                             \
640 {                                                                             \
641     forAll(f, i)                                                              \
642     {                                                                         \
643         opFunc(f[i], f1[i], f2[i]);                                           \
644     }                                                                         \
645 }                                                                             \
646                                                                               \
647 template<template<class> class Field, class Type1, class Type2>               \
648 tmp<FieldField<Field, typename product<Type1, Type2>::type> >                 \
649 operator op                                                                   \
650 (                                                                             \
651     const FieldField<Field, Type1>& f1,                                       \
652     const FieldField<Field, Type2>& f2                                        \
653 )                                                                             \
654 {                                                                             \
655     typedef typename product<Type1, Type2>::type productType;                 \
656     tmp<FieldField<Field, productType> > tRes                                 \
657     (                                                                         \
658         FieldField<Field, productType>::NewCalculatedType(f1)                 \
659     );                                                                        \
660     opFunc(tRes(), f1, f2);                                                   \
661     return tRes;                                                              \
662 }                                                                             \
663                                                                               \
664 template<template<class> class Field, class Type1, class Type2>               \
665 tmp<FieldField<Field, typename product<Type1, Type2>::type> >                 \
666 operator op                                                                   \
667 (                                                                             \
668     const FieldField<Field, Type1>& f1,                                       \
669     const tmp<FieldField<Field, Type2> >& tf2                                 \
670 )                                                                             \
671 {                                                                             \
672     typedef typename product<Type1, Type2>::type productType;                 \
673     tmp<FieldField<Field, productType> > tRes                                 \
674     (                                                                         \
675         reuseTmpFieldField<Field, productType, Type2>::New(tf2)               \
676     );                                                                        \
677     opFunc(tRes(), f1, tf2());                                                \
678     reuseTmpFieldField<Field, productType, Type2>::clear(tf2);                \
679     return tRes;                                                              \
680 }                                                                             \
681                                                                               \
682 template<template<class> class Field, class Type1, class Type2>               \
683 tmp<FieldField<Field, typename product<Type1, Type2>::type> >                 \
684 operator op                                                                   \
685 (                                                                             \
686     const tmp<FieldField<Field, Type1> >& tf1,                                \
687     const FieldField<Field, Type2>& f2                                        \
688 )                                                                             \
689 {                                                                             \
690     typedef typename product<Type1, Type2>::type productType;                 \
691     tmp<FieldField<Field, productType> > tRes                                 \
692     (                                                                         \
693         reuseTmpFieldField<Field, productType, Type1>::New(tf1)               \
694     );                                                                        \
695     opFunc(tRes(), tf1(), f2);                                                \
696     reuseTmpFieldField<Field, productType, Type1>::clear(tf1);                \
697     return tRes;                                                              \
698 }                                                                             \
699                                                                               \
700 template<template<class> class Field, class Type1, class Type2>               \
701 tmp<FieldField<Field, typename product<Type1, Type2>::type> >                 \
702 operator op                                                                   \
703 (                                                                             \
704     const tmp<FieldField<Field, Type1> >& tf1,                                \
705     const tmp<FieldField<Field, Type2> >& tf2                                 \
706 )                                                                             \
707 {                                                                             \
708     typedef typename product<Type1, Type2>::type productType;                 \
709     tmp<FieldField<Field, productType> > tRes                                 \
710     (                                                                         \
711         reuseTmpTmpFieldField<Field, productType, Type1, Type1, Type2>::New   \
712             (tf1, tf2)                                                        \
713     );                                                                        \
714     opFunc(tRes(), tf1(), tf2());                                             \
715     reuseTmpTmpFieldField<Field, productType, Type1, Type1, Type2>::clear     \
716         (tf1, tf2);                                                           \
717     return tRes;                                                              \
718 }                                                                             \
719                                                                               \
720 template                                                                      \
721 <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt>  \
722 void opFunc                                                                   \
723 (                                                                             \
724     FieldField<Field, typename product<Type, Form>::type>& f,                 \
725     const FieldField<Field, Type>& f1,                                        \
726     const VectorSpace<Form,Cmpt,nCmpt>& vs                                    \
727 )                                                                             \
728 {                                                                             \
729     forAll(f, i)                                                              \
730     {                                                                         \
731         opFunc(f[i], f1[i], vs);                                              \
732     }                                                                         \
733 }                                                                             \
734                                                                               \
735 template                                                                      \
736 <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt>  \
737 tmp<FieldField<Field, typename product<Type, Form>::type> >                   \
738 operator op                                                                   \
739 (                                                                             \
740     const FieldField<Field, Type>& f1,                                        \
741     const VectorSpace<Form,Cmpt,nCmpt>& vs                                    \
742 )                                                                             \
743 {                                                                             \
744     typedef typename product<Type, Form>::type productType;                   \
745     tmp<FieldField<Field, productType> > tRes                                 \
746     (                                                                         \
747         FieldField<Field, productType>::NewCalculatedType(f1)                 \
748     );                                                                        \
749     opFunc(tRes(), f1, static_cast<const Form&>(vs));                         \
750     return tRes;                                                              \
751 }                                                                             \
752                                                                               \
753 template                                                                      \
754 <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt>  \
755 tmp<FieldField<Field, typename product<Type, Form>::type> >                   \
756 operator op                                                                   \
757 (                                                                             \
758     const tmp<FieldField<Field, Type> >& tf1,                                 \
759     const VectorSpace<Form,Cmpt,nCmpt>& vs                                    \
760 )                                                                             \
761 {                                                                             \
762     typedef typename product<Type, Form>::type productType;                   \
763     tmp<FieldField<Field, productType> > tRes                                 \
764     (                                                                         \
765         reuseTmpFieldField<Field, productType, Type>::New(tf1)                \
766     );                                                                        \
767     opFunc(tRes(), tf1(), static_cast<const Form&>(vs));                      \
768     reuseTmpFieldField<Field, productType, Type>::clear(tf1);                 \
769     return tRes;                                                              \
770 }                                                                             \
771                                                                               \
772 template                                                                      \
773 <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type>  \
774 void opFunc                                                                   \
775 (                                                                             \
776     FieldField<Field, typename product<Form, Type>::type>& f,                 \
777     const VectorSpace<Form,Cmpt,nCmpt>& vs,                                   \
778     const FieldField<Field, Type>& f1                                         \
779 )                                                                             \
780 {                                                                             \
781     forAll(f, i)                                                              \
782     {                                                                         \
783         opFunc(f[i], vs, f1[i]);                                              \
784     }                                                                         \
785 }                                                                             \
786                                                                               \
787 template                                                                      \
788 <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type>  \
789 tmp<FieldField<Field, typename product<Form, Type>::type> >                   \
790 operator op                                                                   \
791 (                                                                             \
792     const VectorSpace<Form,Cmpt,nCmpt>& vs,                                   \
793     const FieldField<Field, Type>& f1                                         \
794 )                                                                             \
795 {                                                                             \
796     typedef typename product<Form, Type>::type productType;                   \
797     tmp<FieldField<Field, productType> > tRes                                 \
798     (                                                                         \
799         FieldField<Field, productType>::NewCalculatedType(f1)                 \
800     );                                                                        \
801     opFunc(tRes(), static_cast<const Form&>(vs), f1);                         \
802     return tRes;                                                              \
803 }                                                                             \
804                                                                               \
805 template                                                                      \
806 <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type>  \
807 tmp<FieldField<Field, typename product<Form, Type>::type> >                   \
808 operator op                                                                   \
809 (                                                                             \
810     const VectorSpace<Form,Cmpt,nCmpt>& vs,                                   \
811     const tmp<FieldField<Field, Type> >& tf1                                  \
812 )                                                                             \
813 {                                                                             \
814     typedef typename product<Form, Type>::type productType;                   \
815     tmp<FieldField<Field, productType> > tRes                                 \
816     (                                                                         \
817         reuseTmpFieldField<Field, productType, Type>::New(tf1)                \
818     );                                                                        \
819     opFunc(tRes(), static_cast<const Form&>(vs), tf1());                      \
820     reuseTmpFieldField<Field, productType, Type>::clear(tf1);                 \
821     return tRes;                                                              \
824 PRODUCT_OPERATOR(typeOfSum, +, add)
825 PRODUCT_OPERATOR(typeOfSum, -, subtract)
827 PRODUCT_OPERATOR(outerProduct, *, outer)
828 PRODUCT_OPERATOR(crossProduct, ^, cross)
829 PRODUCT_OPERATOR(innerProduct, &, dot)
830 PRODUCT_OPERATOR(scalarProduct, &&, dotdot)
832 #undef PRODUCT_OPERATOR
835 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
837 } // End namespace Foam
839 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
841 #include "undefFieldFunctionsM.H"
843 // ************************************************************************* //