OpenFOAM logo
Open Source CFD Toolkit

FieldM.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2005 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software; you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by the
00013     Free Software Foundation; either version 2 of the License, or (at your
00014     option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM; if not, write to the Free Software Foundation,
00023     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00024 
00025 Description
00026     High performance macro functions for Field<Type> algebra.  These expand
00027     using either array element access (for vector machines) or pointer
00028     dereferencing for scalar machines as appropriate.
00029 
00030 \*---------------------------------------------------------------------------*/
00031 
00032 #ifndef FieldM_H
00033 #define FieldM_H
00034 
00035 #include "error.H"
00036 #include "ListLoopM.H"
00037 
00038 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00039 
00040 namespace Foam
00041 {
00042 
00043 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00044 
00045 #ifdef FULLDEBUG
00046 
00047 template<class Type1, class Type2>
00048 void checkFields
00049 (
00050     const UList<Type1>& f1,
00051     const UList<Type2>& f2,
00052     const char* op
00053 )
00054 {
00055     if (f1.size() != f2.size())
00056     {
00057         FatalErrorIn
00058         (
00059             "checkFields(const UList<Type1>&, "
00060             "const UList<Type2>&, const char*)"
00061         )   << "    incompatible fields"
00062             << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
00063             << " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
00064             << endl << " for operation " << op
00065             << abort(FatalError);
00066     }
00067 }
00068 
00069 template<class Type1, class Type2, class Type3>
00070 void checkFields
00071 (
00072     const UList<Type1>& f1,
00073     const UList<Type2>& f2,
00074     const UList<Type3>& f3,
00075     const char* op
00076 )
00077 {
00078     if (f1.size() != f2.size() || f1.size() != f3.size())
00079     {
00080         FatalErrorIn
00081         (
00082             "checkFields(const UList<Type1>&, "
00083             "const UList<Type2>&, const UList<Type3>&, "
00084             "const char*)"
00085         )   << "    incompatible fields"
00086             << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
00087             << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
00088             << " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
00089             << endl << "    for operation " << op
00090             << abort(FatalError);
00091     }
00092 }
00093 
00094 #else
00095 
00096 template<class Type1, class Type2>
00097 void checkFields
00098 (
00099     const UList<Type1>&,
00100     const UList<Type2>&,
00101     const char*
00102 )
00103 {}
00104 
00105 template<class Type1, class Type2, class Type3>
00106 void checkFields
00107 (
00108     const UList<Type1>&,
00109     const UList<Type2>&,
00110     const UList<Type3>&,
00111     const char*
00112 )
00113 {}
00114 
00115 #endif
00116 
00117 
00118 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00119 
00120 // member function : this f1 OP fUNC f2
00121 
00122 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2)              \
00123                                                                             \
00124     /* check the two fields have same Field<Type> mesh */                   \
00125     checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)");                        \
00126                                                                             \
00127     /* set access to f1, f2 and f3 at end of each field */                  \
00128     List_ACCESS(typeF1, f1, f1P);                                           \
00129     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00130                                                                             \
00131     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00132     List_FOR_ALL(f1, i)                                                     \
00133         List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i));               \
00134     List_END_FOR_ALL                                                        \
00135 
00136 
00137 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC)              \
00138                                                                             \
00139     /* check the two fields have same Field<Type> mesh */                   \
00140     checkFields(f1, f2, "f1 " #OP " f2" #FUNC);                             \
00141                                                                             \
00142     /* set access to f1, f2 and f3 at end of each field */                  \
00143     List_ACCESS(typeF1, f1, f1P);                                           \
00144     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00145                                                                             \
00146     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00147     List_FOR_ALL(f1, i)                                                     \
00148         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i).FUNC();              \
00149     List_END_FOR_ALL                                                        \
00150 
00151 
00152 // member function : this field f1 OP fUNC f2, f3
00153 
00154 #define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3)\
00155                                                                             \
00156     /* check the three fields have same Field<Type> mesh */                 \
00157     checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)");                \
00158                                                                             \
00159     /* set access to f1, f2 and f3 at end of each field */                  \
00160     List_ACCESS(typeF1, f1, f1P);                                           \
00161     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00162     List_CONST_ACCESS(typeF3, f3, f3P);                                     \
00163                                                                             \
00164     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00165     List_FOR_ALL(f1, i)                                                     \
00166         List_ELEM(f1, f1P, i)                                               \
00167         OP FUNC(List_ELEM(f2, f2P, i), List_ELEM(f3, f3P, i));              \
00168     List_END_FOR_ALL                                                        \
00169 
00170 
00171 // member function : this f1 OP fUNC f2, s
00172 
00173 #define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s)  \
00174                                                                             \
00175     /* check the two fields have same Field<Type> mesh */                   \
00176     checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)");                     \
00177                                                                             \
00178     /* set access to f1, f2 and f3 at end of each field */                  \
00179     List_ACCESS(typeF1, f1, f1P);                                           \
00180     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00181                                                                             \
00182     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00183     List_FOR_ALL(f1, i)                                                     \
00184         List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i), (s));          \
00185     List_END_FOR_ALL
00186 
00187 
00188 // member function : s1 OP fUNC f, s2
00189 
00190 #define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2)  \
00191                                                                             \
00192     /* set access to f at end of field */                                   \
00193     List_CONST_ACCESS(typeF, f, fP);                                        \
00194                                                                             \
00195     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00196     List_FOR_ALL(f, i)                                                      \
00197         (s1) OP FUNC(List_ELEM(f, fP, i), (s2));                            \
00198     List_END_FOR_ALL                                                        \
00199 
00200 
00201 // member function : this f1 OP fUNC s, f2
00202 
00203 #define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2)  \
00204                                                                             \
00205     /* check the two fields have same Field<Type> mesh */                   \
00206     checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)");                     \
00207                                                                             \
00208     /* set access to f1, f2 and f3 at end of each field */                  \
00209     List_ACCESS(typeF1, f1, f1P);                                           \
00210     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00211                                                                             \
00212     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00213     List_FOR_ALL(f1, i)                                                     \
00214         List_ELEM(f1, f1P, i) OP FUNC((s), List_ELEM(f2, f2P, i));          \
00215     List_END_FOR_ALL                                                        \
00216 
00217 
00218 // member function : this f1 OP1 f2 OP2 FUNC s
00219 
00220 #define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s)  \
00221                                                                             \
00222     /* check the two fields have same Field<Type> mesh */                   \
00223     checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)");                      \
00224                                                                             \
00225     /* set access to f1, f2 and f3 at end of each field */                  \
00226     List_ACCESS(typeF1, f1, f1P);                                           \
00227     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00228                                                                             \
00229     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00230     List_FOR_ALL(f1, i)                                                     \
00231         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i) FUNC((s));           \
00232     List_END_FOR_ALL                                                        \
00233 
00234 
00235 // define high performance macro functions for Field<Type> operations
00236 
00237 // member operator : this field f1 OP1 f2 OP2 f3
00238 
00239 #define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3)  \
00240                                                                             \
00241     /* check the three fields have same Field<Type> mesh */                 \
00242     checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3");                  \
00243                                                                             \
00244     /* set access to f1, f2 and f3 at end of each field */                  \
00245     List_ACCESS(typeF1, f1, f1P);                                           \
00246     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00247     List_CONST_ACCESS(typeF3, f3, f3P);                                     \
00248                                                                             \
00249     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
00250     List_FOR_ALL(f1, i)                                                     \
00251         List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i)                     \
00252                               OP2 List_ELEM(f3, f3P, i);                    \
00253     List_END_FOR_ALL                                                        \
00254 
00255 
00256 // member operator : this field f1 OP1 s OP2 f2
00257 
00258 #define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2)    \
00259                                                                             \
00260     /* check the two fields have same Field<Type> mesh */                   \
00261     checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2");                       \
00262                                                                             \
00263     /* set access to f1 and f2 at end of each field */                      \
00264     List_ACCESS(typeF1, f1, f1P);                                           \
00265     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00266                                                                             \
00267     /* loop through fields performing f1 OP1 s OP2 f2 */                    \
00268     List_FOR_ALL(f1, i)                                                     \
00269         List_ELEM(f1, f1P, i) OP1 (s) OP2 List_ELEM(f2, f2P, i);            \
00270     List_END_FOR_ALL                                                        \
00271 
00272 
00273 // member operator : this field f1 OP1 f2 OP2 s
00274 
00275 #define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s)    \
00276                                                                             \
00277     /* check the two fields have same Field<Type> mesh */                   \
00278     checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s");                       \
00279                                                                             \
00280     /* set access to f1 and f2 at end of each field */                      \
00281     List_ACCESS(typeF1, f1, f1P);                                           \
00282     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00283                                                                             \
00284     /* loop through fields performing f1 OP1 s OP2 f2 */                    \
00285     List_FOR_ALL(f1, i)                                                     \
00286         List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) OP2 (s);            \
00287     List_END_FOR_ALL                                                        \
00288 
00289 
00290 // member operator : this field f1 OP f2
00291 
00292 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2)                         \
00293                                                                             \
00294     /* check the two fields have same Field<Type> mesh */                   \
00295     checkFields(f1, f2, "f1 " #OP " f2");                                   \
00296                                                                             \
00297     /* set pointer to f1P at end of f1 and */                               \
00298     /* f2.p at end of f2 */                                                 \
00299     List_ACCESS(typeF1, f1, f1P);                                           \
00300     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00301                                                                             \
00302     /* loop through fields performing f1 OP f2 */                           \
00303     List_FOR_ALL(f1, i)                                                     \
00304         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i);                     \
00305     List_END_FOR_ALL                                                        \
00306 
00307 // member operator : this field f1 OP1 OP2 f2
00308 
00309 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2)                \
00310                                                                             \
00311     /* check the two fields have same Field<Type> mesh */                   \
00312     checkFields(f1, f2, #OP1 " " #OP2 " f2");                               \
00313                                                                             \
00314     /* set pointer to f1P at end of f1 and */                               \
00315     /* f2.p at end of f2 */                                                 \
00316     List_ACCESS(typeF1, f1, f1P);                                           \
00317     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00318                                                                             \
00319     /* loop through fields performing f1 OP1 OP2 f2 */                      \
00320     List_FOR_ALL(f1, i)                                                     \
00321         List_ELEM(f1, f1P, i) OP1 OP2 List_ELEM(f2, f2P, i);                \
00322     List_END_FOR_ALL                                                        \
00323 
00324 
00325 // member operator : this field f OP s
00326 
00327 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s)                             \
00328                                                                             \
00329     /* set access to f at end of field */                                   \
00330     List_ACCESS(typeF, f, fP);                                              \
00331                                                                             \
00332     /* loop through field performing f OP s */                              \
00333     List_FOR_ALL(f, i)                                                      \
00334         List_ELEM(f, fP, i) OP (s);                                         \
00335     List_END_FOR_ALL                                                        \
00336 
00337 
00338 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00339 // define high performance macro functions for Field<Type> friend functions
00340 
00341 // friend operator function : s OP f, allocates storage for s
00342 
00343 #define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f)                             \
00344                                                                             \
00345     /* set access to f at end of field */                                   \
00346     List_CONST_ACCESS(typeF, f, fP);                                        \
00347                                                                             \
00348     /* loop through field performing s OP f */                              \
00349     List_FOR_ALL(f, i)                                                      \
00350         (s) OP List_ELEM(f, fP, i);                                         \
00351     List_END_FOR_ALL
00352 
00353 
00354 // friend operator function : s OP1 f1 OP2 f2, allocates storage for s
00355 
00356 #define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2)    \
00357                                                                             \
00358     /* set access to f1 and f2 at end of each field */                      \
00359     List_CONST_ACCESS(typeF1, f1, f1P);                                     \
00360     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
00361                                                                             \
00362     /* loop through field performing s OP f */                              \
00363     List_FOR_ALL(f1, i)                                                     \
00364         (s) OP1 List_ELEM(f1, f1P, i) OP2 List_ELEM(f2, f2P, i);            \
00365     List_END_FOR_ALL
00366 
00367 
00368 // friend operator function : s OP FUNC(f), allocates storage for s
00369 
00370 #define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f)                  \
00371                                                                             \
00372     /* set access to f at end of field */                                   \
00373     List_CONST_ACCESS(typeF, f, fP);                                        \
00374                                                                             \
00375     /* loop through field performing s OP f */                              \
00376     List_FOR_ALL(f, i)                                                      \
00377         (s) OP FUNC(List_ELEM(f, fP, i));                                   \
00378     List_END_FOR_ALL
00379 
00380 
00381 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00382 
00383 } // End namespace Foam
00384 
00385 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00386 
00387 #endif
00388 
00389 // ************************************************************************* //
For further information go to www.openfoam.org