DimensionedFieldFunctionsM.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-2016 OpenFOAM Foundation
9  Copyright (C) 2019-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 
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 #define UNARY_FUNCTION(ReturnType, Type1, Func, Dfunc) \
34  \
35 TEMPLATE \
36 void Func \
37 ( \
38  DimensionedField<ReturnType, GeoMesh>& result, \
39  const DimensionedField<Type1, GeoMesh>& f1 \
40 ) \
41 { \
42  /* TBD: reset dimensions? */ \
43  Func(result.field(), f1.field()); \
44  result.oriented() = Dfunc(f1.oriented()); \
45 } \
46  \
47 TEMPLATE \
48 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
49 ( \
50  const DimensionedField<Type1, GeoMesh>& f1 \
51 ) \
52 { \
53  auto tres = \
54  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
55  ( \
56  f1, \
57  #Func "(" + f1.name() + ')', \
58  Dfunc(f1.dimensions()) \
59  ); \
60  \
61  Foam::Func(tres.ref(), f1); \
62  return tres; \
63 } \
64  \
65  \
66 TEMPLATE \
67 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
68 ( \
69  const tmp<DimensionedField<Type1, GeoMesh>>& tf1 \
70 ) \
71 { \
72  const auto& f1 = tf1(); \
73  \
74  auto tres = \
75  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
76  ( \
77  tf1, \
78  #Func "(" + f1.name() + ')', \
79  Dfunc(f1.dimensions()) \
80  ); \
81  \
82  Foam::Func(tres.ref(), f1); \
83  tf1.clear(); \
84  return tres; \
85 }
86 
87 
88 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
89 
90 #define UNARY_OPERATOR(ReturnType, Type1, Op, OpFunc, Dfunc) \
91  \
92 TEMPLATE \
93 void OpFunc \
94 ( \
95  DimensionedField<ReturnType, GeoMesh>& result, \
96  const DimensionedField<Type1, GeoMesh>& f1 \
97 ) \
98 { \
99  /* TBD: reset dimensions? */ \
100  Foam::OpFunc(result.field(), f1.field()); \
101  result.oriented() = Dfunc(f1.oriented()); \
102 } \
103  \
104 TEMPLATE \
105 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
106 ( \
107  const DimensionedField<Type1, GeoMesh>& f1 \
108 ) \
109 { \
110  auto tres = \
111  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
112  ( \
113  f1, \
114  #Op + f1.name(), \
115  Dfunc(f1.dimensions()) \
116  ); \
117  \
118  Foam::OpFunc(tres.ref(), f1); \
119  return tres; \
120 } \
121  \
122  \
123 TEMPLATE \
124 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
125 ( \
126  const tmp<DimensionedField<Type1, GeoMesh>>& tf1 \
127 ) \
128 { \
129  const auto& f1 = tf1(); \
130  \
131  auto tres = \
132  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
133  ( \
134  tf1, \
135  #Op + f1.name(), \
136  Dfunc(f1.dimensions()) \
137  ); \
138  \
139  Foam::OpFunc(tres.ref(), f1); \
140  tf1.clear(); \
141  return tres; \
142 }
143 
144 
145 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
146 
147 #define BINARY_FUNCTION(ReturnType, Type1, Type2, Func) \
148  \
149 TEMPLATE \
150 void Func \
151 ( \
152  DimensionedField<ReturnType, GeoMesh>& result, \
153  const DimensionedField<Type1, GeoMesh>& f1, \
154  const DimensionedField<Type2, GeoMesh>& f2 \
155 ) \
156 { \
157  /* TBD: reset dimensions? */ \
158  Foam::Func(result.field(), f1.field(), f2.field()); \
159  result.oriented() = Func(f1.oriented(), f2.oriented()); \
160 } \
161  \
162 TEMPLATE \
163 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
164 ( \
165  const DimensionedField<Type1, GeoMesh>& f1, \
166  const DimensionedField<Type2, GeoMesh>& f2 \
167 ) \
168 { \
169  auto tres = \
170  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
171  ( \
172  f1, \
173  #Func "(" + f1.name() + ',' + f2.name() + ')', \
174  Func(f1.dimensions(), f2.dimensions()) \
175  ); \
176  \
177  Foam::Func(tres.ref(), f1, f2); \
178  return tres; \
179 } \
180  \
181  \
182 TEMPLATE \
183 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
184 ( \
185  const DimensionedField<Type1, GeoMesh>& f1, \
186  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
187 ) \
188 { \
189  const auto& f2 = tf2(); \
190  \
191  auto tres = \
192  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
193  ( \
194  tf2, \
195  #Func "(" + f1.name() + ',' + f2.name() + ')', \
196  Func(f1.dimensions(), f2.dimensions()) \
197  ); \
198  \
199  Foam::Func(tres.ref(), f1, f2); \
200  tf2.clear(); \
201  return tres; \
202 } \
203  \
204  \
205 TEMPLATE \
206 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
207 ( \
208  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
209  const DimensionedField<Type2, GeoMesh>& f2 \
210 ) \
211 { \
212  const auto& f1 = tf1(); \
213  \
214  auto tres = \
215  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
216  ( \
217  tf1, \
218  #Func "(" + f1.name() + ',' + f2.name() + ')', \
219  Func(f1.dimensions(), f2.dimensions()) \
220  ); \
221  \
222  Foam::Func(tres.ref(), f1, f2); \
223  tf1.clear(); \
224  return tres; \
225 } \
226  \
227  \
228 TEMPLATE \
229 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
230 ( \
231  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
232  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
233 ) \
234 { \
235  const auto& f1 = tf1(); \
236  const auto& f2 = tf2(); \
237  \
238  auto tres = \
239  reuseTmpTmpDimensionedField \
240  <ReturnType, Type1, Type1, Type2, GeoMesh>::New \
241  ( \
242  tf1, \
243  tf2, \
244  #Func "(" + f1.name() + ',' + f2.name() + ')', \
245  Func(f1.dimensions(), f2.dimensions()) \
246  ); \
247  \
248  Foam::Func(tres.ref(), f1, f2); \
249  tf1.clear(); \
250  tf2.clear(); \
251  return tres; \
252 }
253 
254 
255 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
256 
257 #define BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
258  \
259 TEMPLATE \
260 void Func \
261 ( \
262  DimensionedField<ReturnType, GeoMesh>& result, \
263  const dimensioned<Type1>& dt1, \
264  const DimensionedField<Type2, GeoMesh>& f2 \
265 ) \
266 { \
267  /* TBD: reset dimensions? */ \
268  Func(result.field(), dt1.value(), f2.field()); \
269  result.oriented() = f2.oriented(); \
270 } \
271  \
272 TEMPLATE \
273 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
274 ( \
275  const dimensioned<Type1>& dt1, \
276  const DimensionedField<Type2, GeoMesh>& f2 \
277 ) \
278 { \
279  auto tres = \
280  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
281  ( \
282  f2, \
283  #Func "(" + dt1.name() + ',' + f2.name() + ')', \
284  Func(dt1.dimensions(), f2.dimensions()) \
285  ); \
286  \
287  Foam::Func(tres.ref(), dt1, f2); \
288  return tres; \
289 } \
290  \
291  \
292 TEMPLATE \
293 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
294 ( \
295  const Type1& s1, \
296  const DimensionedField<Type2, GeoMesh>& f2 \
297 ) \
298 { \
299  return Foam::Func(dimensioned<Type1>(s1), f2); \
300 } \
301  \
302  \
303 TEMPLATE \
304 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
305 ( \
306  const dimensioned<Type1>& dt1, \
307  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
308 ) \
309 { \
310  const auto& f2 = tf2(); \
311  \
312  auto tres = \
313  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
314  ( \
315  tf2, \
316  #Func "(" + dt1.name() + ',' + f2.name() + ')', \
317  Func(dt1.dimensions(), f2.dimensions()) \
318  ); \
319  \
320  Foam::Func(tres.ref(), dt1, f2); \
321  tf2.clear(); \
322  return tres; \
323 } \
324  \
325 TEMPLATE \
326 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
327 ( \
328  const Type1& s1, \
329  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
330 ) \
331 { \
332  return Foam::Func(dimensioned<Type2>(s1), tf2); \
333 }
334 
335 
336 #define BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func) \
337  \
338 TEMPLATE \
339 void Func \
340 ( \
341  DimensionedField<ReturnType, GeoMesh>& result, \
342  const DimensionedField<Type1, GeoMesh>& f1, \
343  const dimensioned<Type2>& dt2 \
344 ) \
345 { \
346  /* TBD: reset dimensions? */ \
347  Func(result.field(), f1.field(), dt2.value()); \
348  result.oriented() = f1.oriented(); \
349 } \
350  \
351 TEMPLATE \
352 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
353 ( \
354  const DimensionedField<Type1, GeoMesh>& f1, \
355  const dimensioned<Type2>& dt2 \
356 ) \
357 { \
358  auto tres = \
359  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
360  ( \
361  f1, \
362  #Func "(" + f1.name() + ',' + dt2.name() + ')', \
363  Func(f1.dimensions(), dt2.dimensions()) \
364  ); \
365  \
366  Foam::Func(tres.ref(), f1, dt2); \
367  return tres; \
368 } \
369  \
370  \
371 TEMPLATE \
372 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
373 ( \
374  const DimensionedField<Type1, GeoMesh>& f1, \
375  const Type2& s2 \
376 ) \
377 { \
378  return Foam::Func(f1, dimensioned<Type2>(s2)); \
379 } \
380  \
381  \
382 TEMPLATE \
383 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
384 ( \
385  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
386  const dimensioned<Type2>& dt2 \
387 ) \
388 { \
389  const auto& f1 = tf1(); \
390  \
391  auto tres = \
392  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
393  ( \
394  tf1, \
395  #Func "(" + f1.name() + ',' + dt2.name() + ')', \
396  Func(f1.dimensions(), dt2.dimensions()) \
397  ); \
398  \
399  Foam::Func(tres.ref(), f1, dt2); \
400  tf1.clear(); \
401  return tres; \
402 } \
403  \
404  \
405 TEMPLATE \
406 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
407 ( \
408  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
409  const Type2& s2 \
410 ) \
411 { \
412  return Foam::Func(tf1, dimensioned<Type2>(s2)); \
413 }
414 
415 
416 #define BINARY_TYPE_FUNCTION(ReturnType, Type1, Type2, Func) \
417  BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
418  BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func)
419 
420 
421 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
422 
423 #define BINARY_OPERATOR(ReturnType, Type1, Type2, Op, OpName, OpFunc) \
424  \
425 TEMPLATE \
426 void OpFunc \
427 ( \
428  DimensionedField<ReturnType, GeoMesh>& result, \
429  const DimensionedField<Type1, GeoMesh>& f1, \
430  const DimensionedField<Type2, GeoMesh>& f2 \
431 ) \
432 { \
433  /* TBD: reset dimensions? */ \
434  Foam::OpFunc(result.field(), f1.field(), f2.field()); \
435  result.oriented() = f1.oriented() Op f2.oriented(); \
436 } \
437  \
438  \
439 TEMPLATE \
440 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
441 ( \
442  const DimensionedField<Type1, GeoMesh>& f1, \
443  const DimensionedField<Type2, GeoMesh>& f2 \
444 ) \
445 { \
446  auto tres = \
447  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
448  ( \
449  f1, \
450  '(' + f1.name() + OpName + f2.name() + ')', \
451  (f1.dimensions() Op f2.dimensions()) \
452  ); \
453  \
454  Foam::OpFunc(tres.ref(), f1, f2); \
455  return tres; \
456 } \
457  \
458  \
459 TEMPLATE \
460 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
461 ( \
462  const DimensionedField<Type1, GeoMesh>& f1, \
463  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
464 ) \
465 { \
466  const auto& f2 = tf2(); \
467  \
468  auto tres = \
469  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
470  ( \
471  tf2, \
472  '(' + f1.name() + OpName + f2.name() + ')', \
473  (f1.dimensions() Op f2.dimensions()) \
474  ); \
475  \
476  Foam::OpFunc(tres.ref(), f1, f2); \
477  tf2.clear(); \
478  return tres; \
479 } \
480  \
481  \
482 TEMPLATE \
483 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
484 ( \
485  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
486  const DimensionedField<Type2, GeoMesh>& f2 \
487 ) \
488 { \
489  const auto& f1 = tf1(); \
490  \
491  auto tres = \
492  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
493  ( \
494  tf1, \
495  '(' + f1.name() + OpName + f2.name() + ')', \
496  (f1.dimensions() Op f2.dimensions()) \
497  ); \
498  \
499  Foam::OpFunc(tres.ref(), f1, f2); \
500  tf1.clear(); \
501  return tres; \
502 } \
503  \
504 TEMPLATE \
505 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
506 ( \
507  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
508  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
509 ) \
510 { \
511  const auto& f1 = tf1(); \
512  const auto& f2 = tf2(); \
513  \
514  auto tres = \
515  reuseTmpTmpDimensionedField \
516  <ReturnType, Type1, Type1, Type2, GeoMesh>::New \
517  ( \
518  tf1, \
519  tf2, \
520  '(' + f1.name() + OpName + f2.name() + ')', \
521  f1.dimensions() Op f2.dimensions() \
522  ); \
523  \
524  Foam::OpFunc(tres.ref(), f1, f2); \
525  tf1.clear(); \
526  tf2.clear(); \
527  return tres; \
528 }
529 
530 
531 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
532 
533 #define BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpName, OpFunc) \
534  \
535 TEMPLATE \
536 void OpFunc \
537 ( \
538  DimensionedField<ReturnType, GeoMesh>& result, \
539  const dimensioned<Type1>& dt1, \
540  const DimensionedField<Type2, GeoMesh>& f2 \
541 ) \
542 { \
543  /* TBD: reset dimensions? */ \
544  Foam::OpFunc(result.field(), dt1.value(), f2.field()); \
545  result.oriented() = f2.oriented(); \
546 } \
547  \
548 TEMPLATE \
549 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
550 ( \
551  const dimensioned<Type1>& dt1, \
552  const DimensionedField<Type2, GeoMesh>& f2 \
553 ) \
554 { \
555  auto tres = \
556  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
557  ( \
558  f2, \
559  '(' + dt1.name() + OpName + f2.name() + ')', \
560  (dt1.dimensions() Op f2.dimensions()) \
561  ); \
562  \
563  Foam::OpFunc(tres.ref(), dt1, f2); \
564  return tres; \
565 } \
566  \
567  \
568 TEMPLATE \
569 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
570 ( \
571  const Type1& s1, \
572  const DimensionedField<Type2, GeoMesh>& f2 \
573 ) \
574 { \
575  return dimensioned<Type1>(s1) Op f2; \
576 } \
577  \
578  \
579 TEMPLATE \
580 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
581 ( \
582  const dimensioned<Type1>& dt1, \
583  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
584 ) \
585 { \
586  const auto& f2 = tf2(); \
587  \
588  auto tres = \
589  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
590  ( \
591  tf2, \
592  '(' + dt1.name() + OpName + f2.name() + ')', \
593  (dt1.dimensions() Op f2.dimensions()) \
594  ); \
595  \
596  Foam::OpFunc(tres.ref(), dt1, f2); \
597  tf2.clear(); \
598  return tres; \
599 } \
600  \
601  \
602 TEMPLATE \
603 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
604 ( \
605  const Type1& s1, \
606  const tmp<DimensionedField<Type2, GeoMesh>>& tf2 \
607 ) \
608 { \
609  return dimensioned<Type1>(s1) Op tf2; \
610 }
611 
612 
613 #define BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpName, OpFunc) \
614  \
615 TEMPLATE \
616 void OpFunc \
617 ( \
618  DimensionedField<ReturnType, GeoMesh>& result, \
619  const DimensionedField<Type1, GeoMesh>& f1, \
620  const dimensioned<Type2>& dt2 \
621 ) \
622 { \
623  /* TBD: reset dimensions? */ \
624  Foam::OpFunc(result.field(), f1.field(), dt2.value()); \
625  result.oriented() = f1.oriented(); \
626 } \
627  \
628 TEMPLATE \
629 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
630 ( \
631  const DimensionedField<Type1, GeoMesh>& f1, \
632  const dimensioned<Type2>& dt2 \
633 ) \
634 { \
635  auto tres = \
636  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
637  ( \
638  f1, \
639  '(' + f1.name() + OpName + dt2.name() + ')', \
640  (f1.dimensions() Op dt2.dimensions()) \
641  ); \
642  \
643  Foam::OpFunc(tres.ref(), f1, dt2); \
644  return tres; \
645 } \
646  \
647  \
648 TEMPLATE \
649 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
650 ( \
651  const DimensionedField<Type1, GeoMesh>& f1, \
652  const Type2& s2 \
653 ) \
654 { \
655  return f1 Op dimensioned<Type2>(s2); \
656 } \
657  \
658  \
659 TEMPLATE \
660 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
661 ( \
662  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
663  const dimensioned<Type2>& dt2 \
664 ) \
665 { \
666  const auto& f1 = tf1(); \
667  \
668  auto tres = \
669  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
670  ( \
671  tf1, \
672  '(' + f1.name() + OpName + dt2.name() + ')', \
673  (f1.dimensions() Op dt2.dimensions()) \
674  ); \
675  \
676  Foam::OpFunc(tres.ref(), f1, dt2); \
677  tf1.clear(); \
678  return tres; \
679 } \
680  \
681  \
682 TEMPLATE \
683 tmp<DimensionedField<ReturnType, GeoMesh>> operator Op \
684 ( \
685  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
686  const Type2& s2 \
687 ) \
688 { \
689  return tf1 Op dimensioned<Type2>(s2); \
690 }
691 
692 #define BINARY_TYPE_OPERATOR(ReturnType, Type1, Type2, Op, OpName, OpFunc) \
693  BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpName, OpFunc) \
694  BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpName, OpFunc)
695 
696 
697 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
698 
699 #define TERNARY_FUNCTION(ReturnType, Type1, Type2, Type3, Func) \
700  \
701 TEMPLATE \
702 void Func \
703 ( \
704  DimensionedField<ReturnType, GeoMesh>& result, \
705  const DimensionedField<Type1, GeoMesh>& f1, \
706  const DimensionedField<Type2, GeoMesh>& f2, \
707  const DimensionedField<Type3, GeoMesh>& f3 \
708 ) \
709 { \
710  /* TBD: reset dimensions? */ \
711  Func(result.field(), f1.field(), f2.field(), f3.field()); \
712  result.oriented() = Func(f1.oriented(), f2.oriented()); \
713 } \
714  \
715 TEMPLATE \
716 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
717 ( \
718  const DimensionedField<Type1, GeoMesh>& f1, \
719  const DimensionedField<Type2, GeoMesh>& f2, \
720  const DimensionedField<Type3, GeoMesh>& f3 \
721 ) \
722 { \
723  auto tres = \
724  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
725  ( \
726  f1, \
727  #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \
728  Func(f1.dimensions(), f2.dimensions()) \
729  ); \
730  \
731  Func(tres.ref(), f1, f2, f3); \
732  return tres; \
733 } \
734  \
735 TEMPLATE \
736 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
737 ( \
738  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
739  const DimensionedField<Type2, GeoMesh>& f2, \
740  const DimensionedField<Type3, GeoMesh>& f3 \
741 ) \
742 { \
743  const auto& f1 = tf1(); \
744  \
745  auto tres = \
746  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
747  ( \
748  tf1, \
749  #Func "(" + f1.name() + ',' + f2.name() + ',' + f3.name() + ')', \
750  Func(f1.dimensions(), f2.dimensions()) \
751  ); \
752  \
753  Func(tres.ref(), f1, f2, f3); \
754  tf1.clear(); \
755  return tres; \
756 } \
757  \
758 TEMPLATE \
759 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
760 ( \
761  const DimensionedField<Type1, GeoMesh>& f1, \
762  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
763  const DimensionedField<Type3, GeoMesh>& f3 \
764 ) \
765 { \
766  const auto& f2 = tf2(); \
767  \
768  auto tres = \
769  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
770  ( \
771  tf2, \
772  #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \
773  Func(f1.dimensions(), f2.dimensions()) \
774  ); \
775  \
776  Func(tres.ref(), f1, f2, f3); \
777  tf2.clear(); \
778  return tres; \
779 } \
780  \
781 TEMPLATE \
782 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
783 ( \
784  const DimensionedField<Type1, GeoMesh>& f1, \
785  const DimensionedField<Type2, GeoMesh>& f2, \
786  const tmp<DimensionedField<Type3, GeoMesh>>& tf3 \
787 ) \
788 { \
789  const auto& f3 = tf3(); \
790  \
791  auto tres = \
792  reuseTmpDimensionedField<ReturnType, Type3, GeoMesh>::New \
793  ( \
794  tf3, \
795  #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \
796  Func(f1.dimensions(), f2.dimensions()) \
797  ); \
798  \
799  Func(tres.ref(), f1, f2, f3); \
800  tf3.clear(); \
801  return tres; \
802 } \
803  \
804  \
805 TEMPLATE \
806 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
807 ( \
808  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
809  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
810  const DimensionedField<Type3, GeoMesh>& f3 \
811 ) \
812 { \
813  const auto& f1 = tf1(); \
814  const auto& f2 = tf2(); \
815  \
816  auto tres = \
817  reuseTmpTmpDimensionedField \
818  <ReturnType, Type1, Type1, Type2, GeoMesh>::New \
819  ( \
820  tf1, \
821  tf2, \
822  #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \
823  Func(f1.dimensions(), f2.dimensions()) \
824  ); \
825  \
826  Func(tres.ref(), f1, f2, f3); \
827  tf1.clear(); \
828  tf2.clear(); \
829  return tres; \
830 } \
831  \
832 TEMPLATE \
833 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
834 ( \
835  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
836  const DimensionedField<Type2, GeoMesh>& f2, \
837  const tmp<DimensionedField<Type3, GeoMesh>>& tf3 \
838 ) \
839 { \
840  const auto& f1 = tf1(); \
841  const auto& f3 = tf3(); \
842  \
843  auto tres = \
844  reuseTmpTmpDimensionedField \
845  <ReturnType, Type1, Type1, Type3, GeoMesh>::New \
846  ( \
847  tf1, \
848  tf3, \
849  #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \
850  Func(f1.dimensions(), f2.dimensions()) \
851  ); \
852  \
853  Func(tres.ref(), f1, f2, f3); \
854  tf1.clear(); \
855  tf3.clear(); \
856  return tres; \
857 } \
858  \
859 TEMPLATE \
860 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
861 ( \
862  const DimensionedField<Type1, GeoMesh>& f1, \
863  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
864  const tmp<DimensionedField<Type3, GeoMesh>>& tf3 \
865 ) \
866 { \
867  const auto& f2 = tf2(); \
868  const auto& f3 = tf3(); \
869  \
870  auto tres = \
871  reuseTmpTmpDimensionedField \
872  <ReturnType, Type2, Type2, Type3, GeoMesh>::New \
873  ( \
874  tf2, \
875  tf3, \
876  #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \
877  Func(f1.dimensions(), f2.dimensions()) \
878  ); \
879  \
880  Func(tres.ref(), f1, f2, f3); \
881  tf2.clear(); \
882  tf3.clear(); \
883  return tres; \
884 } \
885  \
886 TEMPLATE \
887 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
888 ( \
889  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
890  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
891  const tmp<DimensionedField<Type3, GeoMesh>>& tf3 \
892 ) \
893 { \
894  const auto& f1 = tf1(); \
895  const auto& f2 = tf2(); \
896  const auto& f3 = tf3(); \
897  \
898  /* TBD: check all three types? */ \
899  auto tres = \
900  reuseTmpTmpDimensionedField \
901  <ReturnType, Type1, Type1, Type2, GeoMesh>::New \
902  ( \
903  tf1, \
904  tf2, \
905  #Func "(" + f1.name() +','+ f2.name() +','+ f3.name() +')', \
906  Func(f1.dimensions(), f2.dimensions()) \
907  ); \
908  \
909  Func(tres.ref(), f1, f2, f3); \
910  tf1.clear(); \
911  tf2.clear(); \
912  tf3.clear(); \
913  return tres; \
914 } \
915 
916 
917 #define TERNARY_TYPE_FUNCTION_FFS(ReturnType, Type1, Type2, Type3, Func) \
918  \
919 TEMPLATE \
920 void Func \
921 ( \
922  DimensionedField<ReturnType, GeoMesh>& result, \
923  const DimensionedField<Type1, GeoMesh>& f1, \
924  const DimensionedField<Type2, GeoMesh>& f2, \
925  const dimensioned<Type3>& dt3 \
926 ) \
927 { \
928  /* TBD: reset dimensions? */ \
929  Func(result.field(), f1.field(), f2.field(), dt3.value()); \
930  result.oriented() = Func(f1.oriented(), f2.oriented()); \
931 } \
932  \
933 TEMPLATE \
934 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
935 ( \
936  const DimensionedField<Type1, GeoMesh>& f1, \
937  const DimensionedField<Type2, GeoMesh>& f2, \
938  const dimensioned<Type3>& dt3 \
939 ) \
940 { \
941  auto tres = \
942  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
943  ( \
944  f1, \
945  #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \
946  Func(f1.dimensions(), f2.dimensions()) \
947  ); \
948  \
949  Func(tres.ref(), f1, f2, dt3); \
950  return tres; \
951 } \
952  \
953 TEMPLATE \
954 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
955 ( \
956  const DimensionedField<Type1, GeoMesh>& f1, \
957  const DimensionedField<Type2, GeoMesh>& f2, \
958  const Type3& s3 \
959 ) \
960 { \
961  return Func(f1, f2, dimensioned<Type3>(s3)); \
962 } \
963  \
964 TEMPLATE \
965 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
966 ( \
967  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
968  const DimensionedField<Type2, GeoMesh>& f2, \
969  const dimensioned<Type3>& dt3 \
970 ) \
971 { \
972  const auto& f1 = tf1(); \
973  \
974  auto tres = \
975  reuseTmpDimensionedField<ReturnType, Type1, GeoMesh>::New \
976  ( \
977  tf1, \
978  #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \
979  Func(f1.dimensions(), f2.dimensions()) \
980  ); \
981  \
982  Func(tres.ref(), f1, f2, dt3); \
983  tf1.clear(); \
984  return tres; \
985 } \
986  \
987 TEMPLATE \
988 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
989 ( \
990  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
991  const DimensionedField<Type2, GeoMesh>& f2, \
992  const Type3& s3 \
993 ) \
994 { \
995  return Func(tf1, f2, dimensioned<Type3>(s3)); \
996 } \
997  \
998 TEMPLATE \
999 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
1000 ( \
1001  const DimensionedField<Type1, GeoMesh>& f1, \
1002  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
1003  const dimensioned<Type3>& dt3 \
1004 ) \
1005 { \
1006  const auto& f2 = tf2(); \
1007  \
1008  auto tres = \
1009  reuseTmpDimensionedField<ReturnType, Type2, GeoMesh>::New \
1010  ( \
1011  tf2, \
1012  #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \
1013  Func(f1.dimensions(), f2.dimensions()) \
1014  ); \
1015  \
1016  Func(tres.ref(), f1, f2, dt3); \
1017  tf2.clear(); \
1018  return tres; \
1019 } \
1020  \
1021 TEMPLATE \
1022 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
1023 ( \
1024  const DimensionedField<Type1, GeoMesh>& f1, \
1025  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
1026  const Type3& s3 \
1027 ) \
1028 { \
1029  return Func(f1, tf2, dimensioned<Type3>(s3)); \
1030 } \
1031  \
1032 TEMPLATE \
1033 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
1034 ( \
1035  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
1036  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
1037  const dimensioned<Type3>& dt3 \
1038 ) \
1039 { \
1040  const auto& f1 = tf1(); \
1041  const auto& f2 = tf2(); \
1042  \
1043  auto tres = \
1044  reuseTmpTmpDimensionedField \
1045  <ReturnType, Type1, Type1, Type2, GeoMesh>::New \
1046  ( \
1047  tf1, \
1048  tf2, \
1049  #Func "(" + f1.name() + ',' + f2.name() + ',' + dt3.name() + ')', \
1050  Func(f1.dimensions(), f2.dimensions()) \
1051  ); \
1052  \
1053  Func(tres.ref(), f1, f2, dt3); \
1054  tf1.clear(); \
1055  tf2.clear(); \
1056  return tres; \
1057 } \
1058  \
1059 TEMPLATE \
1060 tmp<DimensionedField<ReturnType, GeoMesh>> Func \
1061 ( \
1062  const tmp<DimensionedField<Type1, GeoMesh>>& tf1, \
1063  const tmp<DimensionedField<Type2, GeoMesh>>& tf2, \
1064  const Type3& s3 \
1065 ) \
1066 { \
1067  return Func(tf1, tf2, dimensioned<Type3>(s3)); \
1068 }
1069 
1070 
1071 // ************************************************************************* //