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