FieldFieldFunctionsM.C
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-2017 OpenFOAM Foundation
9  Copyright (C) 2022 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 \*---------------------------------------------------------------------------*/
28 
29 #include "FieldM.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 #define UNARY_FUNCTION(ReturnType, Type, Func) \
35  \
36 TEMPLATE \
37 void Func \
38 ( \
39  FieldField<Field, ReturnType>& res, \
40  const FieldField<Field, Type>& f \
41 ) \
42 { \
43  const label loopLen = (res).size(); \
44  \
45  for (label i = 0; i < loopLen; ++i) \
46  { \
47  Func(res[i], f[i]); \
48  } \
49 } \
50  \
51 TEMPLATE \
52 tmp<FieldField<Field, ReturnType>> Func \
53 ( \
54  const FieldField<Field, Type>& f \
55 ) \
56 { \
57  tmp<FieldField<Field, ReturnType>> tres \
58  ( \
59  FieldField<Field, ReturnType>::NewCalculatedType(f) \
60  ); \
61  Func(tres.ref(), f); \
62  return tres; \
63 } \
64  \
65 TEMPLATE \
66 tmp<FieldField<Field, ReturnType>> Func \
67 ( \
68  const tmp<FieldField<Field, Type>>& tf \
69 ) \
70 { \
71  tmp<FieldField<Field, ReturnType>> tres(New(tf)); \
72  Func(tres.ref(), tf()); \
73  tf.clear(); \
74  return tres; \
75 }
76 
77 
78 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
79 
80 #define UNARY_OPERATOR(ReturnType, Type, Op, OpFunc) \
81  \
82 TEMPLATE \
83 void OpFunc \
84 ( \
85  FieldField<Field, ReturnType>& res, \
86  const FieldField<Field, Type>& f \
87 ) \
88 { \
89  const label loopLen = (res).size(); \
90  \
91  for (label i = 0; i < loopLen; ++i) \
92  { \
93  OpFunc(res[i], f[i]); \
94  } \
95 } \
96  \
97 TEMPLATE \
98 tmp<FieldField<Field, ReturnType>> operator Op \
99 ( \
100  const FieldField<Field, Type>& f \
101 ) \
102 { \
103  tmp<FieldField<Field, ReturnType>> tres \
104  ( \
105  FieldField<Field, Type>::NewCalculatedType(f) \
106  ); \
107  OpFunc(tres.ref(), f); \
108  return tres; \
109 } \
110  \
111 TEMPLATE \
112 tmp<FieldField<Field, ReturnType>> operator Op \
113 ( \
114  const tmp<FieldField<Field, Type>>& tf \
115 ) \
116 { \
117  tmp<FieldField<Field, ReturnType>> tres(New(tf)); \
118  OpFunc(tres.ref(), tf()); \
119  tf.clear(); \
120  return tres; \
121 }
122 
123 
124 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
125 
126 #define BINARY_FUNCTION(ReturnType, Type1, Type2, Func) \
127  \
128 TEMPLATE \
129 void Func \
130 ( \
131  FieldField<Field, ReturnType>& f, \
132  const FieldField<Field, Type1>& f1, \
133  const FieldField<Field, Type2>& f2 \
134 ) \
135 { \
136  const label loopLen = (f).size(); \
137  \
138  for (label i = 0; i < loopLen; ++i) \
139  { \
140  Func(f[i], f1[i], f2[i]); \
141  } \
142 } \
143  \
144 TEMPLATE \
145 tmp<FieldField<Field, ReturnType>> Func \
146 ( \
147  const FieldField<Field, Type1>& f1, \
148  const FieldField<Field, Type2>& f2 \
149 ) \
150 { \
151  tmp<FieldField<Field, ReturnType>> tres \
152  ( \
153  FieldField<Field, Type1>::NewCalculatedType(f1) \
154  ); \
155  Func(tres.ref(), f1, f2); \
156  return tres; \
157 } \
158  \
159 TEMPLATE \
160 tmp<FieldField<Field, ReturnType>> Func \
161 ( \
162  const FieldField<Field, Type1>& f1, \
163  const tmp<FieldField<Field, Type2>>& tf2 \
164 ) \
165 { \
166  tmp<FieldField<Field, ReturnType>> tres \
167  ( \
168  reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2) \
169  ); \
170  Func(tres.ref(), f1, tf2()); \
171  tf2.clear(); \
172  return tres; \
173 } \
174  \
175 TEMPLATE \
176 tmp<FieldField<Field, ReturnType>> Func \
177 ( \
178  const tmp<FieldField<Field, Type1>>& tf1, \
179  const FieldField<Field, Type2>& f2 \
180 ) \
181 { \
182  tmp<FieldField<Field, ReturnType>> tres \
183  ( \
184  reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1) \
185  ); \
186  Func(tres.ref(), tf1(), f2); \
187  tf1.clear(); \
188  return tres; \
189 } \
190  \
191 TEMPLATE \
192 tmp<FieldField<Field, ReturnType>> Func \
193 ( \
194  const tmp<FieldField<Field, Type1>>& tf1, \
195  const tmp<FieldField<Field, Type2>>& tf2 \
196 ) \
197 { \
198  tmp<FieldField<Field, ReturnType>> tres \
199  ( \
200  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
201  New(tf1, tf2) \
202  ); \
203  Func(tres.ref(), tf1(), tf2()); \
204  tf1.clear(); \
205  tf2.clear(); \
206  return tres; \
207 }
208 
209 
210 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
211 
212 #define BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
213  \
214 TEMPLATE \
215 void Func \
216 ( \
217  FieldField<Field, ReturnType>& f, \
218  const Type1& s, \
219  const FieldField<Field, Type2>& f2 \
220 ) \
221 { \
222  const label loopLen = (f).size(); \
223  \
224  for (label i = 0; i < loopLen; ++i) \
225  { \
226  Func(f[i], s, f2[i]); \
227  } \
228 } \
229  \
230 TEMPLATE \
231 tmp<FieldField<Field, ReturnType>> Func \
232 ( \
233  const Type1& s, \
234  const FieldField<Field, Type2>& f2 \
235 ) \
236 { \
237  tmp<FieldField<Field, ReturnType>> tres \
238  ( \
239  FieldField<Field, Type2>::NewCalculatedType(f2) \
240  ); \
241  Func(tres.ref(), s, f2); \
242  return tres; \
243 } \
244  \
245 TEMPLATE \
246 tmp<FieldField<Field, ReturnType>> Func \
247 ( \
248  const Type1& s, \
249  const tmp<FieldField<Field, Type2>>& tf2 \
250 ) \
251 { \
252  tmp<FieldField<Field, ReturnType>> tres \
253  ( \
254  reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2) \
255  ); \
256  Func(tres.ref(), s, tf2()); \
257  tf2.clear(); \
258  return tres; \
259 }
260 
261 
262 #define BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func) \
263  \
264 TEMPLATE \
265 void Func \
266 ( \
267  FieldField<Field, ReturnType>& f, \
268  const FieldField<Field, Type1>& f1, \
269  const Type2& s \
270 ) \
271 { \
272  const label loopLen = (f).size(); \
273  \
274  for (label i = 0; i < loopLen; ++i) \
275  { \
276  Func(f[i], f1[i], s); \
277  } \
278 } \
279  \
280 TEMPLATE \
281 tmp<FieldField<Field, ReturnType>> Func \
282 ( \
283  const FieldField<Field, Type1>& f1, \
284  const Type2& s \
285 ) \
286 { \
287  tmp<FieldField<Field, ReturnType>> tres \
288  ( \
289  FieldField<Field, Type1>::NewCalculatedType(f1) \
290  ); \
291  Func(tres.ref(), f1, s); \
292  return tres; \
293 } \
294  \
295 TEMPLATE \
296 tmp<FieldField<Field, ReturnType>> Func \
297 ( \
298  const tmp<FieldField<Field, Type1>>& tf1, \
299  const Type2& s \
300 ) \
301 { \
302  tmp<FieldField<Field, ReturnType>> tres \
303  ( \
304  reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1) \
305  ); \
306  Func(tres.ref(), tf1(), s); \
307  tf1.clear(); \
308  return tres; \
309 }
310 
311 
312 #define BINARY_TYPE_FUNCTION(ReturnType, Type1, Type2, Func) \
313  BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
314  BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func)
315 
316 
317 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
318 
319 #define BINARY_OPERATOR(ReturnType, Type1, Type2, Op, OpFunc) \
320  \
321 TEMPLATE \
322 void OpFunc \
323 ( \
324  FieldField<Field, ReturnType>& f, \
325  const FieldField<Field, Type1>& f1, \
326  const FieldField<Field, Type2>& f2 \
327 ) \
328 { \
329  const label loopLen = (f).size(); \
330  \
331  for (label i = 0; i < loopLen; ++i) \
332  { \
333  OpFunc(f[i], f1[i], f2[i]); \
334  } \
335 } \
336  \
337 TEMPLATE \
338 tmp<FieldField<Field, ReturnType>> operator Op \
339 ( \
340  const FieldField<Field, Type1>& f1, \
341  const FieldField<Field, Type2>& f2 \
342 ) \
343 { \
344  tmp<FieldField<Field, ReturnType>> tres \
345  ( \
346  FieldField<Field, ReturnType>::NewCalculatedType(f1) \
347  ); \
348  OpFunc(tres.ref(), f1, f2); \
349  return tres; \
350 } \
351  \
352 TEMPLATE \
353 tmp<FieldField<Field, ReturnType>> operator Op \
354 ( \
355  const FieldField<Field, Type1>& f1, \
356  const tmp<FieldField<Field, Type2>>& tf2 \
357 ) \
358 { \
359  tmp<FieldField<Field, ReturnType>> tres \
360  ( \
361  reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2) \
362  ); \
363  OpFunc(tres.ref(), f1, tf2()); \
364  tf2.clear(); \
365  return tres; \
366 } \
367  \
368 TEMPLATE \
369 tmp<FieldField<Field, ReturnType>> operator Op \
370 ( \
371  const tmp<FieldField<Field, Type1>>& tf1, \
372  const FieldField<Field, Type2>& f2 \
373 ) \
374 { \
375  tmp<FieldField<Field, ReturnType>> tres \
376  ( \
377  reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1) \
378  ); \
379  OpFunc(tres.ref(), tf1(), f2); \
380  tf1.clear(); \
381  return tres; \
382 } \
383  \
384 TEMPLATE \
385 tmp<FieldField<Field, ReturnType>> operator Op \
386 ( \
387  const tmp<FieldField<Field, Type1>>& tf1, \
388  const tmp<FieldField<Field, Type2>>& tf2 \
389 ) \
390 { \
391  tmp<FieldField<Field, ReturnType>> tres \
392  ( \
393  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
394  New(tf1, tf2) \
395  ); \
396  OpFunc(tres.ref(), tf1(), tf2()); \
397  tf1.clear(); \
398  tf2.clear(); \
399  return tres; \
400 }
401 
402 
403 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
404 
405 #define BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpFunc) \
406  \
407 TEMPLATE \
408 void OpFunc \
409 ( \
410  FieldField<Field, ReturnType>& f, \
411  const Type1& s, \
412  const FieldField<Field, Type2>& f2 \
413 ) \
414 { \
415  const label loopLen = (f).size(); \
416  \
417  for (label i = 0; i < loopLen; ++i) \
418  { \
419  OpFunc(f[i], s, f2[i]); \
420  } \
421 } \
422  \
423 TEMPLATE \
424 tmp<FieldField<Field, ReturnType>> operator Op \
425 ( \
426  const Type1& s, \
427  const FieldField<Field, Type2>& f2 \
428 ) \
429 { \
430  tmp<FieldField<Field, ReturnType>> tres \
431  ( \
432  FieldField<Field, Type2>::NewCalculatedType(f2) \
433  ); \
434  OpFunc(tres.ref(), s, f2); \
435  return tres; \
436 } \
437  \
438 TEMPLATE \
439 tmp<FieldField<Field, ReturnType>> operator Op \
440 ( \
441  const Type1& s, \
442  const tmp<FieldField<Field, Type2>>& tf2 \
443 ) \
444 { \
445  tmp<FieldField<Field, ReturnType>> tres \
446  ( \
447  reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2) \
448  ); \
449  OpFunc(tres.ref(), s, tf2()); \
450  tf2.clear(); \
451  return tres; \
452 }
453 
454 
455 #define BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) \
456  \
457 TEMPLATE \
458 void OpFunc \
459 ( \
460  FieldField<Field, ReturnType>& f, \
461  const FieldField<Field, Type1>& f1, \
462  const Type2& s \
463 ) \
464 { \
465  const label loopLen = (f).size(); \
466  \
467  for (label i = 0; i < loopLen; ++i) \
468  { \
469  OpFunc(f[i], f1[i], s); \
470  } \
471 } \
472  \
473 TEMPLATE \
474 tmp<FieldField<Field, ReturnType>> operator Op \
475 ( \
476  const FieldField<Field, Type1>& f1, \
477  const Type2& s \
478 ) \
479 { \
480  tmp<FieldField<Field, ReturnType>> tres \
481  ( \
482  FieldField<Field, Type1>::NewCalculatedType(f1) \
483  ); \
484  OpFunc(tres.ref(), f1, s); \
485  return tres; \
486 } \
487  \
488 TEMPLATE \
489 tmp<FieldField<Field, ReturnType>> operator Op \
490 ( \
491  const tmp<FieldField<Field, Type1>>& tf1, \
492  const Type2& s \
493 ) \
494 { \
495  tmp<FieldField<Field, ReturnType>> tres \
496  ( \
497  reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1) \
498  ); \
499  OpFunc(tres.ref(), tf1(), s); \
500  tf1.clear(); \
501  return tres; \
502 }
503 
504 
505 #define BINARY_TYPE_OPERATOR(ReturnType, Type1, Type2, Op, OpFunc) \
506  BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpFunc) \
507  BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc)
508 
509 // ************************************************************************* //
High performance macro functions for Field<Type> algebra. These expand using either array element acc...