Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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
33namespace Foam
34{
35
36// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37
38#define UNARY_FUNCTION(ReturnType, Type1, Func, Dfunc) \
39 \
40TEMPLATE \
41void 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 \
58TEMPLATE \
59tmp<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 \
77TEMPLATE \
78tmp<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 \
103TEMPLATE \
104void 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 \
121TEMPLATE \
122tmp<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 \
140TEMPLATE \
141tmp<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 \
166TEMPLATE \
167void 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 \
195TEMPLATE \
196tmp<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 \
215TEMPLATE \
216tmp<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 \
238TEMPLATE \
239tmp<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 \
261TEMPLATE \
262tmp<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 \
293TEMPLATE \
294void 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 \
312TEMPLATE \
313tmp<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 \
332TEMPLATE \
333tmp<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 \
343TEMPLATE \
344tmp<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 \
366TEMPLATE \
367tmp<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 \
379TEMPLATE \
380void 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 \
398TEMPLATE \
399tmp<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 \
418TEMPLATE \
419tmp<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 \
429TEMPLATE \
430tmp<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 \
452TEMPLATE \
453tmp<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 \
472TEMPLATE \
473void 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 \
501TEMPLATE \
502tmp<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 \
521TEMPLATE \
522tmp<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 \
544TEMPLATE \
545tmp<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 \
567TEMPLATE \
568tmp<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 \
598TEMPLATE \
599void 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 \
616TEMPLATE \
617tmp<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 \
636TEMPLATE \
637tmp<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 \
647TEMPLATE \
648tmp<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 \
670TEMPLATE \
671tmp<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 \
683TEMPLATE \
684void 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 \
702TEMPLATE \
703tmp<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 \
722TEMPLATE \
723tmp<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 \
733TEMPLATE \
734tmp<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 \
756TEMPLATE \
757tmp<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 \
776TEMPLATE \
777void 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 \
807TEMPLATE \
808tmp<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 \
827TEMPLATE \
828tmp<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 \
850TEMPLATE \
851tmp<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 \
873TEMPLATE \
874tmp<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 \
896TEMPLATE \
897tmp<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 \
924TEMPLATE \
925tmp<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 \
952TEMPLATE \
953tmp<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 \
980TEMPLATE \
981tmp<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 \
1013TEMPLATE \
1014void 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 \
1044TEMPLATE \
1045tmp<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 \
1064TEMPLATE \
1065tmp<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 \
1075TEMPLATE \
1076tmp<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 \
1098TEMPLATE \
1099tmp<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 \
1109TEMPLATE \
1110tmp<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 \
1132TEMPLATE \
1133tmp<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 \
1143TEMPLATE \
1144tmp<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 \
1171TEMPLATE \
1172tmp<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.