ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / OpenFOAM / fields / Fields / Field / FieldM.H
blobd44d72506afd6cccc641b4e1e8d24c8c74644435
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 Description
25     High performance macro functions for Field\<Type\> algebra.  These expand
26     using either array element access (for vector machines) or pointer
27     dereferencing for scalar machines as appropriate.
29 \*---------------------------------------------------------------------------*/
31 #ifndef FieldM_H
32 #define FieldM_H
34 #include "error.H"
35 #include "ListLoopM.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 namespace Foam
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 #ifdef FULLDEBUG
46 template<class Type1, class Type2>
47 void checkFields
49     const UList<Type1>& f1,
50     const UList<Type2>& f2,
51     const char* op
54     if (f1.size() != f2.size())
55     {
56         FatalErrorIn
57         (
58             "checkFields(const UList<Type1>&, "
59             "const UList<Type2>&, const char*)"
60         )   << "    incompatible fields"
61             << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
62             << " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
63             << endl << " for operation " << op
64             << abort(FatalError);
65     }
68 template<class Type1, class Type2, class Type3>
69 void checkFields
71     const UList<Type1>& f1,
72     const UList<Type2>& f2,
73     const UList<Type3>& f3,
74     const char* op
77     if (f1.size() != f2.size() || f1.size() != f3.size())
78     {
79         FatalErrorIn
80         (
81             "checkFields(const UList<Type1>&, "
82             "const UList<Type2>&, const UList<Type3>&, "
83             "const char*)"
84         )   << "    incompatible fields"
85             << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
86             << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
87             << " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
88             << endl << "    for operation " << op
89             << abort(FatalError);
90     }
93 #else
95 template<class Type1, class Type2>
96 void checkFields
98     const UList<Type1>&,
99     const UList<Type2>&,
100     const char*
104 template<class Type1, class Type2, class Type3>
105 void checkFields
107     const UList<Type1>&,
108     const UList<Type2>&,
109     const UList<Type3>&,
110     const char*
114 #endif
117 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
119 // member function : this f1 OP fUNC f2
121 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2)              \
122                                                                             \
123     /* check the two fields have same Field<Type> mesh */                   \
124     checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)");                        \
125                                                                             \
126     /* set access to f1, f2 and f3 at end of each field */                  \
127     List_ACCESS(typeF1, f1, f1P);                                           \
128     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
129                                                                             \
130     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
131     List_FOR_ALL(f1, i)                                                     \
132         List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i));               \
133     List_END_FOR_ALL                                                        \
136 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC)              \
137                                                                             \
138     /* check the two fields have same Field<Type> mesh */                   \
139     checkFields(f1, f2, "f1 " #OP " f2" #FUNC);                             \
140                                                                             \
141     /* set access to f1, f2 and f3 at end of each field */                  \
142     List_ACCESS(typeF1, f1, f1P);                                           \
143     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
144                                                                             \
145     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
146     List_FOR_ALL(f1, i)                                                     \
147         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i).FUNC();              \
148     List_END_FOR_ALL                                                        \
151 // member function : this field f1 OP fUNC f2, f3
153 #define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3)\
154                                                                             \
155     /* check the three fields have same Field<Type> mesh */                 \
156     checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)");                \
157                                                                             \
158     /* set access to f1, f2 and f3 at end of each field */                  \
159     List_ACCESS(typeF1, f1, f1P);                                           \
160     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
161     List_CONST_ACCESS(typeF3, f3, f3P);                                     \
162                                                                             \
163     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
164     List_FOR_ALL(f1, i)                                                     \
165         List_ELEM(f1, f1P, i)                                               \
166         OP FUNC(List_ELEM(f2, f2P, i), List_ELEM(f3, f3P, i));              \
167     List_END_FOR_ALL                                                        \
170 // member function : this field f1 OP fUNC f2, f3
172 #define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2)  \
173                                                                             \
174     /* check the two fields have same Field<Type> mesh */                   \
175     checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)");                     \
176                                                                             \
177     /* set access to f1 and f2 at end of each field */                      \
178     List_CONST_ACCESS(typeF1, f1, f1P);                                     \
179     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
180                                                                             \
181     /* loop through fields performing s OP FUNC(f1, f2) */                  \
182     List_FOR_ALL(f1, i)                                                     \
183         (s) OP FUNC(List_ELEM(f1, f1P, i), List_ELEM(f2, f2P, i));          \
184     List_END_FOR_ALL                                                        \
187 // member function : this f1 OP fUNC f2, s
189 #define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s)  \
190                                                                             \
191     /* check the two fields have same Field<Type> mesh */                   \
192     checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)");                     \
193                                                                             \
194     /* set access to f1, f2 and f3 at end of each field */                  \
195     List_ACCESS(typeF1, f1, f1P);                                           \
196     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
197                                                                             \
198     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
199     List_FOR_ALL(f1, i)                                                     \
200         List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i), (s));          \
201     List_END_FOR_ALL
204 // member function : s1 OP fUNC f, s2
206 #define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2)  \
207                                                                             \
208     /* set access to f at end of field */                                   \
209     List_CONST_ACCESS(typeF, f, fP);                                        \
210                                                                             \
211     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
212     List_FOR_ALL(f, i)                                                      \
213         (s1) OP FUNC(List_ELEM(f, fP, i), (s2));                            \
214     List_END_FOR_ALL                                                        \
217 // member function : this f1 OP fUNC s, f2
219 #define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2)  \
220                                                                             \
221     /* check the two fields have same Field<Type> mesh */                   \
222     checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)");                     \
223                                                                             \
224     /* set access to f1, f2 and f3 at end of each field */                  \
225     List_ACCESS(typeF1, f1, f1P);                                           \
226     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
227                                                                             \
228     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
229     List_FOR_ALL(f1, i)                                                     \
230         List_ELEM(f1, f1P, i) OP FUNC((s), List_ELEM(f2, f2P, i));          \
231     List_END_FOR_ALL                                                        \
234 // member function : this f1 OP fUNC s, f2
236 #define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)\
237                                                                             \
238     /* set access to f1 at end of field */                                  \
239     List_ACCESS(typeF1, f1, f1P);                                           \
240                                                                             \
241     /* loop through fields performing f1 OP1 FUNC(s1, s2) */                \
242     List_FOR_ALL(f1, i)                                                     \
243         List_ELEM(f1, f1P, i) OP FUNC((s1), (s2));                          \
244     List_END_FOR_ALL                                                        \
247 // member function : this f1 OP1 f2 OP2 FUNC s
249 #define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s)  \
250                                                                             \
251     /* check the two fields have same Field<Type> mesh */                   \
252     checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)");                      \
253                                                                             \
254     /* set access to f1, f2 and f3 at end of each field */                  \
255     List_ACCESS(typeF1, f1, f1P);                                           \
256     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
257                                                                             \
258     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
259     List_FOR_ALL(f1, i)                                                     \
260         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i) FUNC((s));           \
261     List_END_FOR_ALL                                                        \
264 // define high performance macro functions for Field<Type> operations
266 // member operator : this field f1 OP1 f2 OP2 f3
268 #define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3)  \
269                                                                             \
270     /* check the three fields have same Field<Type> mesh */                 \
271     checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3");                  \
272                                                                             \
273     /* set access to f1, f2 and f3 at end of each field */                  \
274     List_ACCESS(typeF1, f1, f1P);                                           \
275     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
276     List_CONST_ACCESS(typeF3, f3, f3P);                                     \
277                                                                             \
278     /* loop through fields performing f1 OP1 f2 OP2 f3 */                   \
279     List_FOR_ALL(f1, i)                                                     \
280         List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i)                     \
281                               OP2 List_ELEM(f3, f3P, i);                    \
282     List_END_FOR_ALL                                                        \
285 // member operator : this field f1 OP1 s OP2 f2
287 #define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2)    \
288                                                                             \
289     /* check the two fields have same Field<Type> mesh */                   \
290     checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2");                       \
291                                                                             \
292     /* set access to f1 and f2 at end of each field */                      \
293     List_ACCESS(typeF1, f1, f1P);                                           \
294     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
295                                                                             \
296     /* loop through fields performing f1 OP1 s OP2 f2 */                    \
297     List_FOR_ALL(f1, i)                                                     \
298         List_ELEM(f1, f1P, i) OP1 (s) OP2 List_ELEM(f2, f2P, i);            \
299     List_END_FOR_ALL                                                        \
302 // member operator : this field f1 OP1 f2 OP2 s
304 #define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s)    \
305                                                                             \
306     /* check the two fields have same Field<Type> mesh */                   \
307     checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s");                       \
308                                                                             \
309     /* set access to f1 and f2 at end of each field */                      \
310     List_ACCESS(typeF1, f1, f1P);                                           \
311     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
312                                                                             \
313     /* loop through fields performing f1 OP1 s OP2 f2 */                    \
314     List_FOR_ALL(f1, i)                                                     \
315         List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) OP2 (s);            \
316     List_END_FOR_ALL                                                        \
319 // member operator : this field f1 OP f2
321 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2)                         \
322                                                                             \
323     /* check the two fields have same Field<Type> mesh */                   \
324     checkFields(f1, f2, "f1 " #OP " f2");                                   \
325                                                                             \
326     /* set pointer to f1P at end of f1 and */                               \
327     /* f2.p at end of f2 */                                                 \
328     List_ACCESS(typeF1, f1, f1P);                                           \
329     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
330                                                                             \
331     /* loop through fields performing f1 OP f2 */                           \
332     List_FOR_ALL(f1, i)                                                     \
333         List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i);                     \
334     List_END_FOR_ALL                                                        \
336 // member operator : this field f1 OP1 OP2 f2
338 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2)                \
339                                                                             \
340     /* check the two fields have same Field<Type> mesh */                   \
341     checkFields(f1, f2, #OP1 " " #OP2 " f2");                               \
342                                                                             \
343     /* set pointer to f1P at end of f1 and */                               \
344     /* f2.p at end of f2 */                                                 \
345     List_ACCESS(typeF1, f1, f1P);                                           \
346     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
347                                                                             \
348     /* loop through fields performing f1 OP1 OP2 f2 */                      \
349     List_FOR_ALL(f1, i)                                                     \
350         List_ELEM(f1, f1P, i) OP1 OP2 List_ELEM(f2, f2P, i);                \
351     List_END_FOR_ALL                                                        \
354 // member operator : this field f OP s
356 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s)                             \
357                                                                             \
358     /* set access to f at end of field */                                   \
359     List_ACCESS(typeF, f, fP);                                              \
360                                                                             \
361     /* loop through field performing f OP s */                              \
362     List_FOR_ALL(f, i)                                                      \
363         List_ELEM(f, fP, i) OP (s);                                         \
364     List_END_FOR_ALL                                                        \
367 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
368 // define high performance macro functions for Field<Type> friend functions
370 // friend operator function : s OP f, allocates storage for s
372 #define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f)                             \
373                                                                             \
374     /* set access to f at end of field */                                   \
375     List_CONST_ACCESS(typeF, f, fP);                                        \
376                                                                             \
377     /* loop through field performing s OP f */                              \
378     List_FOR_ALL(f, i)                                                      \
379         (s) OP List_ELEM(f, fP, i);                                         \
380     List_END_FOR_ALL
383 // friend operator function : s OP1 f1 OP2 f2, allocates storage for s
385 #define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2)    \
386                                                                             \
387     /* set access to f1 and f2 at end of each field */                      \
388     List_CONST_ACCESS(typeF1, f1, f1P);                                     \
389     List_CONST_ACCESS(typeF2, f2, f2P);                                     \
390                                                                             \
391     /* loop through field performing s OP f */                              \
392     List_FOR_ALL(f1, i)                                                     \
393         (s) OP1 List_ELEM(f1, f1P, i) OP2 List_ELEM(f2, f2P, i);            \
394     List_END_FOR_ALL
397 // friend operator function : s OP FUNC(f), allocates storage for s
399 #define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f)                  \
400                                                                             \
401     /* set access to f at end of field */                                   \
402     List_CONST_ACCESS(typeF, f, fP);                                        \
403                                                                             \
404     /* loop through field performing s OP f */                              \
405     List_FOR_ALL(f, i)                                                      \
406         (s) OP FUNC(List_ELEM(f, fP, i));                                   \
407     List_END_FOR_ALL
410 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
412 } // End namespace Foam
414 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
416 #endif
418 // ************************************************************************* //