initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / fields / Fields / Field / FieldM.H
blob80e7507d588b7fe06d5584cf045e2e65b730a6fd
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
26     High performance macro functions for Field\<Type\> algebra.  These expand
27     using either array element access (for vector machines) or pointer
28     dereferencing for scalar machines as appropriate.
30 \*---------------------------------------------------------------------------*/
32 #ifndef FieldM_H
33 #define FieldM_H
35 #include "error.H"
36 #include "ListLoopM.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 namespace Foam
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 #ifdef FULLDEBUG
47 template<class Type1, class Type2>
48 void checkFields
50     const UList<Type1>& f1,
51     const UList<Type2>& f2,
52     const char* op
55     if (f1.size() != f2.size())
56     {
57         FatalErrorIn
58         (
59             "checkFields(const UList<Type1>&, "
60             "const UList<Type2>&, const char*)"
61         )   << "    incompatible fields"
62             << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
63             << " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
64             << endl << " for operation " << op
65             << abort(FatalError);
66     }
69 template<class Type1, class Type2, class Type3>
70 void checkFields
72     const UList<Type1>& f1,
73     const UList<Type2>& f2,
74     const UList<Type3>& f3,
75     const char* op
78     if (f1.size() != f2.size() || f1.size() != f3.size())
79     {
80         FatalErrorIn
81         (
82             "checkFields(const UList<Type1>&, "
83             "const UList<Type2>&, const UList<Type3>&, "
84             "const char*)"
85         )   << "    incompatible fields"
86             << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
87             << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
88             << " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
89             << endl << "    for operation " << op
90             << abort(FatalError);
91     }
94 #else
96 template<class Type1, class Type2>
97 void checkFields
99     const UList<Type1>&,
100     const UList<Type2>&,
101     const char*
105 template<class Type1, class Type2, class Type3>
106 void checkFields
108     const UList<Type1>&,
109     const UList<Type2>&,
110     const UList<Type3>&,
111     const char*
115 #endif
118 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
120 // member function : this f1 OP fUNC f2
122 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2)              \
123                                                                             \
124     /* check the two fields have same Field<Type> mesh */                   \
125     checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)");                        \
126                                                                             \
127     /* set access to f1, f2 and f3 at end of each field */                  \
128     List_ACCESS(typeF1, f1, f1P);                                           \
129     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
130                                                                             \
131     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
132     List_FOR_ALL(f1, i)                                                     \
133         List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i));               \
134     List_END_FOR_ALL                                                        \
137 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC)              \
138                                                                             \
139     /* check the two fields have same Field<Type> mesh */                   \
140     checkFields(f1, f2, "f1 " #OP " f2" #FUNC);                             \
141                                                                             \
142     /* set access to f1, f2 and f3 at end of each field */                  \
143     List_ACCESS(typeF1, f1, f1P);                                           \
144     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
145                                                                             \
146     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
147     List_FOR_ALL(f1, i)                                                     \
148         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i).FUNC();              \
149     List_END_FOR_ALL                                                        \
152 // member function : this field f1 OP fUNC f2, f3
154 #define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3)\
155                                                                             \
156     /* check the three fields have same Field<Type> mesh */                 \
157     checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)");                \
158                                                                             \
159     /* set access to f1, f2 and f3 at end of each field */                  \
160     List_ACCESS(typeF1, f1, f1P);                                           \
161     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
162     List_CONST_ACCESS(typeF3, f3, f3P);                                     \
163                                                                             \
164     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
165     List_FOR_ALL(f1, i)                                                     \
166         List_ELEM(f1, f1P, i)                                               \
167         OP FUNC(List_ELEM(f2, f2P, i), List_ELEM(f3, f3P, i));              \
168     List_END_FOR_ALL                                                        \
171 // member function : this field f1 OP fUNC f2, f3
173 #define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2)  \
174                                                                             \
175     /* check the two fields have same Field<Type> mesh */                   \
176     checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)");                     \
177                                                                             \
178     /* set access to f1 and f2 at end of each field */                      \
179     List_CONST_ACCESS(typeF1, f1, f1P);                                     \
180     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
181                                                                             \
182     /* loop through fields performing s OP FUNC(f1, f2) */                  \
183     List_FOR_ALL(f1, i)                                                     \
184         (s) OP FUNC(List_ELEM(f1, f1P, i), List_ELEM(f2, f2P, i));          \
185     List_END_FOR_ALL                                                        \
188 // member function : this f1 OP fUNC f2, s
190 #define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s)  \
191                                                                             \
192     /* check the two fields have same Field<Type> mesh */                   \
193     checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)");                     \
194                                                                             \
195     /* set access to f1, f2 and f3 at end of each field */                  \
196     List_ACCESS(typeF1, f1, f1P);                                           \
197     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
198                                                                             \
199     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
200     List_FOR_ALL(f1, i)                                                     \
201         List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i), (s));          \
202     List_END_FOR_ALL
205 // member function : s1 OP fUNC f, s2
207 #define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2)  \
208                                                                             \
209     /* set access to f at end of field */                                   \
210     List_CONST_ACCESS(typeF, f, fP);                                        \
211                                                                             \
212     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
213     List_FOR_ALL(f, i)                                                      \
214         (s1) OP FUNC(List_ELEM(f, fP, i), (s2));                            \
215     List_END_FOR_ALL                                                        \
218 // member function : this f1 OP fUNC s, f2
220 #define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2)  \
221                                                                             \
222     /* check the two fields have same Field<Type> mesh */                   \
223     checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)");                     \
224                                                                             \
225     /* set access to f1, f2 and f3 at end of each field */                  \
226     List_ACCESS(typeF1, f1, f1P);                                           \
227     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
228                                                                             \
229     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
230     List_FOR_ALL(f1, i)                                                     \
231         List_ELEM(f1, f1P, i) OP FUNC((s), List_ELEM(f2, f2P, i));          \
232     List_END_FOR_ALL                                                        \
235 // member function : this f1 OP fUNC s, f2
237 #define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)\
238                                                                             \
239     /* set access to f1 at end of field */                                  \
240     List_ACCESS(typeF1, f1, f1P);                                           \
241                                                                             \
242     /* loop through fields performing f1 OP1 FUNC(s1, s2) */                \
243     List_FOR_ALL(f1, i)                                                     \
244         List_ELEM(f1, f1P, i) OP FUNC((s1), (s2));                          \
245     List_END_FOR_ALL                                                        \
248 // member function : this f1 OP1 f2 OP2 FUNC s
250 #define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s)  \
251                                                                             \
252     /* check the two fields have same Field<Type> mesh */                   \
253     checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)");                      \
254                                                                             \
255     /* set access to f1, f2 and f3 at end of each field */                  \
256     List_ACCESS(typeF1, f1, f1P);                                           \
257     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
258                                                                             \
259     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
260     List_FOR_ALL(f1, i)                                                     \
261         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i) FUNC((s));           \
262     List_END_FOR_ALL                                                        \
265 // define high performance macro functions for Field<Type> operations
267 // member operator : this field f1 OP1 f2 OP2 f3
269 #define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3)  \
270                                                                             \
271     /* check the three fields have same Field<Type> mesh */                 \
272     checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3");                  \
273                                                                             \
274     /* set access to f1, f2 and f3 at end of each field */                  \
275     List_ACCESS(typeF1, f1, f1P);                                           \
276     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
277     List_CONST_ACCESS(typeF3, f3, f3P);                                     \
278                                                                             \
279     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
280     List_FOR_ALL(f1, i)                                                     \
281         List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i)                     \
282                               OP2 List_ELEM(f3, f3P, i);                    \
283     List_END_FOR_ALL                                                        \
286 // member operator : this field f1 OP1 s OP2 f2
288 #define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2)    \
289                                                                             \
290     /* check the two fields have same Field<Type> mesh */                   \
291     checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2");                       \
292                                                                             \
293     /* set access to f1 and f2 at end of each field */                      \
294     List_ACCESS(typeF1, f1, f1P);                                           \
295     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
296                                                                             \
297     /* loop through fields performing f1 OP1 s OP2 f2 */                    \
298     List_FOR_ALL(f1, i)                                                     \
299         List_ELEM(f1, f1P, i) OP1 (s) OP2 List_ELEM(f2, f2P, i);            \
300     List_END_FOR_ALL                                                        \
303 // member operator : this field f1 OP1 f2 OP2 s
305 #define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s)    \
306                                                                             \
307     /* check the two fields have same Field<Type> mesh */                   \
308     checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s");                       \
309                                                                             \
310     /* set access to f1 and f2 at end of each field */                      \
311     List_ACCESS(typeF1, f1, f1P);                                           \
312     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
313                                                                             \
314     /* loop through fields performing f1 OP1 s OP2 f2 */                    \
315     List_FOR_ALL(f1, i)                                                     \
316         List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) OP2 (s);            \
317     List_END_FOR_ALL                                                        \
320 // member operator : this field f1 OP f2
322 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2)                         \
323                                                                             \
324     /* check the two fields have same Field<Type> mesh */                   \
325     checkFields(f1, f2, "f1 " #OP " f2");                                   \
326                                                                             \
327     /* set pointer to f1P at end of f1 and */                               \
328     /* f2.p at end of f2 */                                                 \
329     List_ACCESS(typeF1, f1, f1P);                                           \
330     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
331                                                                             \
332     /* loop through fields performing f1 OP f2 */                           \
333     List_FOR_ALL(f1, i)                                                     \
334         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i);                     \
335     List_END_FOR_ALL                                                        \
337 // member operator : this field f1 OP1 OP2 f2
339 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2)                \
340                                                                             \
341     /* check the two fields have same Field<Type> mesh */                   \
342     checkFields(f1, f2, #OP1 " " #OP2 " f2");                               \
343                                                                             \
344     /* set pointer to f1P at end of f1 and */                               \
345     /* f2.p at end of f2 */                                                 \
346     List_ACCESS(typeF1, f1, f1P);                                           \
347     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
348                                                                             \
349     /* loop through fields performing f1 OP1 OP2 f2 */                      \
350     List_FOR_ALL(f1, i)                                                     \
351         List_ELEM(f1, f1P, i) OP1 OP2 List_ELEM(f2, f2P, i);                \
352     List_END_FOR_ALL                                                        \
355 // member operator : this field f OP s
357 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s)                             \
358                                                                             \
359     /* set access to f at end of field */                                   \
360     List_ACCESS(typeF, f, fP);                                              \
361                                                                             \
362     /* loop through field performing f OP s */                              \
363     List_FOR_ALL(f, i)                                                      \
364         List_ELEM(f, fP, i) OP (s);                                         \
365     List_END_FOR_ALL                                                        \
368 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
369 // define high performance macro functions for Field<Type> friend functions
371 // friend operator function : s OP f, allocates storage for s
373 #define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f)                             \
374                                                                             \
375     /* set access to f at end of field */                                   \
376     List_CONST_ACCESS(typeF, f, fP);                                        \
377                                                                             \
378     /* loop through field performing s OP f */                              \
379     List_FOR_ALL(f, i)                                                      \
380         (s) OP List_ELEM(f, fP, i);                                         \
381     List_END_FOR_ALL
384 // friend operator function : s OP1 f1 OP2 f2, allocates storage for s
386 #define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2)    \
387                                                                             \
388     /* set access to f1 and f2 at end of each field */                      \
389     List_CONST_ACCESS(typeF1, f1, f1P);                                     \
390     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
391                                                                             \
392     /* loop through field performing s OP f */                              \
393     List_FOR_ALL(f1, i)                                                     \
394         (s) OP1 List_ELEM(f1, f1P, i) OP2 List_ELEM(f2, f2P, i);            \
395     List_END_FOR_ALL
398 // friend operator function : s OP FUNC(f), allocates storage for s
400 #define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f)                  \
401                                                                             \
402     /* set access to f at end of field */                                   \
403     List_CONST_ACCESS(typeF, f, fP);                                        \
404                                                                             \
405     /* loop through field performing s OP f */                              \
406     List_FOR_ALL(f, i)                                                      \
407         (s) OP FUNC(List_ELEM(f, fP, i));                                   \
408     List_END_FOR_ALL
411 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
413 } // End namespace Foam
415 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
417 #endif
419 // ************************************************************************* //