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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2022-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Description
28  Declaration macros for Field<Type> algebra.
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #ifndef Foam_FieldM_H
33 #define Foam_FieldM_H
34 
35 #include "error.H"
36 #include "ListLoopM.H" // For list access macros
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 
45 #ifdef FULLDEBUG
46 
47 template<class Type1, class Type2>
48 void checkFields
49 (
50  const UList<Type1>& f1,
51  const UList<Type2>& f2,
52  const char* op
53 )
54 {
55  if (f1.size() != f2.size())
56  {
58  << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
59  << " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
60  << endl
61  << " for operation " << op
62  << abort(FatalError);
63  }
64 }
65 
66 template<class Type1, class Type2, class Type3>
67 void checkFields
68 (
69  const UList<Type1>& f1,
70  const UList<Type2>& f2,
71  const UList<Type3>& f3,
72  const char* op
73 )
74 {
75  if (f1.size() != f2.size() || f1.size() != f3.size())
76  {
78  << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
79  << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
80  << " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
81  << endl
82  << " for operation " << op
83  << abort(FatalError);
84  }
85 }
86 
87 template<class Type1, class Type2, class Type3, class Type4>
88 void checkFields
89 (
90  const UList<Type1>& f1,
91  const UList<Type2>& f2,
92  const UList<Type3>& f3,
93  const UList<Type4>& f4,
94  const char* op
95 )
96 {
97  if
98  (
99  f1.size() != f2.size()
100  || f1.size() != f3.size()
101  || f1.size() != f4.size()
102  )
103  {
105  << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')'
106  << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')'
107  << ", Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')'
108  << " and Field<"<<pTraits<Type4>::typeName<<"> f4("<<f4.size()<<')'
109  << endl
110  << " for operation " << op
111  << abort(FatalError);
112  }
113 }
114 
115 #else
116 
117 template<class Type1, class Type2>
118 void checkFields
119 (
120  const UList<Type1>&,
121  const UList<Type2>&,
122  const char*
123 )
124 {}
125 
126 template<class Type1, class Type2, class Type3>
127 void checkFields
128 (
129  const UList<Type1>&,
130  const UList<Type2>&,
131  const UList<Type3>&,
132  const char*
133 )
134 {}
135 
136 template<class Type1, class Type2, class Type3, class Type4>
137 void checkFields
138 (
139  const UList<Type1>&,
140  const UList<Type2>&,
141  const UList<Type3>&,
142  const UList<Type4>&,
143  const char*
144 )
145 {}
146 
147 #endif
149 
150 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
151 
152 // Unary Free Function : f1 OP Func(f2)
153 
154 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \
155 { \
156  /* Check fields have same size */ \
157  checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)"); \
158  \
159  /* Field access */ \
160  List_ACCESS(typeF1, f1, f1P); \
161  List_CONST_ACCESS(typeF2, f2, f2P); \
162  \
163  /* Loop: f1 OP FUNC(f2) */ \
164  const label loop_len = (f1).size(); \
165  \
166  /* pragmas... */ \
167  for (label i = 0; i < loop_len; ++i) \
168  { \
169  (f1P[i]) OP FUNC(f2P[i]); \
170  } \
171 }
172 
173 
174 // Nullary Member Function : f1 OP f2.FUNC()
175 
176 #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \
177 { \
178  /* Check fields have same size */ \
179  checkFields(f1, f2, "f1 " #OP " f2" #FUNC); \
180  \
181  /* Field access */ \
182  List_ACCESS(typeF1, f1, f1P); \
183  List_CONST_ACCESS(typeF2, f2, f2P); \
184  \
185  /* Loop: f1 OP f2.FUNC() */ \
186  const label loop_len = (f1).size(); \
187  \
188  /* pragmas... */ \
189  for (label i = 0; i < loop_len; ++i) \
190  { \
191  (f1P[i]) OP (f2P[i]).FUNC(); \
192  } \
193 }
194 
195 
196 // Binary Free Function : f1 OP FUNC(f2, f3)
197 
198 #define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3) \
199 { \
200  /* Check fields have same size */ \
201  checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)"); \
202  \
203  /* Field access */ \
204  List_ACCESS(typeF1, f1, f1P); \
205  List_CONST_ACCESS(typeF2, f2, f2P); \
206  List_CONST_ACCESS(typeF3, f3, f3P); \
207  \
208  /* Loop: f1 OP FUNC(f2, f3) */ \
209  const label loop_len = (f1).size(); \
210  \
211  /* pragmas... */ \
212  for (label i = 0; i < loop_len; ++i) \
213  { \
214  (f1P[i]) OP FUNC((f2P[i]), (f3P[i])); \
215  } \
216 }
217 
218 
219 // [reduction] Binary Free Function : s OP FUNC(f1, f2)
220 
221 #define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2) \
222 { \
223  /* Check fields have same size */ \
224  checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)"); \
225  \
226  /* Field access */ \
227  List_CONST_ACCESS(typeF1, f1, f1P); \
228  List_CONST_ACCESS(typeF2, f2, f2P); \
229  \
230  /* Loop: s OP FUNC(f1, f2) */ \
231  const label loop_len = (f1).size(); \
232  \
233  /* pragmas, reduction... */ \
234  for (label i = 0; i < loop_len; ++i) \
235  { \
236  (s) OP FUNC((f1P[i]), (f2P[i])); \
237  } \
238 }
239 
240 
241 // Binary Free Function : f1 OP FUNC(f2, s)
242 
243 #define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s) \
244 { \
245  /* Check fields have same size */ \
246  checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)"); \
247  \
248  /* Field access */ \
249  List_ACCESS(typeF1, f1, f1P); \
250  List_CONST_ACCESS(typeF2, f2, f2P); \
251  \
252  /* Loop: f1 OP FUNC(f2, s) */ \
253  const label loop_len = (f1).size(); \
254  \
255  /* pragmas... */ \
256  for (label i = 0; i < loop_len; ++i) \
257  { \
258  (f1P[i]) OP FUNC((f2P[i]), (s)); \
259  } \
260 }
261 
262 
263 // [reduction] Binary Free Function : s1 OP FUNC(f, s2)
264 
265 #define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2) \
266 { \
267  /* Field access */ \
268  List_CONST_ACCESS(typeF, f, fP); \
269  \
270  /* Loop: s1 OP FUNC(f, s2) */ \
271  const label loop_len = (f).size(); \
272  \
273  /* pragmas, reduction... */ \
274  for (label i = 0; i < loop_len; ++i) \
275  { \
276  (s1) OP FUNC((fP[i]), (s2)); \
277  } \
278 }
279 
280 
281 // Binary Free Function : f1 OP FUNC(s, f2)
282 
283 #define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2) \
284 { \
285  /* Check fields have same size */ \
286  checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)"); \
287  \
288  /* Field access */ \
289  List_ACCESS(typeF1, f1, f1P); \
290  List_CONST_ACCESS(typeF2, f2, f2P); \
291  \
292  /* Loop: f1 OP1 f2 OP2 f3 */ \
293  const label loop_len = (f1).size(); \
294  \
295  /* pragmas... */ \
296  for (label i = 0; i < loop_len; ++i) \
297  { \
298  (f1P[i]) OP FUNC((s), (f2P[i])); \
299  } \
300 }
301 
302 
303 // Binary Free Function : f1 OP FUNC(s1, s2)
304 
305 #define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2) \
306 { \
307  /* Field access */ \
308  List_ACCESS(typeF1, f1, f1P); \
309  \
310  /* Loop: f1 OP FUNC(s1, s2) */ \
311  const label loop_len = (f1).size(); \
312  \
313  /* pragmas... */ \
314  for (label i = 0; i < loop_len; ++i) \
315  { \
316  (f1P[i]) OP FUNC((s1), (s2)); \
317  } \
318 }
319 
320 
321 // Unary Member Function : f1 OP f2 FUNC(s)
322 
323 #define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s) \
324 { \
325  /* Check fields have same size */ \
326  checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)"); \
327  \
328  /* Field access */ \
329  List_ACCESS(typeF1, f1, f1P); \
330  List_CONST_ACCESS(typeF2, f2, f2P); \
331  \
332  /* Loop: f1 OP f2 FUNC(s) */ \
333  const label loop_len = (f1).size(); \
334  \
335  /* pragmas... */ \
336  for (label i = 0; i < loop_len; ++i) \
337  { \
338  (f1P[i]) OP (f2P[i]) FUNC((s)); \
339  } \
340 }
342 
343 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
344 
345 // Ternary Free Function : f1 OP FUNC(f2, f3, f4)
346 
347 #define TFOR_ALL_F_OP_FUNC_F_F_F\
348 (typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3, typeF4, f4) \
349 { \
350  /* Check fields have same size */ \
351  checkFields(f1, f2, f3, f4, "f1 " #OP " " #FUNC "(f2, f3, f4)"); \
352  \
353  /* Field access */ \
354  List_ACCESS(typeF1, f1, f1P); \
355  List_CONST_ACCESS(typeF2, f2, f2P); \
356  List_CONST_ACCESS(typeF3, f3, f3P); \
357  List_CONST_ACCESS(typeF4, f4, f4P); \
358  \
359  /* Loop: f1 OP FUNC(f2, f3, f4) */ \
360  const label loop_len = (f1).size(); \
361  \
362  /* pragmas... */ \
363  for (label i = 0; i < loop_len; ++i) \
364  { \
365  (f1P[i]) OP FUNC((f2P[i]), (f3P[i]), (f4P[i])); \
366  } \
367 }
368 
369 // Ternary Free Function : f1 OP FUNC(f2, f3, s4)
370 
371 #define TFOR_ALL_F_OP_FUNC_F_F_S\
372 (typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3, typeF4, s4) \
373 { \
374  /* Check fields have same size */ \
375  checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3, s)"); \
376  \
377  /* Field access */ \
378  List_ACCESS(typeF1, f1, f1P); \
379  List_CONST_ACCESS(typeF2, f2, f2P); \
380  List_CONST_ACCESS(typeF3, f3, f3P); \
381  \
382  /* Loop: f1 OP FUNC(f2, f3, s4) */ \
383  const label loop_len = (f1).size(); \
384  \
385  /* pragmas... */ \
386  for (label i = 0; i < loop_len; ++i) \
387  { \
388  (f1P[i]) OP FUNC((f2P[i]), (f3P[i]), (s4)); \
389  } \
390 }
392 
393 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
394 
395 // Member operator : this field f1 OP1 f2 OP2 f3
396 
397 #define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3) \
398 { \
399  /* Check fields have same size */ \
400  checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3"); \
401  \
402  /* Field access */ \
403  List_ACCESS(typeF1, f1, f1P); \
404  List_CONST_ACCESS(typeF2, f2, f2P); \
405  List_CONST_ACCESS(typeF3, f3, f3P); \
406  \
407  /* Loop: f1 OP1 f2 OP2 f3 */ \
408  const label loop_len = (f1).size(); \
409  \
410  /* pragmas... */ \
411  for (label i = 0; i < loop_len; ++i) \
412  { \
413  (f1P[i]) OP1 (f2P[i]) OP2 (f3P[i]); \
414  } \
415 }
416 
417 
418 // Member operator : this field f1 OP1 s OP2 f2
419 
420 #define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2) \
421 { \
422  /* Check fields have same size */ \
423  checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2"); \
424  \
425  /* Field access */ \
426  List_ACCESS(typeF1, f1, f1P); \
427  List_CONST_ACCESS(typeF2, f2, f2P); \
428  \
429  /* Loop: f1 OP1 s OP2 f2 */ \
430  const label loop_len = (f1).size(); \
431  \
432  /* pragmas... */ \
433  for (label i = 0; i < loop_len; ++i) \
434  { \
435  (f1P[i]) OP1 (s) OP2 (f2P[i]); \
436  } \
437 }
438 
439 
440 // Member operator : this field f1 OP1 f2 OP2 s
441 
442 #define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s) \
443 { \
444  /* Check fields have same size */ \
445  checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s"); \
446  \
447  /* Field access */ \
448  List_ACCESS(typeF1, f1, f1P); \
449  List_CONST_ACCESS(typeF2, f2, f2P); \
450  \
451  /* Loop f1 OP1 s OP2 f2 */ \
452  const label loop_len = (f1).size(); \
453  \
454  /* pragmas... */ \
455  for (label i = 0; i < loop_len; ++i) \
456  { \
457  (f1P[i]) OP1 (f2P[i]) OP2 (s); \
458  } \
459 }
460 
461 
462 // Member operator : this field f1 OP f2
463 
464 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2) \
465 { \
466  /* Check fields have same size */ \
467  checkFields(f1, f2, "f1 " #OP " f2"); \
468  \
469  /* Field access */ \
470  List_ACCESS(typeF1, f1, f1P); \
471  List_CONST_ACCESS(typeF2, f2, f2P); \
472  \
473  /* Loop: f1 OP f2 */ \
474  const label loop_len = (f1).size(); \
475  \
476  /* pragmas... */ \
477  for (label i = 0; i < loop_len; ++i) \
478  { \
479  (f1P[i]) OP (f2P[i]); \
480  } \
481 }
482 
483 
484 // Member operator : this field f1 OP1 OP2 f2
485 
486 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \
487 { \
488  /* Check fields have same size */ \
489  checkFields(f1, f2, #OP1 " " #OP2 " f2"); \
490  \
491  /* Field access */ \
492  List_ACCESS(typeF1, f1, f1P); \
493  List_CONST_ACCESS(typeF2, f2, f2P); \
494  \
495  /* Loop: f1 OP1 OP2 f2 */ \
496  const label loop_len = (f1).size(); \
497  \
498  /* pragmas... */ \
499  for (label i = 0; i < loop_len; ++i) \
500  { \
501  (f1P[i]) OP1 OP2 (f2P[i]); \
502  } \
503 }
504 
505 
506 // Member operator : this field f OP s
507 
508 #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \
509 { \
510  /* Field access */ \
511  List_ACCESS(typeF, f, fP); \
512  \
513  /* Loop: f OP s */ \
514  const label loop_len = (f).size(); \
515  \
516  /* pragmas... */ \
517  for (label i = 0; i < loop_len; ++i) \
518  { \
519  (fP[i]) OP (s); \
520  } \
521 }
523 
524 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
525 
526 // Friend operator function : s OP f, allocates storage for s
527 
528 #define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f) \
529 { \
530  /* Field access */ \
531  List_CONST_ACCESS(typeF, f, fP); \
532  \
533  /* Loop: s OP f */ \
534  const label loop_len = (f).size(); \
535  \
536  /* pragmas, reduction... */ \
537  for (label i = 0; i < loop_len; ++i) \
538  { \
539  (s) OP (fP[i]); \
540  } \
541 }
542 
543 
544 // Friend operator function : s OP1 f1 OP2 f2, allocates storage for s
545 
546 #define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2) \
547 { \
548  /* Field access */ \
549  List_CONST_ACCESS(typeF1, f1, f1P); \
550  List_CONST_ACCESS(typeF2, f2, f2P); \
551  \
552  /* Loop: s OP1 f1 OP2 f2 */ \
553  const label loop_len = (f1).size(); \
554  \
555  /* pragmas, reduction... */ \
556  for (label i = 0; i < loop_len; ++i) \
557  { \
558  (s) OP1 (f1P[i]) OP2 (f2P[i]); \
559  } \
560 }
561 
562 
563 // Friend operator function : s OP FUNC(f), allocates storage for s
564 #define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f) \
565 { \
566  /* Field access */ \
567  List_CONST_ACCESS(typeF, f, fP); \
568  \
569  /* Loop: s OP FUNC(f) */ \
570  const label loop_len = (f).size(); \
571  \
572  /* pragmas, reduction... */ \
573  for (label i = 0; i < loop_len; ++i) \
574  { \
575  (s) OP FUNC(fP[i]); \
576  } \
577 }
578 
579 
580 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
581 
582 } // End namespace Foam
583 
584 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
585 
586 #endif
587 
588 // ************************************************************************* //
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
void checkFields(const FieldField< Field, Type1 > &, const FieldField< Field, Type2 > &, const char *op)
Definition: FieldField.C:78
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Macros for accessing List elements.
Namespace for OpenFOAM.