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-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 \*---------------------------------------------------------------------------*/
28 
29 #include "FieldM.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 #define UNARY_FUNCTION(ReturnType, Type1, Func) \
35  \
36 TEMPLATE \
37 void Func \
38 ( \
39  FieldField<Field, ReturnType>& result, \
40  const FieldField<Field, Type1>& f1 \
41 ) \
42 { \
43  const label loopLen = (result).size(); \
44  \
45  for (label i = 0; i < loopLen; ++i) \
46  { \
47  Func(result[i], f1[i]); \
48  } \
49 } \
50  \
51 TEMPLATE \
52 tmp<FieldField<Field, ReturnType>> Func \
53 ( \
54  const FieldField<Field, Type1>& f1 \
55 ) \
56 { \
57  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
58  Func(tres.ref(), f1); \
59  return tres; \
60 } \
61  \
62 TEMPLATE \
63 tmp<FieldField<Field, ReturnType>> Func \
64 ( \
65  const tmp<FieldField<Field, Type1>>& tf1 \
66 ) \
67 { \
68  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
69  Func(tres.ref(), tf1()); \
70  tf1.clear(); \
71  return tres; \
72 }
73 
74 
75 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
76 
77 #define UNARY_OPERATOR(ReturnType, Type1, Op, OpFunc) \
78  \
79 TEMPLATE \
80 void OpFunc \
81 ( \
82  FieldField<Field, ReturnType>& result, \
83  const FieldField<Field, Type1>& f1 \
84 ) \
85 { \
86  const label loopLen = (result).size(); \
87  \
88  for (label i = 0; i < loopLen; ++i) \
89  { \
90  OpFunc(result[i], f1[i]); \
91  } \
92 } \
93  \
94 TEMPLATE \
95 tmp<FieldField<Field, ReturnType>> operator Op \
96 ( \
97  const FieldField<Field, Type1>& f1 \
98 ) \
99 { \
100  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
101  OpFunc(tres.ref(), f1); \
102  return tres; \
103 } \
104  \
105 TEMPLATE \
106 tmp<FieldField<Field, ReturnType>> operator Op \
107 ( \
108  const tmp<FieldField<Field, Type1>>& tf1 \
109 ) \
110 { \
111  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
112  OpFunc(tres.ref(), tf1()); \
113  tf1.clear(); \
114  return tres; \
115 }
116 
117 
118 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
119 
120 #define BINARY_FUNCTION(ReturnType, Type1, Type2, Func) \
121  \
122 TEMPLATE \
123 void Func \
124 ( \
125  FieldField<Field, ReturnType>& result, \
126  const FieldField<Field, Type1>& f1, \
127  const FieldField<Field, Type2>& f2 \
128 ) \
129 { \
130  const label loopLen = (result).size(); \
131  \
132  for (label i = 0; i < loopLen; ++i) \
133  { \
134  Func(result[i], f1[i], f2[i]); \
135  } \
136 } \
137  \
138 TEMPLATE \
139 tmp<FieldField<Field, ReturnType>> Func \
140 ( \
141  const FieldField<Field, Type1>& f1, \
142  const FieldField<Field, Type2>& f2 \
143 ) \
144 { \
145  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
146  Func(tres.ref(), f1, f2); \
147  return tres; \
148 } \
149  \
150 TEMPLATE \
151 tmp<FieldField<Field, ReturnType>> Func \
152 ( \
153  const FieldField<Field, Type1>& f1, \
154  const tmp<FieldField<Field, Type2>>& tf2 \
155 ) \
156 { \
157  auto tres = reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2); \
158  Func(tres.ref(), f1, tf2()); \
159  tf2.clear(); \
160  return tres; \
161 } \
162  \
163 TEMPLATE \
164 tmp<FieldField<Field, ReturnType>> Func \
165 ( \
166  const tmp<FieldField<Field, Type1>>& tf1, \
167  const FieldField<Field, Type2>& f2 \
168 ) \
169 { \
170  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
171  Func(tres.ref(), tf1(), f2); \
172  tf1.clear(); \
173  return tres; \
174 } \
175  \
176 TEMPLATE \
177 tmp<FieldField<Field, ReturnType>> Func \
178 ( \
179  const tmp<FieldField<Field, Type1>>& tf1, \
180  const tmp<FieldField<Field, Type2>>& tf2 \
181 ) \
182 { \
183  auto tres \
184  ( \
185  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
186  New(tf1, tf2) \
187  ); \
188  Func(tres.ref(), tf1(), tf2()); \
189  tf1.clear(); \
190  tf2.clear(); \
191  return tres; \
192 }
193 
194 
195 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
196 
197 #define BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
198  \
199 TEMPLATE \
200 void Func \
201 ( \
202  FieldField<Field, ReturnType>& result, \
203  const Type1& s1, \
204  const FieldField<Field, Type2>& f2 \
205 ) \
206 { \
207  const label loopLen = (result).size(); \
208  \
209  for (label i = 0; i < loopLen; ++i) \
210  { \
211  Func(result[i], s1, f2[i]); \
212  } \
213 } \
214  \
215 TEMPLATE \
216 tmp<FieldField<Field, ReturnType>> Func \
217 ( \
218  const Type1& s1, \
219  const FieldField<Field, Type2>& f2 \
220 ) \
221 { \
222  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f2); \
223  Func(tres.ref(), s1, f2); \
224  return tres; \
225 } \
226  \
227 TEMPLATE \
228 tmp<FieldField<Field, ReturnType>> Func \
229 ( \
230  const Type1& s1, \
231  const tmp<FieldField<Field, Type2>>& tf2 \
232 ) \
233 { \
234  auto tres = reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2); \
235  Func(tres.ref(), s1, tf2()); \
236  tf2.clear(); \
237  return tres; \
238 }
239 
240 
241 #define BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func) \
242  \
243 TEMPLATE \
244 void Func \
245 ( \
246  FieldField<Field, ReturnType>& result, \
247  const FieldField<Field, Type1>& f1, \
248  const Type2& s2 \
249 ) \
250 { \
251  const label loopLen = (result).size(); \
252  \
253  for (label i = 0; i < loopLen; ++i) \
254  { \
255  Func(result[i], f1[i], s2); \
256  } \
257 } \
258  \
259 TEMPLATE \
260 tmp<FieldField<Field, ReturnType>> Func \
261 ( \
262  const FieldField<Field, Type1>& f1, \
263  const Type2& s2 \
264 ) \
265 { \
266  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
267  Func(tres.ref(), f1, s2); \
268  return tres; \
269 } \
270  \
271 TEMPLATE \
272 tmp<FieldField<Field, ReturnType>> Func \
273 ( \
274  const tmp<FieldField<Field, Type1>>& tf1, \
275  const Type2& s2 \
276 ) \
277 { \
278  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
279  Func(tres.ref(), tf1(), s2); \
280  tf1.clear(); \
281  return tres; \
282 }
283 
284 
285 #define BINARY_TYPE_FUNCTION(ReturnType, Type1, Type2, Func) \
286  BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
287  BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func)
288 
289 
290 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
291 
292 #define BINARY_OPERATOR(ReturnType, Type1, Type2, Op, OpFunc) \
293  \
294 TEMPLATE \
295 void OpFunc \
296 ( \
297  FieldField<Field, ReturnType>& result, \
298  const FieldField<Field, Type1>& f1, \
299  const FieldField<Field, Type2>& f2 \
300 ) \
301 { \
302  const label loopLen = (result).size(); \
303  \
304  for (label i = 0; i < loopLen; ++i) \
305  { \
306  OpFunc(result[i], f1[i], f2[i]); \
307  } \
308 } \
309  \
310 TEMPLATE \
311 tmp<FieldField<Field, ReturnType>> operator Op \
312 ( \
313  const FieldField<Field, Type1>& f1, \
314  const FieldField<Field, Type2>& f2 \
315 ) \
316 { \
317  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
318  OpFunc(tres.ref(), f1, f2); \
319  return tres; \
320 } \
321  \
322 TEMPLATE \
323 tmp<FieldField<Field, ReturnType>> operator Op \
324 ( \
325  const FieldField<Field, Type1>& f1, \
326  const tmp<FieldField<Field, Type2>>& tf2 \
327 ) \
328 { \
329  auto tres = reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2); \
330  OpFunc(tres.ref(), f1, tf2()); \
331  tf2.clear(); \
332  return tres; \
333 } \
334  \
335 TEMPLATE \
336 tmp<FieldField<Field, ReturnType>> operator Op \
337 ( \
338  const tmp<FieldField<Field, Type1>>& tf1, \
339  const FieldField<Field, Type2>& f2 \
340 ) \
341 { \
342  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
343  OpFunc(tres.ref(), tf1(), f2); \
344  tf1.clear(); \
345  return tres; \
346 } \
347  \
348 TEMPLATE \
349 tmp<FieldField<Field, ReturnType>> operator Op \
350 ( \
351  const tmp<FieldField<Field, Type1>>& tf1, \
352  const tmp<FieldField<Field, Type2>>& tf2 \
353 ) \
354 { \
355  auto tres \
356  ( \
357  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
358  New(tf1, tf2) \
359  ); \
360  OpFunc(tres.ref(), tf1(), tf2()); \
361  tf1.clear(); \
362  tf2.clear(); \
363  return tres; \
364 }
365 
366 
367 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
368 
369 #define BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpFunc) \
370  \
371 TEMPLATE \
372 void OpFunc \
373 ( \
374  FieldField<Field, ReturnType>& result, \
375  const Type1& s1, \
376  const FieldField<Field, Type2>& f2 \
377 ) \
378 { \
379  const label loopLen = (result).size(); \
380  \
381  for (label i = 0; i < loopLen; ++i) \
382  { \
383  OpFunc(result[i], s1, f2[i]); \
384  } \
385 } \
386  \
387 TEMPLATE \
388 tmp<FieldField<Field, ReturnType>> operator Op \
389 ( \
390  const Type1& s1, \
391  const FieldField<Field, Type2>& f2 \
392 ) \
393 { \
394  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f2); \
395  OpFunc(tres.ref(), s1, f2); \
396  return tres; \
397 } \
398  \
399 TEMPLATE \
400 tmp<FieldField<Field, ReturnType>> operator Op \
401 ( \
402  const Type1& s1, \
403  const tmp<FieldField<Field, Type2>>& tf2 \
404 ) \
405 { \
406  auto tres = reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2); \
407  OpFunc(tres.ref(), s1, tf2()); \
408  tf2.clear(); \
409  return tres; \
410 }
411 
412 
413 #define BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) \
414  \
415 TEMPLATE \
416 void OpFunc \
417 ( \
418  FieldField<Field, ReturnType>& result, \
419  const FieldField<Field, Type1>& f1, \
420  const Type2& s2 \
421 ) \
422 { \
423  const label loopLen = (result).size(); \
424  \
425  for (label i = 0; i < loopLen; ++i) \
426  { \
427  OpFunc(result[i], f1[i], s2); \
428  } \
429 } \
430  \
431 TEMPLATE \
432 tmp<FieldField<Field, ReturnType>> operator Op \
433 ( \
434  const FieldField<Field, Type1>& f1, \
435  const Type2& s2 \
436 ) \
437 { \
438  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
439  OpFunc(tres.ref(), f1, s2); \
440  return tres; \
441 } \
442  \
443 TEMPLATE \
444 tmp<FieldField<Field, ReturnType>> operator Op \
445 ( \
446  const tmp<FieldField<Field, Type1>>& tf1, \
447  const Type2& s2 \
448 ) \
449 { \
450  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
451  OpFunc(tres.ref(), tf1(), s2); \
452  tf1.clear(); \
453  return tres; \
454 }
455 
456 
457 #define BINARY_TYPE_OPERATOR(ReturnType, Type1, Type2, Op, OpFunc) \
458  BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpFunc) \
459  BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc)
460 
461 
462 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
463 
464 #define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \
465  \
466 TEMPLATE \
467 void Func \
468 ( \
469  FieldField<Field, ReturnType>& result, \
470  const FieldField<Field, Type1>& f1, \
471  const FieldField<Field, Type2>& f2, \
472  const FieldField<Field, Type3>& f3 \
473 ) \
474 { \
475  const label loopLen = (result).size(); \
476  \
477  for (label i = 0; i < loopLen; ++i) \
478  { \
479  Func(result[i], f1[i], f2[i], f3[i]); \
480  } \
481 } \
482  \
483 TEMPLATE \
484 tmp<FieldField<Field, ReturnType>> Func \
485 ( \
486  const FieldField<Field, Type1>& f1, \
487  const FieldField<Field, Type2>& f2, \
488  const FieldField<Field, Type3>& f3 \
489 ) \
490 { \
491  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
492  Func(tres.ref(), f1, f2, f3); \
493  return tres; \
494 } \
495  \
496 TEMPLATE \
497 tmp<FieldField<Field, ReturnType>> Func \
498 ( \
499  const tmp<FieldField<Field, Type1>>& tf1, \
500  const FieldField<Field, Type2>& f2, \
501  const FieldField<Field, Type3>& f3 \
502 ) \
503 { \
504  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
505  Func(tres.ref(), tf1(), f2, f3); \
506  tf1.clear(); \
507  return tres; \
508 } \
509  \
510 TEMPLATE \
511 tmp<FieldField<Field, ReturnType>> Func \
512 ( \
513  const FieldField<Field, Type1>& f1, \
514  const tmp<FieldField<Field, Type2>>& tf2, \
515  const FieldField<Field, Type3>& f3 \
516 ) \
517 { \
518  auto tres = reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2); \
519  Func(tres.ref(), f1, tf2(), f3); \
520  tf2.clear(); \
521  return tres; \
522 } \
523  \
524 TEMPLATE \
525 tmp<FieldField<Field, ReturnType>> Func \
526 ( \
527  const FieldField<Field, Type1>& f1, \
528  const FieldField<Field, Type2>& f2, \
529  const tmp<FieldField<Field, Type3>>& tf3 \
530 ) \
531 { \
532  auto tres = reuseTmpFieldField<Field, ReturnType, Type3>::New(tf3); \
533  Func(tres.ref(), f1, f2, tf3()); \
534  tf3.clear(); \
535  return tres; \
536 } \
537  \
538 TEMPLATE \
539 tmp<FieldField<Field, ReturnType>> Func \
540 ( \
541  const tmp<FieldField<Field, Type1>>& tf1, \
542  const tmp<FieldField<Field, Type2>>& tf2, \
543  const FieldField<Field, Type3>& f3 \
544 ) \
545 { \
546  tmp<FieldField<Field, ReturnType>> tres \
547  ( \
548  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
549  New(tf1, tf2) \
550  ); \
551  Func(tres.ref(), tf1(), tf2(), f3); \
552  tf1.clear(); \
553  tf2.clear(); \
554  return tres; \
555 } \
556  \
557 TEMPLATE \
558 tmp<FieldField<Field, ReturnType>> Func \
559 ( \
560  const tmp<FieldField<Field, Type1>>& tf1, \
561  const FieldField<Field, Type2>& f2, \
562  const tmp<FieldField<Field, Type3>>& tf3 \
563 ) \
564 { \
565  tmp<FieldField<Field, ReturnType>> tres \
566  ( \
567  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type3>:: \
568  New(tf1, tf3) \
569  ); \
570  Func(tres.ref(), tf1(), f2, tf3()); \
571  tf1.clear(); \
572  tf3.clear(); \
573  return tres; \
574 } \
575  \
576 TEMPLATE \
577 tmp<FieldField<Field, ReturnType>> Func \
578 ( \
579  const FieldField<Field, Type1>& f1, \
580  const tmp<FieldField<Field, Type2>>& tf2, \
581  const tmp<FieldField<Field, Type3>>& tf3 \
582 ) \
583 { \
584  tmp<FieldField<Field, ReturnType>> tres \
585  ( \
586  reuseTmpTmpFieldField<Field, ReturnType, Type2, Type2, Type3>:: \
587  New(tf2, tf3) \
588  ); \
589  Func(tres.ref(), f1, tf2(), tf3()); \
590  tf2.clear(); \
591  tf3.clear(); \
592  return tres; \
593 } \
594  \
595 TEMPLATE \
596 tmp<FieldField<Field, ReturnType>> Func \
597 ( \
598  const tmp<FieldField<Field, Type1>>& tf1, \
599  const tmp<FieldField<Field, Type2>>& tf2, \
600  const tmp<FieldField<Field, Type3>>& tf3 \
601 ) \
602 { \
603  /* TBD: check all three types? */ \
604  tmp<FieldField<Field, ReturnType>> tres \
605  ( \
606  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
607  New(tf1, tf2) \
608  ); \
609  Func(tres.ref(), tf1(), tf2(), tf3()); \
610  tf1.clear(); \
611  tf2.clear(); \
612  tf3.clear(); \
613  return tres; \
614 }
615 
616 
617 #define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \
618  \
619 TEMPLATE \
620 void Func \
621 ( \
622  FieldField<Field, ReturnType>& result, \
623  const FieldField<Field, Type1>& f1, \
624  const FieldField<Field, Type2>& f2, \
625  const Type3& s3 \
626 ) \
627 { \
628  const label loopLen = (result).size(); \
629  \
630  for (label i = 0; i < loopLen; ++i) \
631  { \
632  Func(result[i], f1[i], f2[i], s3); \
633  } \
634 } \
635  \
636 TEMPLATE \
637 tmp<FieldField<Field, ReturnType>> Func \
638 ( \
639  const FieldField<Field, Type1>& f1, \
640  const FieldField<Field, Type2>& f2, \
641  const Type3& s3 \
642 ) \
643 { \
644  auto tres = FieldField<Field, ReturnType>::NewCalculatedType(f1); \
645  Func(tres.ref(), f1, f2, s3); \
646  return tres; \
647 } \
648  \
649 TEMPLATE \
650 tmp<FieldField<Field, ReturnType>> Func \
651 ( \
652  const tmp<FieldField<Field, Type1>>& tf1, \
653  const FieldField<Field, Type2>& f2, \
654  const Type3& s3 \
655 ) \
656 { \
657  auto tres = reuseTmpFieldField<Field, ReturnType, Type1>::New(tf1); \
658  Func(tres.ref(), tf1(), f2, s3); \
659  tf1.clear(); \
660  return tres; \
661 } \
662  \
663 TEMPLATE \
664 tmp<FieldField<Field, ReturnType>> Func \
665 ( \
666  const FieldField<Field, Type1>& f1, \
667  const tmp<FieldField<Field, Type2>>& tf2, \
668  const Type3& s3 \
669 ) \
670 { \
671  auto tres = reuseTmpFieldField<Field, ReturnType, Type2>::New(tf2); \
672  Func(tres.ref(), f1, tf2(), s3); \
673  tf2.clear(); \
674  return tres; \
675 } \
676  \
677 TEMPLATE \
678 tmp<FieldField<Field, ReturnType>> Func \
679 ( \
680  const tmp<FieldField<Field, Type1>>& tf1, \
681  const tmp<FieldField<Field, Type2>>& tf2, \
682  const Type3& s3 \
683 ) \
684 { \
685  tmp<FieldField<Field, ReturnType>> tres \
686  ( \
687  reuseTmpTmpFieldField<Field, ReturnType, Type1, Type1, Type2>:: \
688  New(tf1, tf2) \
689  ); \
690  Func(tres.ref(), tf1(), tf2(), s3); \
691  tf1.clear(); \
692  tf2.clear(); \
693  return tres; \
694 }
695 
696 
697 // ************************************************************************* //
Declaration macros for Field<Type> algebra.