FieldM.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
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 "error.H"
35 #include "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  << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
58  << " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
59  << endl << " for operation " << op
60  << abort(FatalError);
61  }
62 }
63 
64 template<class Type1, class Type2, class Type3>
65 void checkFields
66 (
67  const UList<Type1>& f1,
68  const UList<Type2>& f2,
69  const UList<Type3>& f3,
70  const char* op
71 )
72 {
73  if (f1.size() != f2.size() || f1.size() != f3.size())
74  {
76  << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
77  << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
78  << " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
79  << endl << " for operation " << op
80  << abort(FatalError);
81  }
82 }
83 
84 #else
85 
86 template<class Type1, class Type2>
87 void checkFields
88 (
89  const UList<Type1>&,
90  const UList<Type2>&,
91  const char*
92 )
93 {}
94 
95 template<class Type1, class Type2, class Type3>
96 void checkFields
97 (
98  const UList<Type1>&,
99  const UList<Type2>&,
100  const UList<Type3>&,
101  const char*
102 )
103 {}
104 
105 #endif
106 
107 
108 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
109 
110 // member function : this f1 OP fUNC f2
111 
112 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \
113  \
114  /* check the two fields have same Field<Type> mesh */ \
115  checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)"); \
116  \
117  /* set access to f1, f2 and f3 at end of each field */ \
118  List_ACCESS(typeF1, f1, f1P); \
119  List_CONST_ACCESS(typeF2, f2, f2P); \
120  \
121  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
122  List_FOR_ALL(f1, i) \
123  List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i)); \
124  List_END_FOR_ALL \
125 
126 
127 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \
128  \
129  /* check the two fields have same Field<Type> mesh */ \
130  checkFields(f1, f2, "f1 " #OP " f2" #FUNC); \
131  \
132  /* set access to f1, f2 and f3 at end of each field */ \
133  List_ACCESS(typeF1, f1, f1P); \
134  List_CONST_ACCESS(typeF2, f2, f2P); \
135  \
136  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
137  List_FOR_ALL(f1, i) \
138  List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i).FUNC(); \
139  List_END_FOR_ALL \
140 
141 
142 // member function : this field f1 OP fUNC f2, f3
143 
144 #define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3)\
145  \
146  /* check the three fields have same Field<Type> mesh */ \
147  checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)"); \
148  \
149  /* set access to f1, f2 and f3 at end of each field */ \
150  List_ACCESS(typeF1, f1, f1P); \
151  List_CONST_ACCESS(typeF2, f2, f2P); \
152  List_CONST_ACCESS(typeF3, f3, f3P); \
153  \
154  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
155  List_FOR_ALL(f1, i) \
156  List_ELEM(f1, f1P, i) \
157  OP FUNC(List_ELEM(f2, f2P, i), List_ELEM(f3, f3P, i)); \
158  List_END_FOR_ALL \
159 
160 
161 // member function : this field f1 OP fUNC f2, f3
162 
163 #define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2) \
164  \
165  /* check the two fields have same Field<Type> mesh */ \
166  checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)"); \
167  \
168  /* set access to f1 and f2 at end of each field */ \
169  List_CONST_ACCESS(typeF1, f1, f1P); \
170  List_CONST_ACCESS(typeF2, f2, f2P); \
171  \
172  /* loop through fields performing s OP FUNC(f1, f2) */ \
173  List_FOR_ALL(f1, i) \
174  (s) OP FUNC(List_ELEM(f1, f1P, i), List_ELEM(f2, f2P, i)); \
175  List_END_FOR_ALL \
176 
177 
178 // member function : this f1 OP fUNC f2, s
179 
180 #define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s) \
181  \
182  /* check the two fields have same Field<Type> mesh */ \
183  checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)"); \
184  \
185  /* set access to f1, f2 and f3 at end of each field */ \
186  List_ACCESS(typeF1, f1, f1P); \
187  List_CONST_ACCESS(typeF2, f2, f2P); \
188  \
189  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
190  List_FOR_ALL(f1, i) \
191  List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i), (s)); \
192  List_END_FOR_ALL
193 
194 
195 // member function : s1 OP fUNC f, s2
196 
197 #define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2) \
198  \
199  /* set access to f at end of field */ \
200  List_CONST_ACCESS(typeF, f, fP); \
201  \
202  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
203  List_FOR_ALL(f, i) \
204  (s1) OP FUNC(List_ELEM(f, fP, i), (s2)); \
205  List_END_FOR_ALL \
206 
207 
208 // member function : this f1 OP fUNC s, f2
209 
210 #define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2) \
211  \
212  /* check the two fields have same Field<Type> mesh */ \
213  checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)"); \
214  \
215  /* set access to f1, f2 and f3 at end of each field */ \
216  List_ACCESS(typeF1, f1, f1P); \
217  List_CONST_ACCESS(typeF2, f2, f2P); \
218  \
219  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
220  List_FOR_ALL(f1, i) \
221  List_ELEM(f1, f1P, i) OP FUNC((s), List_ELEM(f2, f2P, i)); \
222  List_END_FOR_ALL \
223 
224 
225 // member function : this f1 OP fUNC s, f2
226 
227 #define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)\
228  \
229  /* set access to f1 at end of field */ \
230  List_ACCESS(typeF1, f1, f1P); \
231  \
232  /* loop through fields performing f1 OP1 FUNC(s1, s2) */ \
233  List_FOR_ALL(f1, i) \
234  List_ELEM(f1, f1P, i) OP FUNC((s1), (s2)); \
235  List_END_FOR_ALL \
236 
237 
238 // member function : this f1 OP1 f2 OP2 FUNC s
239 
240 #define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s) \
241  \
242  /* check the two fields have same Field<Type> mesh */ \
243  checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)"); \
244  \
245  /* set access to f1, f2 and f3 at end of each field */ \
246  List_ACCESS(typeF1, f1, f1P); \
247  List_CONST_ACCESS(typeF2, f2, f2P); \
248  \
249  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
250  List_FOR_ALL(f1, i) \
251  List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i) FUNC((s)); \
252  List_END_FOR_ALL \
253 
254 
255 // define high performance macro functions for Field<Type> operations
256 
257 // member operator : this field f1 OP1 f2 OP2 f3
258 
259 #define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3) \
260  \
261  /* check the three fields have same Field<Type> mesh */ \
262  checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3"); \
263  \
264  /* set access to f1, f2 and f3 at end of each field */ \
265  List_ACCESS(typeF1, f1, f1P); \
266  List_CONST_ACCESS(typeF2, f2, f2P); \
267  List_CONST_ACCESS(typeF3, f3, f3P); \
268  \
269  /* loop through fields performing f1 OP1 f2 OP2 f3 */ \
270  List_FOR_ALL(f1, i) \
271  List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) \
272  OP2 List_ELEM(f3, f3P, i); \
273  List_END_FOR_ALL \
274 
275 
276 // member operator : this field f1 OP1 s OP2 f2
277 
278 #define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2) \
279  \
280  /* check the two fields have same Field<Type> mesh */ \
281  checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2"); \
282  \
283  /* set access to f1 and f2 at end of each field */ \
284  List_ACCESS(typeF1, f1, f1P); \
285  List_CONST_ACCESS(typeF2, f2, f2P); \
286  \
287  /* loop through fields performing f1 OP1 s OP2 f2 */ \
288  List_FOR_ALL(f1, i) \
289  List_ELEM(f1, f1P, i) OP1 (s) OP2 List_ELEM(f2, f2P, i); \
290  List_END_FOR_ALL \
291 
292 
293 // member operator : this field f1 OP1 f2 OP2 s
294 
295 #define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s) \
296  \
297  /* check the two fields have same Field<Type> mesh */ \
298  checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s"); \
299  \
300  /* set access to f1 and f2 at end of each field */ \
301  List_ACCESS(typeF1, f1, f1P); \
302  List_CONST_ACCESS(typeF2, f2, f2P); \
303  \
304  /* loop through fields performing f1 OP1 s OP2 f2 */ \
305  List_FOR_ALL(f1, i) \
306  List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) OP2 (s); \
307  List_END_FOR_ALL \
308 
309 
310 // member operator : this field f1 OP f2
311 
312 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2) \
313  \
314  /* check the two fields have same Field<Type> mesh */ \
315  checkFields(f1, f2, "f1 " #OP " f2"); \
316  \
317  /* set pointer to f1P at end of f1 and */ \
318  /* f2.p at end of f2 */ \
319  List_ACCESS(typeF1, f1, f1P); \
320  List_CONST_ACCESS(typeF2, f2, f2P); \
321  \
322  /* loop through fields performing f1 OP f2 */ \
323  List_FOR_ALL(f1, i) \
324  List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i); \
325  List_END_FOR_ALL \
326 
327 // member operator : this field f1 OP1 OP2 f2
328 
329 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \
330  \
331  /* check the two fields have same Field<Type> mesh */ \
332  checkFields(f1, f2, #OP1 " " #OP2 " f2"); \
333  \
334  /* set pointer to f1P at end of f1 and */ \
335  /* f2.p at end of f2 */ \
336  List_ACCESS(typeF1, f1, f1P); \
337  List_CONST_ACCESS(typeF2, f2, f2P); \
338  \
339  /* loop through fields performing f1 OP1 OP2 f2 */ \
340  List_FOR_ALL(f1, i) \
341  List_ELEM(f1, f1P, i) OP1 OP2 List_ELEM(f2, f2P, i); \
342  List_END_FOR_ALL \
343 
344 
345 // member operator : this field f OP s
346 
347 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \
348  \
349  /* set access to f at end of field */ \
350  List_ACCESS(typeF, f, fP); \
351  \
352  /* loop through field performing f OP s */ \
353  List_FOR_ALL(f, i) \
354  List_ELEM(f, fP, i) OP (s); \
355  List_END_FOR_ALL \
356 
357 
358 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
359 // define high performance macro functions for Field<Type> friend functions
360 
361 // friend operator function : s OP f, allocates storage for s
362 
363 #define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f) \
364  \
365  /* set access to f at end of field */ \
366  List_CONST_ACCESS(typeF, f, fP); \
367  \
368  /* loop through field performing s OP f */ \
369  List_FOR_ALL(f, i) \
370  (s) OP List_ELEM(f, fP, i); \
371  List_END_FOR_ALL
372 
373 
374 // friend operator function : s OP1 f1 OP2 f2, allocates storage for s
375 
376 #define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2) \
377  \
378  /* set access to f1 and f2 at end of each field */ \
379  List_CONST_ACCESS(typeF1, f1, f1P); \
380  List_CONST_ACCESS(typeF2, f2, f2P); \
381  \
382  /* loop through field performing s OP f */ \
383  List_FOR_ALL(f1, i) \
384  (s) OP1 List_ELEM(f1, f1P, i) OP2 List_ELEM(f2, f2P, i); \
385  List_END_FOR_ALL
386 
387 
388 // friend operator function : s OP FUNC(f), allocates storage for s
389 
390 #define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f) \
391  \
392  /* set access to f at end of field */ \
393  List_CONST_ACCESS(typeF, f, fP); \
394  \
395  /* loop through field performing s OP f */ \
396  List_FOR_ALL(f, i) \
397  (s) OP FUNC(List_ELEM(f, fP, i)); \
398  List_END_FOR_ALL
399 
400 
401 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
402 
403 } // End namespace Foam
404 
405 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
406 
407 #endif
408 
409 // ************************************************************************* //
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
void checkFields(const FieldField< Field, Type1 > &, const FieldField< Field, Type2 > &, const char *op)
Definition: FieldField.C:85
errorManip< error > abort(error &err)
Definition: errorManip.H:131
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
List<T> is a 1D vector of objects of type T, where the size of the vector is known and used for subsc...
Namespace for OpenFOAM.