FieldFunctionsM.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "FieldM.H"
27 #include "FieldReuseFunctions.H"
28 
29 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 
31 #define UNARY_FUNCTION(ReturnType, Type, Func) \
32  \
33 TEMPLATE \
34 void Func(Field<ReturnType>& res, const UList<Type>& f) \
35 { \
36  TFOR_ALL_F_OP_FUNC_F(ReturnType, res, =, ::Foam::Func, Type, f) \
37 } \
38  \
39 TEMPLATE \
40 tmp<Field<ReturnType>> Func(const Field<Type>& f) \
41 { \
42  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f.size())); \
43  Func(tRes.ref(), f); \
44  return tRes; \
45 } \
46  \
47 TEMPLATE \
48 tmp<Field<ReturnType>> Func(const SubField<Type>& f) \
49 { \
50  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f.size())); \
51  Func(tRes.ref(), f); \
52  return tRes; \
53 } \
54  \
55 TEMPLATE \
56 tmp<Field<ReturnType>> Func(const tmp<Field<Type>>& tf) \
57 { \
58  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type>::New(tf); \
59  Func(tRes.ref(), tf()); \
60  tf.clear(); \
61  return tRes; \
62 }
63 
64 
65 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66 
67 #define UNARY_OPERATOR(ReturnType, Type, Op, OpFunc) \
68  \
69 TEMPLATE \
70 void OpFunc(Field<ReturnType>& res, const UList<Type>& f) \
71 { \
72  TFOR_ALL_F_OP_OP_F(ReturnType, res, =, Op, Type, f) \
73 } \
74  \
75 TEMPLATE \
76 tmp<Field<ReturnType>> operator Op(const Field<Type>& f) \
77 { \
78  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f.size())); \
79  OpFunc(tRes.ref(), f); \
80  return tRes; \
81 } \
82  \
83 TEMPLATE \
84 tmp<Field<ReturnType>> operator Op(const SubField<Type>& f) \
85 { \
86  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f.size())); \
87  OpFunc(tRes.ref(), f); \
88  return tRes; \
89 } \
90  \
91 TEMPLATE \
92 tmp<Field<ReturnType>> operator Op(const tmp<Field<Type>>& tf) \
93 { \
94  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type>::New(tf); \
95  OpFunc(tRes.ref(), tf()); \
96  tf.clear(); \
97  return tRes; \
98 }
99 
100 
101 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
102 
103 #define BINARY_FUNCTION(ReturnType, Type1, Type2, Func) \
104  \
105 TEMPLATE \
106 void Func \
107 ( \
108  Field<ReturnType>& res, \
109  const UList<Type1>& f1, \
110  const UList<Type2>& f2 \
111 ) \
112 { \
113  TFOR_ALL_F_OP_FUNC_F_F \
114  ( \
115  ReturnType, res, =, ::Foam::Func, Type1, f1, Type2, f2 \
116  ) \
117 } \
118  \
119 TEMPLATE \
120 tmp<Field<ReturnType>> Func \
121 ( \
122  const Field<Type1>& f1, \
123  const Field<Type2>& f2 \
124 ) \
125 { \
126  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
127  Func(tRes.ref(), f1, f2); \
128  return tRes; \
129 } \
130  \
131 TEMPLATE \
132 tmp<Field<ReturnType>> Func \
133 ( \
134  const Field<Type1>& f1, \
135  const SubField<Type2>& f2 \
136 ) \
137 { \
138  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
139  Func(tRes.ref(), f1, f2); \
140  return tRes; \
141 } \
142  \
143 TEMPLATE \
144 tmp<Field<ReturnType>> Func \
145 ( \
146  const SubField<Type1>& f1, \
147  const Field<Type2>& f2 \
148 ) \
149 { \
150  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
151  Func(tRes.ref(), f1, f2); \
152  return tRes; \
153 } \
154  \
155 TEMPLATE \
156 tmp<Field<ReturnType>> Func \
157 ( \
158  const SubField<Type1>& f1, \
159  const SubField<Type2>& f2 \
160 ) \
161 { \
162  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
163  Func(tRes.ref(), f1, f2); \
164  return tRes; \
165 } \
166  \
167 TEMPLATE \
168 tmp<Field<ReturnType>> Func \
169 ( \
170  const Field<Type1>& f1, \
171  const tmp<Field<Type2>>& tf2 \
172 ) \
173 { \
174  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type2>::New(tf2); \
175  Func(tRes.ref(), f1, tf2()); \
176  tf2.clear(); \
177  return tRes; \
178 } \
179  \
180 TEMPLATE \
181 tmp<Field<ReturnType>> Func \
182 ( \
183  const SubField<Type1>& f1, \
184  const tmp<Field<Type2>>& tf2 \
185 ) \
186 { \
187  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type2>::New(tf2); \
188  Func(tRes.ref(), f1, tf2()); \
189  tf2.clear(); \
190  return tRes; \
191 } \
192  \
193 TEMPLATE \
194 tmp<Field<ReturnType>> Func \
195 ( \
196  const tmp<Field<Type1>>& tf1, \
197  const Field<Type2>& f2 \
198 ) \
199 { \
200  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type1>::New(tf1); \
201  Func(tRes.ref(), tf1(), f2); \
202  tf1.clear(); \
203  return tRes; \
204 } \
205  \
206 TEMPLATE \
207 tmp<Field<ReturnType>> Func \
208 ( \
209  const tmp<Field<Type1>>& tf1, \
210  const SubField<Type2>& f2 \
211 ) \
212 { \
213  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type1>::New(tf1); \
214  Func(tRes.ref(), tf1(), f2); \
215  tf1.clear(); \
216  return tRes; \
217 } \
218  \
219 TEMPLATE \
220 tmp<Field<ReturnType>> Func \
221 ( \
222  const tmp<Field<Type1>>& tf1, \
223  const tmp<Field<Type2>>& tf2 \
224 ) \
225 { \
226  tmp<Field<ReturnType>> tRes = \
227  reuseTmpTmp<ReturnType, Type1, Type1, Type2>::New(tf1, tf2); \
228  Func(tRes.ref(), tf1(), tf2()); \
229  tf1.clear(); \
230  tf2.clear(); \
231  return tRes; \
232 }
233 
234 
235 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
236 
237 #define BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
238  \
239 TEMPLATE \
240 void Func \
241 ( \
242  Field<ReturnType>& res, \
243  const Type1& s1, \
244  const UList<Type2>& f2 \
245 ) \
246 { \
247  TFOR_ALL_F_OP_FUNC_S_F \
248  ( \
249  ReturnType, res, =, ::Foam::Func, Type1, s1, Type2, f2 \
250  ) \
251 } \
252  \
253 TEMPLATE \
254 tmp<Field<ReturnType>> Func \
255 ( \
256  const Type1& s1, \
257  const Field<Type2>& f2 \
258 ) \
259 { \
260  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f2.size())); \
261  Func(tRes.ref(), s1, f2); \
262  return tRes; \
263 } \
264  \
265 TEMPLATE \
266 tmp<Field<ReturnType>> Func \
267 ( \
268  const Type1& s1, \
269  const SubField<Type2>& f2 \
270 ) \
271 { \
272  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f2.size())); \
273  Func(tRes.ref(), s1, f2); \
274  return tRes; \
275 } \
276  \
277 TEMPLATE \
278 tmp<Field<ReturnType>> Func \
279 ( \
280  const Type1& s1, \
281  const tmp<Field<Type2>>& tf2 \
282 ) \
283 { \
284  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type2>::New(tf2); \
285  Func(tRes.ref(), s1, tf2()); \
286  tf2.clear(); \
287  return tRes; \
288 }
289 
290 
291 #define BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func) \
292  \
293 TEMPLATE \
294 void Func \
295 ( \
296  Field<ReturnType>& res, \
297  const UList<Type1>& f1, \
298  const Type2& s2 \
299 ) \
300 { \
301  TFOR_ALL_F_OP_FUNC_F_S \
302  ( \
303  ReturnType, res, =, ::Foam::Func, Type1, f1, Type2, s2 \
304  ) \
305 } \
306  \
307 TEMPLATE \
308 tmp<Field<ReturnType>> Func \
309 ( \
310  const Field<Type1>& f1, \
311  const Type2& s2 \
312 ) \
313 { \
314  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
315  Func(tRes.ref(), f1, s2); \
316  return tRes; \
317 } \
318  \
319 TEMPLATE \
320 tmp<Field<ReturnType>> Func \
321 ( \
322  const SubField<Type1>& f1, \
323  const Type2& s2 \
324 ) \
325 { \
326  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
327  Func(tRes.ref(), f1, s2); \
328  return tRes; \
329 } \
330  \
331 TEMPLATE \
332 tmp<Field<ReturnType>> Func \
333 ( \
334  const tmp<Field<Type1>>& tf1, \
335  const Type2& s2 \
336 ) \
337 { \
338  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type1>::New(tf1); \
339  Func(tRes.ref(), tf1(), s2); \
340  tf1.clear(); \
341  return tRes; \
342 }
343 
344 
345 #define BINARY_TYPE_FUNCTION(ReturnType, Type1, Type2, Func) \
346  BINARY_TYPE_FUNCTION_SF(ReturnType, Type1, Type2, Func) \
347  BINARY_TYPE_FUNCTION_FS(ReturnType, Type1, Type2, Func)
348 
349 
350 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
351 
352 #define BINARY_OPERATOR(ReturnType, Type1, Type2, Op, OpFunc) \
353  \
354 TEMPLATE \
355 void OpFunc \
356 ( \
357  Field<ReturnType>& res, \
358  const UList<Type1>& f1, \
359  const UList<Type2>& f2 \
360 ) \
361 { \
362  TFOR_ALL_F_OP_F_OP_F(ReturnType, res, =, Type1, f1, Op, Type2, f2) \
363 } \
364  \
365 TEMPLATE \
366 tmp<Field<ReturnType>> operator Op \
367 ( \
368  const Field<Type1>& f1, \
369  const Field<Type2>& f2 \
370 ) \
371 { \
372  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
373  OpFunc(tRes.ref(), f1, f2); \
374  return tRes; \
375 } \
376  \
377 TEMPLATE \
378 tmp<Field<ReturnType>> operator Op \
379 ( \
380  const Field<Type1>& f1, \
381  const SubField<Type2>& f2 \
382 ) \
383 { \
384  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
385  OpFunc(tRes.ref(), f1, f2); \
386  return tRes; \
387 } \
388  \
389 TEMPLATE \
390 tmp<Field<ReturnType>> operator Op \
391 ( \
392  const SubField<Type1>& f1, \
393  const Field<Type2>& f2 \
394 ) \
395 { \
396  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
397  OpFunc(tRes.ref(), f1, f2); \
398  return tRes; \
399 } \
400  \
401 TEMPLATE \
402 tmp<Field<ReturnType>> operator Op \
403 ( \
404  const SubField<Type1>& f1, \
405  const SubField<Type2>& f2 \
406 ) \
407 { \
408  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
409  OpFunc(tRes.ref(), f1, f2); \
410  return tRes; \
411 } \
412  \
413 TEMPLATE \
414 tmp<Field<ReturnType>> operator Op \
415 ( \
416  const Field<Type1>& f1, \
417  const tmp<Field<Type2>>& tf2 \
418 ) \
419 { \
420  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type2>::New(tf2); \
421  OpFunc(tRes.ref(), f1, tf2()); \
422  tf2.clear(); \
423  return tRes; \
424 } \
425  \
426 TEMPLATE \
427 tmp<Field<ReturnType>> operator Op \
428 ( \
429  const SubField<Type1>& f1, \
430  const tmp<Field<Type2>>& tf2 \
431 ) \
432 { \
433  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type2>::New(tf2); \
434  OpFunc(tRes.ref(), f1, tf2()); \
435  tf2.clear(); \
436  return tRes; \
437 } \
438  \
439 TEMPLATE \
440 tmp<Field<ReturnType>> operator Op \
441 ( \
442  const tmp<Field<Type1>>& tf1, \
443  const Field<Type2>& f2 \
444 ) \
445 { \
446  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type1>::New(tf1); \
447  OpFunc(tRes.ref(), tf1(), f2); \
448  tf1.clear(); \
449  return tRes; \
450 } \
451  \
452 TEMPLATE \
453 tmp<Field<ReturnType>> operator Op \
454 ( \
455  const tmp<Field<Type1>>& tf1, \
456  const SubField<Type2>& f2 \
457 ) \
458 { \
459  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type1>::New(tf1); \
460  OpFunc(tRes.ref(), tf1(), f2); \
461  tf1.clear(); \
462  return tRes; \
463 } \
464  \
465 TEMPLATE \
466 tmp<Field<ReturnType>> operator Op \
467 ( \
468  const tmp<Field<Type1>>& tf1, \
469  const tmp<Field<Type2>>& tf2 \
470 ) \
471 { \
472  tmp<Field<ReturnType>> tRes = \
473  reuseTmpTmp<ReturnType, Type1, Type1, Type2>::New(tf1, tf2); \
474  OpFunc(tRes.ref(), tf1(), tf2()); \
475  tf1.clear(); \
476  tf2.clear(); \
477  return tRes; \
478 }
479 
480 
481 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
482 
483 #define BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpFunc) \
484  \
485 TEMPLATE \
486 void OpFunc \
487 ( \
488  Field<ReturnType>& res, \
489  const Type1& s1, \
490  const UList<Type2>& f2 \
491 ) \
492 { \
493  TFOR_ALL_F_OP_S_OP_F(ReturnType, res, =, Type1, s1, Op, Type2, f2) \
494 } \
495  \
496 TEMPLATE \
497 tmp<Field<ReturnType>> operator Op \
498 ( \
499  const Type1& s1, \
500  const Field<Type2>& f2 \
501 ) \
502 { \
503  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f2.size())); \
504  OpFunc(tRes.ref(), s1, f2); \
505  return tRes; \
506 } \
507  \
508 TEMPLATE \
509 tmp<Field<ReturnType>> operator Op \
510 ( \
511  const Type1& s1, \
512  const SubField<Type2>& f2 \
513 ) \
514 { \
515  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f2.size())); \
516  OpFunc(tRes.ref(), s1, f2); \
517  return tRes; \
518 } \
519  \
520 TEMPLATE \
521 tmp<Field<ReturnType>> operator Op \
522 ( \
523  const Type1& s1, \
524  const tmp<Field<Type2>>& tf2 \
525 ) \
526 { \
527  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type2>::New(tf2); \
528  OpFunc(tRes.ref(), s1, tf2()); \
529  tf2.clear(); \
530  return tRes; \
531 }
532 
533 
534 #define BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc) \
535  \
536 TEMPLATE \
537 void OpFunc \
538 ( \
539  Field<ReturnType>& res, \
540  const UList<Type1>& f1, \
541  const Type2& s2 \
542 ) \
543 { \
544  TFOR_ALL_F_OP_F_OP_S(ReturnType, res, =, Type1, f1, Op, Type2, s2) \
545 } \
546  \
547 TEMPLATE \
548 tmp<Field<ReturnType>> operator Op \
549 ( \
550  const Field<Type1>& f1, \
551  const Type2& s2 \
552 ) \
553 { \
554  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
555  OpFunc(tRes.ref(), f1, s2); \
556  return tRes; \
557 } \
558  \
559 TEMPLATE \
560 tmp<Field<ReturnType>> operator Op \
561 ( \
562  const SubField<Type1>& f1, \
563  const Type2& s2 \
564 ) \
565 { \
566  tmp<Field<ReturnType>> tRes(new Field<ReturnType>(f1.size())); \
567  OpFunc(tRes.ref(), f1, s2); \
568  return tRes; \
569 } \
570  \
571 TEMPLATE \
572 tmp<Field<ReturnType>> operator Op \
573 ( \
574  const tmp<Field<Type1>>& tf1, \
575  const Type2& s2 \
576 ) \
577 { \
578  tmp<Field<ReturnType>> tRes = reuseTmp<ReturnType, Type1>::New(tf1); \
579  OpFunc(tRes.ref(), tf1(), s2); \
580  tf1.clear(); \
581  return tRes; \
582 }
583 
584 
585 #define BINARY_TYPE_OPERATOR(ReturnType, Type1, Type2, Op, OpFunc) \
586  BINARY_TYPE_OPERATOR_SF(ReturnType, Type1, Type2, Op, OpFunc) \
587  BINARY_TYPE_OPERATOR_FS(ReturnType, Type1, Type2, Op, OpFunc)
588 
589 
590 // ************************************************************************* //
High performance macro functions for Field<Type> algebra. These expand using either array element acc...