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