00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/PstreamReduceOps.H>
00027 #include "FieldFieldReuseFunctions.H"
00028
00029 #define TEMPLATE template<template<class> class Field, class Type>
00030 #include "FieldFieldFunctionsM.C"
00031
00032
00033
00034 namespace Foam
00035 {
00036
00037
00038
00039 template<template<class> class Field, class Type>
00040 void component
00041 (
00042 FieldField<Field, typename FieldField<Field, Type>::cmptType>& sf,
00043 const FieldField<Field, Type>& f,
00044 const direction d
00045 )
00046 {
00047 forAll(sf, i)
00048 {
00049 component(sf[i], f[i], d);
00050 }
00051 }
00052
00053
00054 template<template<class> class Field, class Type>
00055 void T(FieldField<Field, Type>& f1, const FieldField<Field, Type>& f2)
00056 {
00057 forAll(f1, i)
00058 {
00059 T(f1[i], f2[i]);
00060 }
00061 }
00062
00063
00064 template<template<class> class Field, class Type, int r>
00065 void pow
00066 (
00067 FieldField<Field, typename powProduct<Type, r>::type>& f,
00068 const FieldField<Field, Type>& vf
00069 )
00070 {
00071 forAll(f, i)
00072 {
00073 pow(f[i], vf[i]);
00074 }
00075 }
00076
00077 template<template<class> class Field, class Type, int r>
00078 tmp<FieldField<Field, typename powProduct<Type, r>::type> >
00079 pow
00080 (
00081 const FieldField<Field, Type>& f, typename powProduct<Type, r>::type
00082 )
00083 {
00084 typedef typename powProduct<Type, r>::type powProductType;
00085 tmp<FieldField<Field, powProductType> > tRes
00086 (
00087 FieldField<Field, powProductType>::NewCalculatedType(f)
00088 );
00089 pow<Type, r>(tRes(), f);
00090 return tRes;
00091 }
00092
00093 template<template<class> class Field, class Type, int r>
00094 tmp<FieldField<Field, typename powProduct<Type, r>::type> >
00095 pow
00096 (
00097 const tmp<FieldField<Field, Type> >& tf, typename powProduct<Type, r>::type
00098 )
00099 {
00100 typedef typename powProduct<Type, r>::type powProductType;
00101 tmp<FieldField<Field, powProductType> > tRes
00102 (
00103 reuseTmpFieldField<Field, powProductType, Type>::New(tf)
00104 );
00105 pow<Type, r>(tRes(), tf());
00106 reuseTmpFieldField<Field, powProductType, Type>::clear(tf);
00107 return tRes;
00108 }
00109
00110
00111 template<template<class> class Field, class Type>
00112 void sqr
00113 (
00114 FieldField<Field, typename outerProduct<Type, Type>::type>& f,
00115 const FieldField<Field, Type>& vf
00116 )
00117 {
00118 forAll(f, i)
00119 {
00120 sqr(f[i], vf[i]);
00121 }
00122 }
00123
00124 template<template<class> class Field, class Type>
00125 tmp<FieldField<Field, typename outerProduct<Type, Type>::type> >
00126 sqr(const FieldField<Field, Type>& f)
00127 {
00128 typedef typename outerProduct<Type, Type>::type outerProductType;
00129 tmp<FieldField<Field, outerProductType> > tRes
00130 (
00131 FieldField<Field, outerProductType>::NewCalculatedType(f)
00132 );
00133 sqr(tRes(), f);
00134 return tRes;
00135 }
00136
00137 template<template<class> class Field, class Type>
00138 tmp<FieldField<Field, typename outerProduct<Type, Type>::type> >
00139 sqr(const tmp<FieldField<Field, Type> >& tf)
00140 {
00141 typedef typename outerProduct<Type, Type>::type outerProductType;
00142 tmp<FieldField<Field, outerProductType> > tRes
00143 (
00144 reuseTmpFieldField<Field, outerProductType, Type>::New(tf)
00145 );
00146 sqr(tRes(), tf());
00147 reuseTmpFieldField<Field, outerProductType, Type>::clear(tf);
00148 return tRes;
00149 }
00150
00151
00152 template<template<class> class Field, class Type>
00153 void magSqr(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
00154 {
00155 forAll(sf, i)
00156 {
00157 magSqr(sf[i], f[i]);
00158 }
00159 }
00160
00161 template<template<class> class Field, class Type>
00162 tmp<FieldField<Field, scalar> > magSqr(const FieldField<Field, Type>& f)
00163 {
00164 tmp<FieldField<Field, scalar> > tRes
00165 (
00166 FieldField<Field, scalar>::NewCalculatedType(f)
00167 );
00168
00169 magSqr(tRes(), f);
00170 return tRes;
00171 }
00172
00173 template<template<class> class Field, class Type>
00174 tmp<FieldField<Field, scalar> > magSqr(const tmp<FieldField<Field, Type> >& tf)
00175 {
00176 tmp<FieldField<Field, scalar> > tRes
00177 (
00178 reuseTmpFieldField<Field, scalar, Type>::New(tf)
00179 );
00180
00181 magSqr(tRes(), tf());
00182 reuseTmpFieldField<Field, scalar, Type>::clear(tf);
00183 return tRes;
00184 }
00185
00186
00187 template<template<class> class Field, class Type>
00188 void mag(FieldField<Field, scalar>& sf, const FieldField<Field, Type>& f)
00189 {
00190 forAll(sf, i)
00191 {
00192 mag(sf[i], f[i]);
00193 }
00194 }
00195
00196 template<template<class> class Field, class Type>
00197 tmp<FieldField<Field, scalar> > mag(const FieldField<Field, Type>& f)
00198 {
00199 tmp<FieldField<Field, scalar> > tRes
00200 (
00201 FieldField<Field, scalar>::NewCalculatedType(f)
00202 );
00203
00204 mag(tRes(), f);
00205 return tRes;
00206 }
00207
00208 template<template<class> class Field, class Type>
00209 tmp<FieldField<Field, scalar> > mag(const tmp<FieldField<Field, Type> >& tf)
00210 {
00211 tmp<FieldField<Field, scalar> > tRes
00212 (
00213 reuseTmpFieldField<Field, scalar, Type>::New(tf)
00214 );
00215
00216 mag(tRes(), tf());
00217 reuseTmpFieldField<Field, scalar, Type>::clear(tf);
00218 return tRes;
00219 }
00220
00221
00222 template<template<class> class Field, class Type>
00223 void cmptMax
00224 (
00225 FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
00226 const FieldField<Field, Type>& f
00227 )
00228 {
00229 forAll(cf, i)
00230 {
00231 cmptMax(cf[i], f[i]);
00232 }
00233 }
00234
00235 template<template<class> class Field, class Type>
00236 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMax
00237 (
00238 const FieldField<Field, Type>& f
00239 )
00240 {
00241 typedef typename FieldField<Field, Type>::cmptType cmptType;
00242 tmp<FieldField<Field, cmptType> > tRes
00243 (
00244 FieldField<Field, cmptType>::NewCalculatedType(f)
00245 );
00246 cmptMax(tRes(), f);
00247 return tRes;
00248 }
00249
00250 template<template<class> class Field, class Type>
00251 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMax
00252 (
00253 const tmp<FieldField<Field, Type> >& tf
00254 )
00255 {
00256 typedef typename FieldField<Field, Type>::cmptType cmptType;
00257 tmp<FieldField<Field, cmptType> > tRes
00258 (
00259 reuseTmpFieldField<Field, cmptType, Type>::New(tf)
00260 );
00261 cmptMax(tRes(), tf());
00262 reuseTmpFieldField<Field, cmptType, Type>::clear(tf);
00263 return tRes;
00264 }
00265
00266
00267 template<template<class> class Field, class Type>
00268 void cmptMin
00269 (
00270 FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
00271 const FieldField<Field, Type>& f
00272 )
00273 {
00274 forAll(cf, i)
00275 {
00276 cmptMin(cf[i], f[i]);
00277 }
00278 }
00279
00280 template<template<class> class Field, class Type>
00281 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMin
00282 (
00283 const FieldField<Field, Type>& f
00284 )
00285 {
00286 typedef typename FieldField<Field, Type>::cmptType cmptType;
00287 tmp<FieldField<Field, cmptType> > tRes
00288 (
00289 FieldField<Field, cmptType>::NewCalculatedType(f)
00290 );
00291 cmptMin(tRes(), f);
00292 return tRes;
00293 }
00294
00295 template<template<class> class Field, class Type>
00296 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptMin
00297 (
00298 const tmp<FieldField<Field, Type> >& tf
00299 )
00300 {
00301 typedef typename FieldField<Field, Type>::cmptType cmptType;
00302 tmp<FieldField<Field, cmptType> > tRes
00303 (
00304 reuseTmpFieldField<Field, cmptType, Type>::New(tf)
00305 );
00306 cmptMin(tRes(), tf());
00307 reuseTmpFieldField<Field, cmptType, Type>::clear(tf);
00308 return tRes;
00309 }
00310
00311
00312 template<template<class> class Field, class Type>
00313 void cmptAv
00314 (
00315 FieldField<Field, typename FieldField<Field, Type>::cmptType>& cf,
00316 const FieldField<Field, Type>& f
00317 )
00318 {
00319 forAll(cf, i)
00320 {
00321 cmptAv(cf[i], f[i]);
00322 }
00323 }
00324
00325 template<template<class> class Field, class Type>
00326 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptAv
00327 (
00328 const FieldField<Field, Type>& f
00329 )
00330 {
00331 typedef typename FieldField<Field, Type>::cmptType cmptType;
00332 tmp<FieldField<Field, cmptType> > tRes
00333 (
00334 FieldField<Field, cmptType>::NewCalculatedType(f)
00335 );
00336 cmptAv(tRes(), f);
00337 return tRes;
00338 }
00339
00340 template<template<class> class Field, class Type>
00341 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType> > cmptAv
00342 (
00343 const tmp<FieldField<Field, Type> >& tf
00344 )
00345 {
00346 typedef typename FieldField<Field, Type>::cmptType cmptType;
00347 tmp<FieldField<Field, cmptType> > tRes
00348 (
00349 reuseTmpFieldField<Field, cmptType, Type>::New(tf)
00350 );
00351 cmptAv(tRes(), tf());
00352 reuseTmpFieldField<Field, cmptType, Type>::clear(tf);
00353 return tRes;
00354 }
00355
00356
00357 template<template<class> class Field, class Type>
00358 void cmptMag
00359 (
00360 FieldField<Field, Type>& cf,
00361 const FieldField<Field, Type>& f
00362 )
00363 {
00364 forAll(cf, i)
00365 {
00366 cmptMag(cf[i], f[i]);
00367 }
00368 }
00369
00370 template<template<class> class Field, class Type>
00371 tmp<FieldField<Field, Type> > cmptMag
00372 (
00373 const FieldField<Field, Type>& f
00374 )
00375 {
00376 tmp<FieldField<Field, Type> > tRes
00377 (
00378 FieldField<Field, Type>::NewCalculatedType(f)
00379 );
00380 cmptMag(tRes(), f);
00381 return tRes;
00382 }
00383
00384 template<template<class> class Field, class Type>
00385 tmp<FieldField<Field, Type> > cmptMag
00386 (
00387 const tmp<FieldField<Field, Type> >& tf
00388 )
00389 {
00390 tmp<FieldField<Field, Type> > tRes
00391 (
00392 reuseTmpFieldField<Field, Type, Type>::New(tf)
00393 );
00394 cmptMag(tRes(), tf());
00395 reuseTmpFieldField<Field, Type, Type>::clear(tf);
00396 return tRes;
00397 }
00398
00399
00400 #define TMP_UNARY_FUNCTION(returnType, func) \
00401 \
00402 template<template<class> class Field, class Type> \
00403 returnType func(const tmp<FieldField<Field, Type> >& tf1) \
00404 { \
00405 returnType res = func(tf1()); \
00406 tf1.clear(); \
00407 return res; \
00408 }
00409
00410 template<template<class> class Field, class Type>
00411 Type max(const FieldField<Field, Type>& f)
00412 {
00413 label i = 0;
00414 while(i < f.size() && !f[i].size()) i++;
00415
00416 if (i < f.size())
00417 {
00418 Type Max(max(f[i]));
00419
00420 for (label j=i+1; j<f.size(); j++)
00421 {
00422 if (f[j].size())
00423 {
00424 Max = max(max(f[j]), Max);
00425 }
00426 }
00427
00428 return Max;
00429 }
00430 else
00431 {
00432 return pTraits<Type>::min;
00433 }
00434 }
00435
00436 TMP_UNARY_FUNCTION(Type, max)
00437
00438 template<template<class> class Field, class Type>
00439 Type min(const FieldField<Field, Type>& f)
00440 {
00441 label i = 0;
00442 while(i < f.size() && !f[i].size()) i++;
00443
00444 if (i < f.size())
00445 {
00446 label i = 0;
00447 while(!f[i].size()) i++;
00448
00449 Type Min(min(f[i]));
00450
00451 for (label j=i+1; j<f.size(); j++)
00452 {
00453 if (f[j].size())
00454 {
00455 Min = min(min(f[j]), Min);
00456 }
00457 }
00458
00459 return Min;
00460 }
00461 else
00462 {
00463 return pTraits<Type>::max;
00464 }
00465 }
00466
00467 TMP_UNARY_FUNCTION(Type, min)
00468
00469 template<template<class> class Field, class Type>
00470 Type sum(const FieldField<Field, Type>& f)
00471 {
00472 if (f.size())
00473 {
00474 Type Sum = pTraits<Type>::zero;
00475
00476 forAll(f, i)
00477 {
00478 Sum += sum(f[i]);
00479 }
00480
00481 return Sum;
00482 }
00483 else
00484 {
00485 return pTraits<Type>::zero;
00486 }
00487 }
00488
00489 TMP_UNARY_FUNCTION(Type, sum)
00490
00491 template<template<class> class Field, class Type>
00492 scalar sumMag(const FieldField<Field, Type>& f)
00493 {
00494 if (f.size())
00495 {
00496 scalar SumMag = 0.0;
00497
00498 forAll(f, i)
00499 {
00500 SumMag += sumMag(f[i]);
00501 }
00502
00503 return SumMag;
00504 }
00505 else
00506 {
00507 return 0.0;
00508 }
00509 }
00510
00511 TMP_UNARY_FUNCTION(scalar, sumMag)
00512
00513 template<template<class> class Field, class Type>
00514 Type average(const FieldField<Field, Type>& f)
00515 {
00516 if (f.size())
00517 {
00518 label n = 0;
00519
00520 forAll(f, i)
00521 {
00522 n += f[i].size();
00523 }
00524
00525 if (n == 0)
00526 {
00527 WarningIn("average(const FieldField<Field, Type>&) const")
00528 << "empty fieldField, returning zero" << endl;
00529
00530 return pTraits<Type>::zero;
00531 }
00532
00533 Type avrg = sum(f)/n;
00534
00535 return avrg;
00536 }
00537 else
00538 {
00539 WarningIn("average(const FieldField<Field, Type>&) const")
00540 << "empty fieldField, returning zero" << endl;
00541
00542 return pTraits<Type>::zero;
00543 }
00544 }
00545
00546 TMP_UNARY_FUNCTION(Type, average)
00547
00548
00549 #include <OpenFOAM/PstreamReduceOps.H>
00550
00551 #define G_UNARY_FUNCTION(returnType, gFunc, func, rFunc) \
00552 \
00553 template<template<class> class Field, class Type> \
00554 returnType gFunc(const FieldField<Field, Type>& f) \
00555 { \
00556 returnType res = func(f); \
00557 reduce(res, rFunc##Op<Type>()); \
00558 return res; \
00559 } \
00560 TMP_UNARY_FUNCTION(returnType, gFunc)
00561
00562 G_UNARY_FUNCTION(Type, gMax, max, max)
00563 G_UNARY_FUNCTION(Type, gMin, min, min)
00564 G_UNARY_FUNCTION(Type, gSum, sum, sum)
00565 G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
00566
00567 #undef G_UNARY_FUNCTION
00568
00569
00570 template<template<class> class Field, class Type>
00571 Type gAverage(const FieldField<Field, Type>& f)
00572 {
00573 label n = 0;
00574
00575 forAll(f, i)
00576 {
00577 n += f[i].size();
00578 }
00579
00580 reduce(n, sumOp<label>());
00581
00582 if (n > 0)
00583 {
00584 Type avrg = gSum(f)/n;
00585
00586 return avrg;
00587 }
00588 else
00589 {
00590 WarningIn("gAverage(const FieldField<Field, Type>&) const")
00591 << "empty fieldField, returning zero" << endl;
00592
00593 return pTraits<Type>::zero;
00594 }
00595 }
00596
00597 TMP_UNARY_FUNCTION(Type, gAverage)
00598
00599 #undef TMP_UNARY_FUNCTION
00600
00601
00602 BINARY_FUNCTION(Type, Type, Type, max)
00603 BINARY_FUNCTION(Type, Type, Type, min)
00604 BINARY_FUNCTION(Type, Type, Type, cmptMultiply)
00605 BINARY_FUNCTION(Type, Type, Type, cmptDivide)
00606
00607 BINARY_TYPE_FUNCTION(Type, Type, Type, max)
00608 BINARY_TYPE_FUNCTION(Type, Type, Type, min)
00609 BINARY_TYPE_FUNCTION(Type, Type, Type, cmptMultiply)
00610 BINARY_TYPE_FUNCTION(Type, Type, Type, cmptDivide)
00611
00612
00613
00614
00615 UNARY_OPERATOR(Type, Type, -, negate)
00616
00617 #ifndef __INTEL_COMPILER
00618 BINARY_OPERATOR(Type, Type, scalar, *, multiply)
00619 BINARY_OPERATOR(Type, scalar, Type, *, multiply)
00620 #endif
00621 BINARY_OPERATOR(Type, Type, scalar, /, divide)
00622
00623 BINARY_TYPE_OPERATOR_SF(Type, scalar, Type, *, multiply)
00624 BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, *, multiply)
00625
00626 BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, /, divide)
00627
00628
00629
00630
00631 #define PRODUCT_OPERATOR(product, op, opFunc) \
00632 \
00633 template<template<class> class Field, class Type1, class Type2> \
00634 void opFunc \
00635 ( \
00636 FieldField<Field, typename product<Type1, Type2>::type>& f, \
00637 const FieldField<Field, Type1>& f1, \
00638 const FieldField<Field, Type2>& f2 \
00639 ) \
00640 { \
00641 forAll(f, i) \
00642 { \
00643 opFunc(f[i], f1[i], f2[i]); \
00644 } \
00645 } \
00646 \
00647 template<template<class> class Field, class Type1, class Type2> \
00648 tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
00649 operator op \
00650 ( \
00651 const FieldField<Field, Type1>& f1, \
00652 const FieldField<Field, Type2>& f2 \
00653 ) \
00654 { \
00655 typedef typename product<Type1, Type2>::type productType; \
00656 tmp<FieldField<Field, productType> > tRes \
00657 ( \
00658 FieldField<Field, productType>::NewCalculatedType(f1) \
00659 ); \
00660 opFunc(tRes(), f1, f2); \
00661 return tRes; \
00662 } \
00663 \
00664 template<template<class> class Field, class Type1, class Type2> \
00665 tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
00666 operator op \
00667 ( \
00668 const FieldField<Field, Type1>& f1, \
00669 const tmp<FieldField<Field, Type2> >& tf2 \
00670 ) \
00671 { \
00672 typedef typename product<Type1, Type2>::type productType; \
00673 tmp<FieldField<Field, productType> > tRes \
00674 ( \
00675 reuseTmpFieldField<Field, productType, Type2>::New(tf2) \
00676 ); \
00677 opFunc(tRes(), f1, tf2()); \
00678 reuseTmpFieldField<Field, productType, Type2>::clear(tf2); \
00679 return tRes; \
00680 } \
00681 \
00682 template<template<class> class Field, class Type1, class Type2> \
00683 tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
00684 operator op \
00685 ( \
00686 const tmp<FieldField<Field, Type1> >& tf1, \
00687 const FieldField<Field, Type2>& f2 \
00688 ) \
00689 { \
00690 typedef typename product<Type1, Type2>::type productType; \
00691 tmp<FieldField<Field, productType> > tRes \
00692 ( \
00693 reuseTmpFieldField<Field, productType, Type1>::New(tf1) \
00694 ); \
00695 opFunc(tRes(), tf1(), f2); \
00696 reuseTmpFieldField<Field, productType, Type1>::clear(tf1); \
00697 return tRes; \
00698 } \
00699 \
00700 template<template<class> class Field, class Type1, class Type2> \
00701 tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
00702 operator op \
00703 ( \
00704 const tmp<FieldField<Field, Type1> >& tf1, \
00705 const tmp<FieldField<Field, Type2> >& tf2 \
00706 ) \
00707 { \
00708 typedef typename product<Type1, Type2>::type productType; \
00709 tmp<FieldField<Field, productType> > tRes \
00710 ( \
00711 reuseTmpTmpFieldField<Field, productType, Type1, Type1, Type2>::New \
00712 (tf1, tf2) \
00713 ); \
00714 opFunc(tRes(), tf1(), tf2()); \
00715 reuseTmpTmpFieldField<Field, productType, Type1, Type1, Type2>::clear \
00716 (tf1, tf2); \
00717 return tRes; \
00718 } \
00719 \
00720 template \
00721 <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
00722 void opFunc \
00723 ( \
00724 FieldField<Field, typename product<Type, Form>::type>& f, \
00725 const FieldField<Field, Type>& f1, \
00726 const VectorSpace<Form,Cmpt,nCmpt>& vs \
00727 ) \
00728 { \
00729 forAll(f, i) \
00730 { \
00731 opFunc(f[i], f1[i], vs); \
00732 } \
00733 } \
00734 \
00735 template \
00736 <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
00737 tmp<FieldField<Field, typename product<Type, Form>::type> > \
00738 operator op \
00739 ( \
00740 const FieldField<Field, Type>& f1, \
00741 const VectorSpace<Form,Cmpt,nCmpt>& vs \
00742 ) \
00743 { \
00744 typedef typename product<Type, Form>::type productType; \
00745 tmp<FieldField<Field, productType> > tRes \
00746 ( \
00747 FieldField<Field, productType>::NewCalculatedType(f1) \
00748 ); \
00749 opFunc(tRes(), f1, static_cast<const Form&>(vs)); \
00750 return tRes; \
00751 } \
00752 \
00753 template \
00754 <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
00755 tmp<FieldField<Field, typename product<Type, Form>::type> > \
00756 operator op \
00757 ( \
00758 const tmp<FieldField<Field, Type> >& tf1, \
00759 const VectorSpace<Form,Cmpt,nCmpt>& vs \
00760 ) \
00761 { \
00762 typedef typename product<Type, Form>::type productType; \
00763 tmp<FieldField<Field, productType> > tRes \
00764 ( \
00765 reuseTmpFieldField<Field, productType, Type>::New(tf1) \
00766 ); \
00767 opFunc(tRes(), tf1(), static_cast<const Form&>(vs)); \
00768 reuseTmpFieldField<Field, productType, Type>::clear(tf1); \
00769 return tRes; \
00770 } \
00771 \
00772 template \
00773 <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
00774 void opFunc \
00775 ( \
00776 FieldField<Field, typename product<Form, Type>::type>& f, \
00777 const VectorSpace<Form,Cmpt,nCmpt>& vs, \
00778 const FieldField<Field, Type>& f1 \
00779 ) \
00780 { \
00781 forAll(f, i) \
00782 { \
00783 opFunc(f[i], vs, f1[i]); \
00784 } \
00785 } \
00786 \
00787 template \
00788 <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
00789 tmp<FieldField<Field, typename product<Form, Type>::type> > \
00790 operator op \
00791 ( \
00792 const VectorSpace<Form,Cmpt,nCmpt>& vs, \
00793 const FieldField<Field, Type>& f1 \
00794 ) \
00795 { \
00796 typedef typename product<Form, Type>::type productType; \
00797 tmp<FieldField<Field, productType> > tRes \
00798 ( \
00799 FieldField<Field, productType>::NewCalculatedType(f1) \
00800 ); \
00801 opFunc(tRes(), static_cast<const Form&>(vs), f1); \
00802 return tRes; \
00803 } \
00804 \
00805 template \
00806 <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
00807 tmp<FieldField<Field, typename product<Form, Type>::type> > \
00808 operator op \
00809 ( \
00810 const VectorSpace<Form,Cmpt,nCmpt>& vs, \
00811 const tmp<FieldField<Field, Type> >& tf1 \
00812 ) \
00813 { \
00814 typedef typename product<Form, Type>::type productType; \
00815 tmp<FieldField<Field, productType> > tRes \
00816 ( \
00817 reuseTmpFieldField<Field, productType, Type>::New(tf1) \
00818 ); \
00819 opFunc(tRes(), static_cast<const Form&>(vs), tf1()); \
00820 reuseTmpFieldField<Field, productType, Type>::clear(tf1); \
00821 return tRes; \
00822 }
00823
00824 PRODUCT_OPERATOR(typeOfSum, +, add)
00825 PRODUCT_OPERATOR(typeOfSum, -, subtract)
00826
00827 PRODUCT_OPERATOR(outerProduct, *, outer)
00828 PRODUCT_OPERATOR(crossProduct, ^, cross)
00829 PRODUCT_OPERATOR(innerProduct, &, dot)
00830 PRODUCT_OPERATOR(scalarProduct, &&, dotdot)
00831
00832 #undef PRODUCT_OPERATOR
00833
00834
00835
00836
00837 }
00838
00839
00840
00841 #include <OpenFOAM/undefFieldFunctionsM.H>
00842
00843