FreeFOAM The Cross-Platform CFD Toolkit
FieldM.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
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.
28 
29 \*---------------------------------------------------------------------------*/
30 
31 #ifndef FieldM_H
32 #define FieldM_H
33 
34 #include <OpenFOAM/error.H>
35 #include <OpenFOAM/ListLoopM.H>
36 
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 #ifdef FULLDEBUG
45 
46 template<class Type1, class Type2>
47 void checkFields
48 (
49  const UList<Type1>& f1,
50  const UList<Type2>& f2,
51  const char* op
52 )
53 {
54  if (f1.size() != f2.size())
55  {
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  }
66 }
67 
68 template<class Type1, class Type2, class Type3>
69 void checkFields
70 (
71  const UList<Type1>& f1,
72  const UList<Type2>& f2,
73  const UList<Type3>& f3,
74  const char* op
75 )
76 {
77  if (f1.size() != f2.size() || f1.size() != f3.size())
78  {
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  }
91 }
92 
93 #else
94 
95 template<class Type1, class Type2>
96 void checkFields
97 (
98  const UList<Type1>&,
99  const UList<Type2>&,
100  const char*
101 )
102 {}
103 
104 template<class Type1, class Type2, class Type3>
105 void checkFields
106 (
107  const UList<Type1>&,
108  const UList<Type2>&,
109  const UList<Type3>&,
110  const char*
111 )
112 {}
113 
114 #endif
115 
116 
117 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
118 
119 // member function : this f1 OP fUNC f2
120 
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 \
134 
135 
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 \
149 
150 
151 // member function : this field f1 OP fUNC f2, f3
152 
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 \
168 
169 
170 // member function : this field f1 OP fUNC f2, f3
171 
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 \
185 
186 
187 // member function : this f1 OP fUNC f2, s
188 
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
202 
203 
204 // member function : s1 OP fUNC f, s2
205 
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 \
215 
216 
217 // member function : this f1 OP fUNC s, f2
218 
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 \
232 
233 
234 // member function : this f1 OP fUNC s, f2
235 
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 \
245 
246 
247 // member function : this f1 OP1 f2 OP2 FUNC s
248 
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 \
262 
263 
264 // define high performance macro functions for Field<Type> operations
265 
266 // member operator : this field f1 OP1 f2 OP2 f3
267 
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 \
283 
284 
285 // member operator : this field f1 OP1 s OP2 f2
286 
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 \
300 
301 
302 // member operator : this field f1 OP1 f2 OP2 s
303 
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 \
317 
318 
319 // member operator : this field f1 OP f2
320 
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 \
335 
336 // member operator : this field f1 OP1 OP2 f2
337 
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 \
352 
353 
354 // member operator : this field f OP s
355 
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 \
365 
366 
367 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
368 // define high performance macro functions for Field<Type> friend functions
369 
370 // friend operator function : s OP f, allocates storage for s
371 
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
381 
382 
383 // friend operator function : s OP1 f1 OP2 f2, allocates storage for s
384 
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
395 
396 
397 // friend operator function : s OP FUNC(f), allocates storage for s
398 
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
408 
409 
410 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
411 
412 } // End namespace Foam
413 
414 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
415 
416 #endif
417 
418 // ************************ vim: set sw=4 sts=4 et: ************************ //