1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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
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 \*---------------------------------------------------------------------------*/
36 #include "ListLoopM.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 template<class Type1, class Type2>
50 const UList<Type1>& f1,
51 const UList<Type2>& f2,
55 if (f1.size() != f2.size())
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
69 template<class Type1, class Type2, class Type3>
72 const UList<Type1>& f1,
73 const UList<Type2>& f2,
74 const UList<Type3>& f3,
78 if (f1.size() != f2.size() || f1.size() != f3.size())
82 "checkFields(const UList<Type1>&, "
83 "const UList<Type2>&, const UList<Type3>&, "
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
96 template<class Type1, class Type2>
105 template<class Type1, class Type2, class Type3>
118 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
120 // member function : this f1 OP fUNC f2
122 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \
124 /* check the two fields have same Field<Type> mesh */ \
125 checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)"); \
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); \
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)); \
137 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \
139 /* check the two fields have same Field<Type> mesh */ \
140 checkFields(f1, f2, "f1 " #OP " f2" #FUNC); \
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); \
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(); \
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)\
156 /* check the three fields have same Field<Type> mesh */ \
157 checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)"); \
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); \
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)); \
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) \
175 /* check the two fields have same Field<Type> mesh */ \
176 checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)"); \
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); \
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)); \
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) \
192 /* check the two fields have same Field<Type> mesh */ \
193 checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)"); \
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); \
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)); \
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) \
209 /* set access to f at end of field */ \
210 List_CONST_ACCESS(typeF, f, fP); \
212 /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
214 (s1) OP FUNC(List_ELEM(f, fP, i), (s2)); \
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) \
222 /* check the two fields have same Field<Type> mesh */ \
223 checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)"); \
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); \
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)); \
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)\
239 /* set access to f1 at end of field */ \
240 List_ACCESS(typeF1, f1, f1P); \
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)); \
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) \
252 /* check the two fields have same Field<Type> mesh */ \
253 checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)"); \
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); \
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)); \
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) \
271 /* check the three fields have same Field<Type> mesh */ \
272 checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3"); \
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); \
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); \
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) \
290 /* check the two fields have same Field<Type> mesh */ \
291 checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2"); \
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); \
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); \
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) \
307 /* check the two fields have same Field<Type> mesh */ \
308 checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s"); \
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); \
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); \
320 // member operator : this field f1 OP f2
322 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2) \
324 /* check the two fields have same Field<Type> mesh */ \
325 checkFields(f1, f2, "f1 " #OP " f2"); \
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); \
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); \
337 // member operator : this field f1 OP1 OP2 f2
339 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \
341 /* check the two fields have same Field<Type> mesh */ \
342 checkFields(f1, f2, #OP1 " " #OP2 " f2"); \
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); \
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); \
355 // member operator : this field f OP s
357 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \
359 /* set access to f at end of field */ \
360 List_ACCESS(typeF, f, fP); \
362 /* loop through field performing f OP s */ \
364 List_ELEM(f, fP, i) OP (s); \
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) \
375 /* set access to f at end of field */ \
376 List_CONST_ACCESS(typeF, f, fP); \
378 /* loop through field performing s OP f */ \
380 (s) OP List_ELEM(f, fP, i); \
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) \
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); \
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); \
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) \
402 /* set access to f at end of field */ \
403 List_CONST_ACCESS(typeF, f, fP); \
405 /* loop through field performing s OP f */ \
407 (s) OP FUNC(List_ELEM(f, fP, i)); \
411 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
413 } // End namespace Foam
415 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
419 // ************************************************************************* //