1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
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
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/>.
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 \*---------------------------------------------------------------------------*/
35 #include "ListLoopM.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 template<class Type1, class Type2>
49 const UList<Type1>& f1,
50 const UList<Type2>& f2,
54 if (f1.size() != f2.size())
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
68 template<class Type1, class Type2, class Type3>
71 const UList<Type1>& f1,
72 const UList<Type2>& f2,
73 const UList<Type3>& f3,
77 if (f1.size() != f2.size() || f1.size() != f3.size())
81 "checkFields(const UList<Type1>&, "
82 "const UList<Type2>&, const UList<Type3>&, "
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
95 template<class Type1, class Type2>
104 template<class Type1, class Type2, class Type3>
117 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
119 // member function : this f1 OP fUNC f2
121 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \
123 /* check the two fields have same Field<Type> mesh */ \
124 checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)"); \
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); \
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)); \
136 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \
138 /* check the two fields have same Field<Type> mesh */ \
139 checkFields(f1, f2, "f1 " #OP " f2" #FUNC); \
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); \
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(); \
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)\
155 /* check the three fields have same Field<Type> mesh */ \
156 checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)"); \
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); \
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)); \
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) \
174 /* check the two fields have same Field<Type> mesh */ \
175 checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)"); \
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); \
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)); \
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) \
191 /* check the two fields have same Field<Type> mesh */ \
192 checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)"); \
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); \
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)); \
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) \
208 /* set access to f at end of field */ \
209 List_CONST_ACCESS(typeF, f, fP); \
211 /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
213 (s1) OP FUNC(List_ELEM(f, fP, i), (s2)); \
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) \
221 /* check the two fields have same Field<Type> mesh */ \
222 checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)"); \
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); \
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)); \
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)\
238 /* set access to f1 at end of field */ \
239 List_ACCESS(typeF1, f1, f1P); \
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)); \
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) \
251 /* check the two fields have same Field<Type> mesh */ \
252 checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)"); \
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); \
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)); \
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) \
270 /* check the three fields have same Field<Type> mesh */ \
271 checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3"); \
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); \
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); \
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) \
289 /* check the two fields have same Field<Type> mesh */ \
290 checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2"); \
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); \
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); \
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) \
306 /* check the two fields have same Field<Type> mesh */ \
307 checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s"); \
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); \
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); \
319 // member operator : this field f1 OP f2
321 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2) \
323 /* check the two fields have same Field<Type> mesh */ \
324 checkFields(f1, f2, "f1 " #OP " f2"); \
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); \
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); \
336 // member operator : this field f1 OP1 OP2 f2
338 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \
340 /* check the two fields have same Field<Type> mesh */ \
341 checkFields(f1, f2, #OP1 " " #OP2 " f2"); \
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); \
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); \
354 // member operator : this field f OP s
356 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \
358 /* set access to f at end of field */ \
359 List_ACCESS(typeF, f, fP); \
361 /* loop through field performing f OP s */ \
363 List_ELEM(f, fP, i) OP (s); \
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) \
374 /* set access to f at end of field */ \
375 List_CONST_ACCESS(typeF, f, fP); \
377 /* loop through field performing s OP f */ \
379 (s) OP List_ELEM(f, fP, i); \
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) \
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); \
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); \
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) \
401 /* set access to f at end of field */ \
402 List_CONST_ACCESS(typeF, f, fP); \
404 /* loop through field performing s OP f */ \
406 (s) OP FUNC(List_ELEM(f, fP, i)); \
410 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
412 } // End namespace Foam
414 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
418 // ************************************************************************* //