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