Loading...
Searching...
No Matches
GeometricFieldExpression.H
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) 2024,2025 M. Janssens
9 Copyright (C) 2025 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
27InNamespace
28 Foam::Expression
29
30Description
31 Expression templates for GeometricFields
32
33SourceFiles
34 GeometricFieldExpression.H
35
36\*---------------------------------------------------------------------------*/
37
38#ifndef Foam_GeometricFieldExpression_H
39#define Foam_GeometricFieldExpression_H
40
41#include "ListExpression.H"
42#include "orientedType.H"
43#include "pointMesh.H"
44//#include "fixedValuePointPatchField.H" // no assignable yet. tbd.
45//#include <boost/core/demangle.hpp>
46//#include <typeinfo>
47//#include <iostream>
48
49// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50
51namespace Foam
52{
53namespace Expression
54{
55
56// Forward Declarations
57template<class GeoField> class UniformGeometricFieldWrap2;
58
59/*---------------------------------------------------------------------------*\
60 Class GeometricFieldExpression Declaration
61\*---------------------------------------------------------------------------*/
62
63//- Expression of GeometricField
64template
65<
66 typename E,
67 typename IntExpr,
68 typename UncoupledPatchExpr,
69 typename CoupledPatchExpr,
70 typename Type
71>
73{
74protected:
79public:
80 static constexpr bool is_leaf = false;
81
83 (
86 )
87 :
90 {
91 //Pout<< "GeometricFieldExpression :" << nl
92 // << " E : "
93 // << boost::core::demangle(typeid(E).name())
94 // << nl
95 // << " IntExpr : "
96 // << boost::core::demangle(typeid(IntExpr).name()) << nl
97 // << " dimensions : " << dimensions_ << nl
98 // << " oriented : " << oriented_ << nl
99 // << endl;
100 }
101
102 // TBD. Do we still need this? Is faster than always going through
103 // internalField() though.
104 Type operator[](const label i) const
105 {
106 // Delegation to the actual expression type. This avoids dynamic
107 // polymorphism (a.k.a. virtual functions in C++)
108 return static_cast<E const&>(*this)[i];
109 }
110 auto size() const noexcept { return static_cast<const E&>(*this).size(); }
111
112 const dimensionSet& dimensions() const noexcept
113 {
114 return dimensions_;
116
117 const orientedType& oriented() const noexcept
118 {
119 return oriented_;
121
122 IntExpr internalField() const
123 {
124 return static_cast<const E&>(*this).internalField();
126
127 IntExpr internalField()
128 {
129 return static_cast<E&>(*this).internalField();
131
132 UncoupledPatchExpr patchField(const label i)
133 {
134 return static_cast<E&>(*this).patchField(i);
136
137 UncoupledPatchExpr patchField(const label i) const
138 {
139 return static_cast<const E&>(*this).patchField(i);
141
142 CoupledPatchExpr coupledPatchField(const label i)
143 {
144 return static_cast<E&>(*this).coupledPatchField(i);
146
147 CoupledPatchExpr coupledPatchField(const label i) const
148 {
149 return static_cast<const E&>(*this).coupledPatchField(i);
150 }
152 template<class Op>
153 auto access(const Op& cop, const label i) const
154 {
155 return static_cast<const E&>(*this).access(cop, i);
156 }
157
158 //- Helper to evaluate a GeometricField
159 template<class GeoField>
160 GeoField& evaluate(GeoField& fld, const bool force = false) const
161 {
162 fld.dimensions() = this->dimensions();
163 fld.oriented() = this->oriented();
164
165 assert(fld.size() == this->size());
166 using ActualType = typename IntExpr::value_type;
167 ListRefWrap<ActualType> wfld(fld.internalFieldRef(), internalField());
168
169 // Do boundary field
170 typedef Field<ActualType> FieldType;
171 auto& bfld = fld.boundaryFieldRef();
172 const label n = bfld.size();
173#ifdef FOAM_OFFLOAD
174 constexpr bool foam_offload = true;
175#else
176 constexpr bool foam_offload = false;
177#endif
178 if constexpr (foam_offload)
179 {
180 // Wrap multiple containers into single container so there is only
181 // a single kernel. Looking up individual container is fast enough.
182
183 constexpr bool is_pointField =
184 std::is_same_v<pointMesh, typename GeoField::Mesh>;
185
186 auto do_something = [](auto& data, label& i, auto& pfld)
187 {
188 if constexpr (is_pointField)
189 {
190 if (auto* vp = isA<FieldType>(pfld))
191 {
192 data[i++] = const_cast<FieldType*>(vp);
193 }
194 }
195 else
196 {
197 data[i++] = &static_cast<FieldType&>(pfld);
198 }
199 };
200
201 // Note: avoid calling isA for pointFields
203 (
204 fld.boundaryFieldRef(),
205 do_something
206 );
207
208 std::vector<UncoupledPatchExpr> unc_patchExpr;
209 std::vector<CoupledPatchExpr> cou_patchExpr;
210 std::vector<int> coupledID;
211 std::vector<int> uncoupledID;
212
213 // Assume most patches are uncoupled
214 unc_patchExpr.reserve(n);
215 uncoupledID.reserve(n);
216
217 for (label i = 0; i < n; ++i)
218 {
219 auto& pfld = bfld[i];
220 if (force || pfld.assignable())
221 {
222 if (pfld.coupled())
223 {
224 // Get patch expression
225 const auto patchExpr = this->coupledPatchField(i);
226 cou_patchExpr.emplace_back(patchExpr);
227 coupledID.emplace_back(i);
228 }
229 else
230 {
231 const auto patchExpr = this->patchField(i);
232 unc_patchExpr.emplace_back(patchExpr);
233 uncoupledID.emplace_back(i);
234 }
235 }
236 }
237
238 ListsRefWrap<UncoupledPatchExpr> uncpatchExprExpression
239 (
240 unc_patchExpr
241 );
242 ListsRefWrap<CoupledPatchExpr> coupatchExprExpression
243 (
244 cou_patchExpr
245 );
246
247 // Evaluate
248
249 coupatchExprExpression.evaluate(expr, coupledID);
250 uncpatchExprExpression.evaluate(expr, uncoupledID);
251 }
252 else
253 {
254 // Patch by patch evaluation
255 for (label i = 0; i < n; ++i)
256 {
257 auto& pfld = bfld[i];
258 if (force || pfld.assignable())
259 {
260 if (pfld.coupled())
261 {
262 // Get patch expression
263 const auto patchExpr = this->coupledPatchField(i);
264
265 if constexpr
266 (
267 std::is_same_v<pointMesh, typename GeoField::Mesh>
268 )
269 {
270 const auto* vp = isA<FieldType>(pfld);
271 if (vp)
272 {
273 patchExpr.evaluate(const_cast<FieldType&>(*vp));
274 }
275 }
276 else
277 {
278 patchExpr.evaluate(pfld);
279 }
280 }
281 else
282 {
283 // Get patch expression
284 const auto patchExpr = this->patchField(i);
285 if constexpr
286 (
287 std::is_same_v<pointMesh, typename GeoField::Mesh>
288 )
289 {
290 const auto* vp = isA<FieldType>(pfld);
291 if (vp)
292 {
293 patchExpr.evaluate(const_cast<FieldType&>(*vp));
294 }
295 }
296 else
297 {
298 patchExpr.evaluate(pfld);
299 }
300 }
301 }
302 }
303 }
304 fld.correctLocalBoundaryConditions();
305 return fld;
306 }
307};
308
309
310/*---------------------------------------------------------------------------*\
311 Class GeometricFieldRefWrap Declaration
312\*---------------------------------------------------------------------------*/
313
314//- Expression wrap of non-const reference to GeometricField
315template<class GeoField>
316class GeometricFieldRefWrap
317:
319 <
320 GeometricFieldRefWrap<GeoField>,
321 ListRefWrap<typename GeoField::value_type>,
322 ListRefWrap<typename GeoField::value_type>,
323 ListTmpWrap<Field<typename GeoField::value_type>>,
324 typename GeoField::value_type
325 >
326{
327public:
328
329 static constexpr bool is_leaf = false; //true;
330
331 //- The GeometricField type
332 typedef GeoField this_type;
333
334 //- Type to return for internal field
335 typedef typename GeoField::value_type value_type;
337 //- Type to return for patchField
342
343private:
344
345 this_type& elems_;
348public:
349
350 //- Copy construct
352 :
354 <
355 GeometricFieldRefWrap<GeoField>,
356 IntExpr,
360 >
362 elems.dimensions(),
363 elems.oriented()
364 ),
365 elems_(elems)
366 {}
367
368 //- Move construct
370 :
372 <
373 GeometricFieldRefWrap<GeoField>,
374 IntExpr,
378 >
379 (
380 elems.dimensions(),
381 elems.oriented()
382 ),
383 elems_(elems)
384 {}
385
386 // Construct from ListExpression, forcing its evaluation.
387 template<typename E>
389 (
390 this_type& elems,
392 <
393 E,
394 typename E::IntExpr,
395 typename E::UncoupledPatchExpr,
396 typename E::CoupledPatchExpr,
397 typename E::value_type
398 >& expr
399 )
402 <
403 GeometricFieldRefWrap<GeoField>,
404 IntExpr,
408 >
409 (
410 elems.dimensions(),
411 elems.oriented()
412 ),
413 elems_(elems)
414 {
415 expr.evaluate(elems_);
416 }
417
418 //- Assignment
419 template<typename E>
420 void operator=
421 (
423 <
424 E,
425 typename E::IntExpr,
426 typename E::UncoupledPatchExpr,
427 typename E::CoupledPatchExpr,
428 typename E::value_type
429 >& expr
430 )
431 {
432 expr.evaluate(elems_);
433 }
435 //- Evaluate and return as GeoField. Rename to evaluate to make it clear
436 //- it takes time? Or leave as indexing for convenience?
437 template<typename E>
439 (
441 <
442 E,
443 typename E::IntExpr,
444 typename E::UncoupledPatchExpr,
445 typename E::CoupledPatchExpr,
446 typename E::value_type
447 >& expr
448 )
449 {
450 return expr.evaluate(elems_);
451 }
452
453 value_type operator[](const label i) const
455 return elems_[i];
456 }
457
458 value_type& operator[](const label i)
459 {
460 return elems_[i];
461 }
462
463 auto size() const noexcept
464 {
465 return elems_.size();
466 }
467
470 auto& fld = elems_.internalFieldRef();
471 return IntExpr(fld.size(), fld);
472 }
473
475 {
476 auto& fld = elems_.internalField();
477 return IntExpr(fld.size(), fld);
478 }
480 UncoupledPatchExpr patchField(const label i)
481 {
482 auto& fld = elems_.boundaryFieldRef()[i];
483 if constexpr
485 std::is_same_v<pointMesh, typename GeoField::Mesh>
486 )
487 {
488 const auto* vp = isA<Field<value_type>>(fld);
489 if (vp)
491 auto& v = *vp;
492 return UncoupledPatchExpr
493 (
494 v.size(),
495 const_cast<Field<value_type>&>(v)
496 );
497 }
498 else
499 {
501 }
502 }
503 else
504 {
505 return UncoupledPatchExpr(fld.size(), fld);
506 }
507 }
508
509 UncoupledPatchExpr patchField(const label i) const
510 {
511 const auto& fld = elems_.boundaryField()[i];
512 if constexpr
513 (
514 std::is_same_v<pointMesh, typename GeoField::Mesh>
515 )
516 {
517 const auto* vp = isA<Field<value_type>>(fld);
518 if (vp)
519 {
520 return UncoupledPatchExpr(vp->size(), *vp);
521 }
522 else
523 {
526 }
527 else
528 {
529 return UncoupledPatchExpr(fld.size(), fld);
530 }
531 }
532
534 {
535 auto& fld = elems_.boundaryFieldRef()[i];
536 if constexpr
537 (
538 std::is_same_v<pointMesh, typename GeoField::Mesh>
539 )
540 {
541 const auto* vp = isA<Field<value_type>>(fld);
542 if (vp)
543 {
544 auto& v = *vp;
545 return CoupledPatchExpr
546 (
547 //v.size(),
548 const_cast<Field<value_type>&>(v)
549 );
550 }
551 else
552 {
554 }
555 }
556 else
557 {
558 return CoupledPatchExpr(fld);
559 }
560 }
561
562 CoupledPatchExpr coupledPatchField(const label i) const
563 {
564 const auto& fld = elems_.boundaryField()[i];
565 if constexpr
566 (
567 std::is_same_v<pointMesh, typename GeoField::Mesh>
568 )
569 {
570 const auto* vp = isA<Field<value_type>>(fld);
571 if (vp)
572 {
573 //return CoupledPatchExpr(vp->size(), *vp);
574 return CoupledPatchExpr(*vp);
575 }
576 else
577 {
578 //return CoupledPatchExpr(0, List<value_type>::null());
580 }
581 }
582 else
583 {
584 //return UncoupledPatchExpr(fld.size(), fld);
585 return CoupledPatchExpr(fld);
586 }
587 }
588
589 template<class AccessOp>
590 auto access(const AccessOp& cop, const label i) const
591 {
592 return cop(elems_, i);
593 }
594};
595
596
597/*---------------------------------------------------------------------------*\
598 Class GeometricFieldConstRefWrap Declaration
599\*---------------------------------------------------------------------------*/
600
601//- Expression wrap of const reference to GeometricField
602template<class GeoField>
604:
607 GeometricFieldConstRefWrap<GeoField>,
608 ListConstRefWrap<typename GeoField::value_type>,
609 ListConstRefWrap<typename GeoField::value_type>,
610 ListConstTmpWrap<Field<typename GeoField::value_type>>,
611 typename GeoField::value_type
612 >
613{
614public:
615
616 static constexpr bool is_leaf = false; //true;
617
618 //- The GeometricField type
619 typedef GeoField this_type;
620
621 //- Type to return for internal field
622 typedef typename GeoField::value_type value_type;
623
624 //- Type to return for patchField
628
629
630private:
631
632 const this_type& elems_;
633
635public:
636
637 // Construct from components
641 <
643 IntExpr,
647 >
648 (
649 elems.dimensions(),
650 elems.oriented()
651 ),
652 elems_(elems)
653 {}
654
655 // return the underlying data
656 const auto& data() const
657 {
658 return elems_;
659 }
660
661 value_type operator[](const label i) const
663 return elems_[i];
664 }
665
666 auto size() const noexcept
667 {
668 return elems_.size();
669 }
670
671 IntExpr internalField() const
672 {
673 return elems_.internalField();
674 }
675
676 UncoupledPatchExpr patchField(const label i) const
677 {
678 //return elems_.boundaryField()[i];
679 const auto& fld = elems_.boundaryField()[i];
680 if constexpr
681 (
682 std::is_same_v<pointMesh, typename GeoField::Mesh>
683 )
684 {
685 const auto* vp = isA<Field<value_type>>(fld);
686 if (vp)
687 {
688 return UncoupledPatchExpr(*vp);
689 }
690 else
691 {
693 }
694 }
695 else
696 {
697 return UncoupledPatchExpr(fld);
698 }
699 }
701 CoupledPatchExpr coupledPatchField(const label i) const
702 {
703 const auto& fld = elems_.boundaryField()[i];
704 if constexpr
705 (
706 std::is_same_v<pointMesh, typename GeoField::Mesh>
707 )
708 {
709 const auto* vp = isA<Field<value_type>>(fld);
710 if (vp)
711 {
712 return CoupledPatchExpr(*vp);
713 }
714 else
715 {
716 return CoupledPatchExpr(tmp<Field<value_type>>(nullptr));
717 }
718 }
719 else
720 {
721 return CoupledPatchExpr(fld);
722 }
723 }
724
725 template<class AccessOp>
726 auto access(const AccessOp& cop, const label i) const
727 {
728 return cop(elems_, i);
729 }
730};
731
732
733/*---------------------------------------------------------------------------*\
734 Class GeometricFieldConstTmpWrap Declaration
735\*---------------------------------------------------------------------------*/
736
737//- Expression wrap of const tmp to GeometricField
738template<class GeoField>
739class GeometricFieldConstTmpWrap
740:
741 public GeometricFieldExpression
742 <
743 GeometricFieldConstTmpWrap<GeoField>,
744 ListConstRefWrap<typename GeoField::value_type>,
745 ListConstRefWrap<typename GeoField::value_type>,
746 ListConstTmpWrap<Field<typename GeoField::value_type>>,
747 typename GeoField::value_type
748 >
749{
750public:
751
752 //- Have expressions use copy to maintain tmp refCount
753 static constexpr bool is_leaf = false;
754
755 //- The GeometricField type
756 typedef GeoField this_type;
757
758 //- Type to return for internal field
759 typedef typename GeoField::value_type value_type;
760
761 //- Type to return for patchField
766
767private:
768
769 const tmp<this_type> elems_;
770
771
772public:
773
774 // Construct from components
776 :
778 <
780 IntExpr,
784 >
785 (
786 elems().dimensions(),
787 elems().oriented()
788 ),
789 elems_(elems, true)
790 {
791 //Pout<< "GeometricFieldConstTmpWrap :" << nl
792 // << " this_type : "
793 // << boost::core::demangle(typeid(this_type).name())
794 // << nl
795 // << " PatchExpr : "
796 // << boost::core::demangle(typeid(IntExpr).name()) << nl
797 // << endl;
799
801 (
803 )
804 :
806 <
808 IntExpr,
812 >
813 (
814 w.dimensions(),
815 w.oriented()
816 ),
817 elems_(w.elems_)
818 {
819 //Pout<< "GeometricFieldConstTmpWrap copy :" << nl
820 // << " this_type : "
821 // << boost::core::demangle(typeid(this_type).name())
822 // << nl
823 // << " PatchExpr : "
824 // << boost::core::demangle(typeid(IntExpr).name()) << nl
825 // << endl;
826 }
827
829 {
830 //Pout<< "~GeometricFieldConstTmpWrap destructor :" << nl
831 // << " this_type : "
832 // << boost::core::demangle(typeid(this_type).name())
833 // << nl
834 // << endl;
835 }
836
837 // return the underlying data
838 const auto& data() const
839 {
840 return elems_();
841 }
842
843 value_type operator[](const label i) const
844 {
845 // Redirection for every access. Slow?
846 return elems_()[i];
847 }
848
849 auto size() const noexcept
850 {
851 return elems_().size();
852 }
853
854 IntExpr internalField() const
855 {
856 return elems_().internalField();
857 }
858
859 UncoupledPatchExpr patchField(const label i) const
860 {
861 const auto& fld = elems_().boundaryField()[i];
862 if constexpr
863 (
864 std::is_same_v<pointMesh, typename GeoField::Mesh>
865 )
866 {
867 const auto* vp = isA<Field<value_type>>(fld);
868 if (vp)
869 {
870 return UncoupledPatchExpr(*vp);
871 }
872 else
873 {
875 }
876 }
877 else
878 {
879 return UncoupledPatchExpr(fld);
880 }
881
882 }
884 CoupledPatchExpr coupledPatchField(const label i) const
885 {
886 const auto& fld = elems_().boundaryField()[i];
887 if constexpr
889 std::is_same_v<pointMesh, typename GeoField::Mesh>
890 )
891 {
892 const auto* vp = isA<Field<value_type>>(fld);
893 if (vp)
894 {
895 return CoupledPatchExpr(*vp);
896 }
897 else
898 {
900 }
901 }
902 else
903 {
904 return CoupledPatchExpr(fld);
905 }
906 }
907
908 template<class AccessOp>
909 auto access(const AccessOp& cop, const label i) const
910 {
911 return cop(elems_(), i);
912 }
913};
914
915
916// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
917
918// Expressions on GeometricFields
919// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
920
921// Do '+' ourselves - just to show. Others done with macros below.
922template<typename E1, typename E2>
923class GF_add
924:
926 <
927 GF_add<E1, E2>,
928 List_add
929 <
930 typename E1::IntExpr,
931 typename E2::IntExpr
932 >,
933 List_add
934 <
935 typename E1::UncoupledPatchExpr,
936 typename E2::UncoupledPatchExpr
937 >,
938 List_add
939 <
940 typename E1::CoupledPatchExpr,
941 typename E2::CoupledPatchExpr
942 >,
943 typename E1::value_type
944 >
945{
946 // cref if leaf, copy otherwise
947 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
948 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_;
949
950public:
951 static constexpr bool is_leaf = false;
952
953 //- Type to return for internal field
954 typedef typename E1::value_type value_type;
955
956 //- Type to return for patchField
957 typedef List_add
958 <
959 typename E1::IntExpr,
960 typename E2::IntExpr
961 > IntExpr;
962 typedef List_add
963 <
964 typename E1::UncoupledPatchExpr,
965 typename E2::UncoupledPatchExpr
967 typedef List_add
968 <
969 typename E1::CoupledPatchExpr,
970 typename E2::CoupledPatchExpr
972
973 GF_add(const E1& u, const E2& v)
974 :
976 <
977 GF_add<E1, E2>,
978 IntExpr,
982 >
983 (
984 u.dimensions() + v.dimensions(),
985 u.oriented() // + v.oriented()
986 ),
987 u_(u),
988 v_(v)
989 {
990 assert(u.size() == -1 || v.size() == -1 || u.size() == v.size());
991 static_assert
992 (
993 std::is_same_v
994 <
995 typename E1::value_type,
996 typename E2::value_type
997 > == true
998 );
1000 auto operator[](const label i) const
1001 {
1002 return u_[i] + v_[i];
1003 }
1004 auto size() const noexcept { return Foam::max(u_.size(), v_.size()); }
1005
1006 IntExpr internalField() const
1007 {
1008 return IntExpr(u_.internalField(), v_.internalField());
1010
1011 UncoupledPatchExpr patchField(const label i) const
1012 {
1013 return UncoupledPatchExpr(u_.patchField(i), v_.patchField(i));
1014 }
1015
1016 CoupledPatchExpr coupledPatchField(const label i) const
1017 {
1018 return CoupledPatchExpr
1019 (
1020 u_.coupledPatchField(i),
1021 v_.coupledPatchField(i)
1022 );
1023 }
1024
1025 template<class AccessOp>
1026 auto access(const AccessOp& cop, const label i) const
1027 {
1028 return UncoupledPatchExpr(u_.access(cop, i), v_.access(cop, i));
1029 }
1030};
1031template<typename E1, typename E2>
1032auto operator+
1033(
1035 <
1036 E1,
1037 typename E1::IntExpr,
1038 typename E1::UncoupledPatchExpr,
1039 typename E1::CoupledPatchExpr,
1040 typename E1::value_type
1041 > const& u,
1043 <
1044 E2,
1045 typename E2::IntExpr,
1046 typename E2::UncoupledPatchExpr,
1047 typename E2::CoupledPatchExpr,
1048 typename E2::value_type
1049 > const& v
1050)
1051{
1052 return GF_add<E1, E2>
1053 (
1054 static_cast<const E1&>(u),
1055 static_cast<const E2&>(v)
1056 );
1057}
1058template<typename E1,class Type,template<class> class PatchField,class GeoMesh>
1059auto operator+
1060(
1062 <
1063 E1,
1064 typename E1::IntExpr,
1065 typename E1::UncoupledPatchExpr,
1066 typename E1::CoupledPatchExpr,
1067 typename E1::value_type
1068 > const& u,
1071{
1073 <
1075 > E2;
1076
1077 return GF_add(static_cast<const E1&>(u), E2(v));
1078}
1079template<typename E1,class Type,template<class> class PatchField,class GeoMesh>
1080auto operator+
1081(
1083 GeometricFieldExpression
1084 <
1085 E1,
1086 typename E1::IntExpr,
1087 typename E1::UncoupledPatchExpr,
1088 typename E1::CoupledPatchExpr,
1089 typename E1::value_type
1090 > const& v
1091)
1092{
1094 <
1096 > E2;
1097 return GF_add(E2(u), static_cast<const E1&>(v));
1098}
1099template
1100<class Type1, class Type2, template<class> class PatchField, class GeoMesh>
1101auto operator+
1102(
1105)
1106{
1108 <
1110 > E1;
1112 <
1114 > E2;
1115 return GF_add(E1(u), E2(v));
1116}
1117template<class Type, template<class> class PatchField, class GeoMesh>
1118auto operator+
1119(
1121 const dimensioned<Type>& v
1122)
1123{
1124 typedef typename Foam::GeometricField<Type, PatchField, GeoMesh> GeoField;
1127 return GF_add(E1(u), E2(u, v));
1128}
1129template<class Type, template<class> class PatchField, class GeoMesh>
1130auto operator+
1131(
1132 const dimensioned<Type>& u,
1134)
1135{
1136 typedef typename Foam::GeometricField<Type, PatchField, GeoMesh> GeoField;
1139 return GF_add(E2(v, u), E1(v));
1140}
1141
1142
1143#undef EXPRESSION_GF_FUNCTION1_DIMLESS
1144#define EXPRESSION_GF_FUNCTION1_DIMLESS(Func, BaseFunc, WrapType, OpFunc) \
1145template<typename E1> \
1146class OpFunc \
1147: \
1148 public GeometricFieldExpression \
1149 < \
1150 OpFunc<E1>, \
1151 WrapType<typename E1::IntExpr>, \
1152 WrapType<typename E1::UncoupledPatchExpr>, \
1153 WrapType<typename E1::CoupledPatchExpr>, \
1154 typename E1::value_type \
1155 > \
1157 /* cref if leaf, copy otherwise */ \
1158 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
1159 \
1160public: \
1161 static constexpr bool is_leaf = false; \
1162 \
1163 /* Type to return for internal field */ \
1164 typedef typename E1::value_type value_type; \
1165 \
1166 /* Type to return for patchField */ \
1167 typedef WrapType<typename E1::IntExpr> IntExpr; \
1168 typedef WrapType<typename E1::UncoupledPatchExpr> UncoupledPatchExpr; \
1169 typedef WrapType<typename E1::CoupledPatchExpr> CoupledPatchExpr; \
1170 \
1171 OpFunc(const E1& u) \
1172 : \
1173 GeometricFieldExpression \
1174 < \
1175 OpFunc<E1>, \
1176 IntExpr, \
1177 UncoupledPatchExpr, \
1178 CoupledPatchExpr, \
1179 value_type \
1180 > \
1181 ( \
1182 u.dimensions(), \
1183 u.oriented() \
1184 ), \
1185 u_(u) \
1186 {} \
1187 auto operator[](const label i) const \
1188 { \
1189 return BaseFunc(u_[i]); \
1190 } \
1191 auto size() const noexcept { return u_.size(); } \
1192 \
1193 IntExpr internalField() const \
1194 { \
1195 return IntExpr(u_.internalField()); \
1196 } \
1197 \
1198 UncoupledPatchExpr patchField(const label i) const \
1199 { \
1200 return UncoupledPatchExpr(u_.patchField(i)); \
1201 } \
1202 \
1203 CoupledPatchExpr coupledPatchField(const label i) const \
1204 { \
1205 return CoupledPatchExpr(u_.coupledPatchField(i)); \
1206 } \
1207 \
1208 template<class AccessOpOp> \
1209 auto access(const AccessOpOp& cop, const label i) const \
1210 { \
1211 return UncoupledPatchExpr(u_.access(cop, i)); \
1212 } \
1213}; \
1214template<typename E1> \
1215auto Func \
1216( \
1217 GeometricFieldExpression \
1218 < \
1219 E1, \
1220 typename E1::IntExpr, \
1221 typename E1::UncoupledPatchExpr, \
1222 typename E1::CoupledPatchExpr, \
1223 typename E1::value_type \
1224 > const& u \
1225) \
1226{ \
1227 return OpFunc<E1>(static_cast<const E1&>(u)); \
1228} \
1229template<class Type, template<class> class PatchField, class GeoMesh> \
1230auto Func(GeometricField<Type, PatchField, GeoMesh> const& fld) \
1231{ \
1232 typedef typename Expression::GeometricFieldConstRefWrap \
1233 <GeometricField<Type, PatchField, GeoMesh>> E1; \
1234 return Func(E1(fld)); \
1235}
1236
1237#undef EXPRESSION_GF_FUNCTION1
1238#define EXPRESSION_GF_FUNCTION1(Func, BaseFunc, WrapType, OpFunc) \
1239template<typename E1> \
1240class OpFunc \
1241: \
1242 public GeometricFieldExpression \
1243 < \
1244 OpFunc<E1>, \
1245 WrapType<typename E1::IntExpr>, \
1246 WrapType<typename E1::UncoupledPatchExpr>, \
1247 WrapType<typename E1::CoupledPatchExpr>, \
1248 typename E1::value_type \
1249 > \
1250{ \
1251 /* cref if leaf, copy otherwise */ \
1252 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
1253 \
1254public: \
1255 static constexpr bool is_leaf = false; \
1256 \
1257 /* Type to return for internal field */ \
1258 typedef typename E1::value_type value_type; \
1259 \
1260 /* Type to return for patchField */ \
1261 typedef WrapType<typename E1::IntExpr> IntExpr; \
1262 typedef WrapType<typename E1::UncoupledPatchExpr> UncoupledPatchExpr; \
1263 typedef WrapType<typename E1::CoupledPatchExpr> CoupledPatchExpr; \
1264 \
1265 OpFunc(const E1& u) \
1266 : \
1267 GeometricFieldExpression \
1268 < \
1269 OpFunc<E1>, \
1270 IntExpr, \
1271 UncoupledPatchExpr, \
1272 CoupledPatchExpr, \
1273 value_type \
1274 > \
1275 ( \
1276 BaseFunc(u.dimensions()), \
1277 BaseFunc(u.oriented()) \
1278 ), \
1279 u_(u) \
1280 {} \
1281 auto operator[](const label i) const \
1282 { \
1283 return BaseFunc(u_[i]); \
1284 } \
1285 auto size() const noexcept { return u_.size(); } \
1286 \
1287 IntExpr internalField() const \
1288 { \
1289 return IntExpr(u_.internalField()); \
1290 } \
1291 \
1292 UncoupledPatchExpr patchField(const label i) const \
1293 { \
1294 return UncoupledPatchExpr(u_.patchField(i)); \
1295 } \
1296 \
1297 CoupledPatchExpr coupledPatchField(const label i) const \
1298 { \
1299 return CoupledPatchExpr(u_.coupledPatchField(i)); \
1300 } \
1301 \
1302 template<class AccessOpOp> \
1303 auto access(const AccessOpOp& cop, const label i) const \
1304 { \
1305 return UncoupledPatchExpr(u_.access(cop, i)); \
1306 } \
1307}; \
1308template<typename E1> \
1309auto Func \
1310( \
1311 GeometricFieldExpression \
1312 < \
1313 E1, \
1314 typename E1::IntExpr, \
1315 typename E1::UncoupledPatchExpr, \
1316 typename E1::CoupledPatchExpr, \
1317 typename E1::value_type \
1318 > const& u \
1319) \
1320{ \
1321 return OpFunc<E1>(static_cast<const E1&>(u)); \
1322} \
1323template<class Type, template<class> class PatchField, class GeoMesh> \
1324auto Func(GeometricField<Type, PatchField, GeoMesh> const& fld) \
1325{ \
1326 typedef typename Expression::GeometricFieldConstRefWrap \
1327 <GeometricField<Type, PatchField, GeoMesh>> E1; \
1328 return Func(E1(fld)); \
1329}
1330
1331
1333//template<typename E1>
1334//class GeometricFieldNegate
1335//:
1336// public GeometricFieldExpression
1337// <
1338// GeometricFieldNegate<E1>,
1339// List_negate<typename E1::IntExpr>,
1340// List_negate<typename E1::UncoupledPatchExpr>,
1341// List_negate<typename E1::CoupledPatchExpr>,
1342// typename E1::value_type
1343// >
1344//{
1345// /* cref if leaf, copy otherwise */
1346// typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
1347//
1348//public:
1349// static constexpr bool is_leaf = false;
1350//
1351// /* Type to return for internal field */
1352// typedef typename E1::value_type value_type;
1353//
1354// /* Type to return for patchField */
1355// typedef List_negate<typename E1::IntExpr> IntExpr;
1356// typedef List_negate<typename E1::UncoupledPatchExpr> UncoupledPatchExpr;
1357// typedef List_negate<typename E1::CoupledPatchExpr> CoupledPatchExpr;
1358//
1359// GeometricFieldNegate(const E1& u)
1360// :
1361// GeometricFieldExpression
1362// <
1363// GeometricFieldNegate<E1>,
1364// IntExpr,
1365// UncoupledPatchExpr,
1366// CoupledPatchExpr,
1367// value_type
1368// >
1369// (
1370// -u.dimensions(),
1371// -u.oriented()
1372// ),
1373// u_(u)
1374// {}
1375// auto operator[](const label i) const
1376// {
1377// return -u_[i];
1378// }
1379// label size() const { return u_.size(); }
1380//
1381// IntExpr internalField() const
1382// {
1383// return PatchExpr(u_.internalField());
1384// }
1385//
1386// UncoupledPatchExpr patchField(const label i) const
1387// {
1388// return UncoupledPatchExpr(u_.patchField(i));
1389// }
1390//};
1391//template<typename E1>
1392//GeometricFieldNegate<E1> operator-
1393//(
1394// GeometricFieldExpression
1395// <
1396// E1,
1397// typename E1::IntExpr,
1398// typename E1::UncoupledPatchExpr,
1399// typename E1::CoupledPatchExpr,
1400// typename E1::value_type
1401// > const& u
1402//)
1403//{
1404// return GeometricFieldNegate<E1>(static_cast<const E1&>(u));
1405//}
1406
1407#undef EXPRESSION_GF_OPERATOR
1408#define EXPRESSION_GF_OPERATOR(Op, WrapType, OpFunc) \
1409template<typename E1, typename E2> \
1410class OpFunc \
1411: \
1412 public GeometricFieldExpression \
1413 < \
1414 OpFunc<E1, E2>, \
1415 WrapType \
1416 < \
1417 typename E1::IntExpr, \
1418 typename E2::IntExpr \
1419 >, \
1420 WrapType \
1421 < \
1422 typename E1::UncoupledPatchExpr, \
1423 typename E2::UncoupledPatchExpr \
1424 >, \
1425 WrapType \
1426 < \
1427 typename E1::CoupledPatchExpr, \
1428 typename E2::CoupledPatchExpr \
1429 >, \
1430 typename E1::value_type \
1431 > \
1432{ \
1433 /* cref if leaf, copy otherwise */ \
1434 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
1435 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
1436 \
1437public: \
1438 static constexpr bool is_leaf = false; \
1439 \
1440 /* Type to return for internal field */ \
1441 typedef typename E1::value_type value_type; \
1442 \
1443 /* Type to return for patchField */ \
1444 typedef WrapType \
1445 < \
1446 typename E1::IntExpr, \
1447 typename E2::IntExpr \
1448 > IntExpr; \
1449 typedef WrapType \
1450 < \
1451 typename E1::UncoupledPatchExpr, \
1452 typename E2::UncoupledPatchExpr \
1453 > UncoupledPatchExpr; \
1454 typedef WrapType \
1455 < \
1456 typename E1::CoupledPatchExpr, \
1457 typename E2::CoupledPatchExpr \
1458 > CoupledPatchExpr; \
1459 \
1460 OpFunc(const E1& u, const E2& v) \
1461 : \
1462 GeometricFieldExpression \
1463 < \
1464 OpFunc<E1, E2>, \
1465 IntExpr, \
1466 UncoupledPatchExpr, \
1467 CoupledPatchExpr, \
1468 typename E1::value_type \
1469 > \
1470 ( \
1471 u.dimensions() Op v.dimensions(), \
1472 u.oriented() Op v.oriented() \
1473 ), \
1474 u_(u), \
1475 v_(v) \
1476 { \
1477 /*static_assert \
1478 ( \
1479 std::is_same_v \
1480 < \
1481 typename E1::value_type, \
1482 typename E2::value_type \
1483 > == true \
1484 );*/ \
1485 assert(u.size() == -1 || v.size() == -1 || u.size() == v.size()); \
1486 } \
1487 auto operator[](const label i) const \
1488 { \
1489 return u_[i] Op v_[i]; \
1490 } \
1491 auto size() const noexcept { return Foam::max(u_.size(), v_.size()); } \
1492 \
1493 IntExpr internalField() const \
1494 { \
1495 return IntExpr(u_.internalField(), v_.internalField()); \
1496 } \
1497 \
1498 UncoupledPatchExpr patchField(const label i) const \
1499 { \
1500 return UncoupledPatchExpr(u_.patchField(i), v_.patchField(i)); \
1501 } \
1502 \
1503 CoupledPatchExpr coupledPatchField(const label i) const \
1504 { \
1505 return CoupledPatchExpr \
1506 ( \
1507 u_.coupledPatchField(i), \
1508 v_.coupledPatchField(i) \
1509 ); \
1510 } \
1511 \
1512 template<class AccessOp> \
1513 auto access(const AccessOp& cop, const label i) const \
1514 { \
1515 return UncoupledPatchExpr \
1516 ( \
1517 u_.access(cop, i), \
1518 v_.access(cop, i) \
1519 ); \
1520 } \
1521}; \
1522template<typename E1, typename E2> \
1523auto operator Op \
1524( \
1525 GeometricFieldExpression \
1526 < \
1527 E1, \
1528 typename E1::IntExpr, \
1529 typename E1::UncoupledPatchExpr, \
1530 typename E1::CoupledPatchExpr, \
1531 typename E1::value_type \
1532 > const& u, \
1533 GeometricFieldExpression \
1534 < \
1535 E2, \
1536 typename E2::IntExpr, \
1537 typename E2::UncoupledPatchExpr, \
1538 typename E2::CoupledPatchExpr, \
1539 typename E2::value_type \
1540 > const& v \
1541) \
1542{ \
1543 return OpFunc<E1, E2> \
1544 ( \
1545 static_cast<const E1&>(u), \
1546 static_cast<const E2&>(v) \
1547 ); \
1548} \
1549template \
1550< \
1551 typename E1, \
1552 class Type, template<class> class PatchField, class GeoMesh \
1553> \
1554auto operator Op \
1555( \
1556 GeometricFieldExpression \
1557 < \
1558 E1, \
1559 typename E1::IntExpr, \
1560 typename E1::UncoupledPatchExpr, \
1561 typename E1::CoupledPatchExpr, \
1562 typename E1::value_type \
1563 > const& u, \
1564 GeometricField<Type, PatchField, GeoMesh> const& fld \
1565) \
1566{ \
1567 typedef typename Expression::GeometricFieldConstRefWrap \
1568 <GeometricField<Type, PatchField, GeoMesh>> E2; \
1569 return operator Op(u, E2(fld)); \
1570} \
1571template \
1572< \
1573 class Type, template<class> class PatchField, class GeoMesh, \
1574 typename E1 \
1575> \
1576auto operator Op \
1577( \
1578 GeometricField<Type, PatchField, GeoMesh> const& fld, \
1579 GeometricFieldExpression \
1580 < \
1581 E1, \
1582 typename E1::IntExpr, \
1583 typename E1::UncoupledPatchExpr, \
1584 typename E1::CoupledPatchExpr, \
1585 typename E1::value_type \
1586 > const& u \
1587) \
1588{ \
1589 typedef typename Expression::GeometricFieldConstRefWrap \
1590 <GeometricField<Type, PatchField, GeoMesh>> E2; \
1591 return operator Op(E2(fld), u); \
1592} \
1593template \
1594<class Type1, class Type2, template<class> class PatchField, class GeoMesh> \
1595auto operator Op \
1596( \
1597 GeometricField<Type1, PatchField, GeoMesh> const& u, \
1598 GeometricField<Type2, PatchField, GeoMesh> const& v \
1599) \
1600{ \
1601 typedef typename Expression::GeometricFieldConstRefWrap \
1602 <GeometricField<Type1, PatchField, GeoMesh>> E1; \
1603 typedef typename Expression::GeometricFieldConstRefWrap \
1604 <GeometricField<Type2, PatchField, GeoMesh>> E2; \
1605 return operator Op(E1(u), E2(v)); \
1606} \
1607/* Dimensioned types */ \
1608template<typename E1, class Type> \
1609auto operator Op \
1610( \
1611 GeometricFieldExpression \
1612 < \
1613 E1, \
1614 typename E1::IntExpr, \
1615 typename E1::UncoupledPatchExpr, \
1616 typename E1::CoupledPatchExpr, \
1617 typename E1::value_type \
1618 > const& u, \
1619 dimensioned<Type> const& v \
1620) \
1621{ \
1622 typedef typename Foam::Expression::UniformGeometricFieldWrap2<Type> E2; \
1623 return operator Op(u, E2(v)); \
1624} \
1625template<typename E1, class Type> \
1626auto operator Op \
1627( \
1628 dimensioned<Type> const& u, \
1629 GeometricFieldExpression \
1630 < \
1631 E1, \
1632 typename E1::IntExpr, \
1633 typename E1::UncoupledPatchExpr, \
1634 typename E1::CoupledPatchExpr, \
1635 typename E1::value_type \
1636 > const& v \
1637) \
1638{ \
1639 typedef typename Foam::Expression::UniformGeometricFieldWrap2<Type> E2; \
1640 return operator Op(E2(u), v); \
1641} \
1642/* Primitive types */ \
1643template \
1644< \
1645 class Type1, class Type2, template<class> class PatchField, class GeoMesh, \
1646 class = std::enable_if_t \
1647 < \
1648 (std::is_arithmetic_v<Type2> || Foam::is_vectorspace_v<Type2>) \
1649 > \
1650> \
1651auto operator Op \
1652( \
1653 GeometricField<Type1, PatchField, GeoMesh> const& u, \
1654 Type2 const& v \
1655) \
1656{ \
1657 typedef typename Foam::GeometricField<Type1, PatchField, GeoMesh> GeoField;\
1658 typedef typename Expression::UniformGeometricFieldWrap<GeoField, Type2> E2;\
1659 return operator Op(u, E2(u, v)); \
1660} \
1661template \
1662< \
1663 class Type1, class Type2, template<class> class PatchField, class GeoMesh, \
1664 class = std::enable_if_t \
1665 < \
1666 (std::is_arithmetic_v<Type2> || Foam::is_vectorspace_v<Type2>) \
1667 > \
1668> \
1669auto operator Op \
1670( \
1671 Type2 const& u, \
1672 GeometricField<Type1, PatchField, GeoMesh> const& v \
1673) \
1674{ \
1675 typedef typename Foam::GeometricField<Type1, PatchField, GeoMesh> GeoField;\
1676 typedef typename Expression::UniformGeometricFieldWrap<GeoField, Type2> E2;\
1677 return operator Op(E2(v, u), v); \
1678} \
1679/* GeoFields and Dimensioned types */ \
1680template \
1681< \
1682 class Type1, class Type2, template<class> class PatchField, class GeoMesh \
1683> \
1684auto operator Op \
1685( \
1686 GeometricField<Type1, PatchField, GeoMesh> const& u, \
1687 dimensioned<Type2> const& v \
1688) \
1689{ \
1690 typedef typename Foam::Expression::UniformGeometricFieldWrap \
1691 <GeometricField<Type1, PatchField, GeoMesh>, Type2> E2; \
1692 return operator Op(u, E2(u, v)); \
1693} \
1694template \
1695< \
1696 class Type1, class Type2, template<class> class PatchField, class GeoMesh \
1697> \
1698auto operator Op \
1699( \
1700 dimensioned<Type2> const& u, \
1701 GeometricField<Type1, PatchField, GeoMesh> const& v \
1702) \
1703{ \
1704 typedef typename Foam::Expression::UniformGeometricFieldWrap \
1705 <GeometricField<Type1, PatchField, GeoMesh>, Type2> E2; \
1706 return operator Op(E2(v, u), v); \
1707} \
1708/* Expressions and primitive types */ \
1709template \
1710< \
1711 class E1, class Type2, \
1712 class = std::enable_if_t \
1713 < \
1714 (std::is_arithmetic_v<Type2> || Foam::is_vectorspace_v<Type2>) \
1715 > \
1716> \
1717auto operator Op \
1718( \
1719 GeometricFieldExpression \
1720 < \
1721 E1, \
1722 typename E1::IntExpr, \
1723 typename E1::UncoupledPatchExpr, \
1724 typename E1::CoupledPatchExpr, \
1725 typename E1::value_type \
1726 > const& u, \
1727 Type2 const& v \
1728) \
1729{ \
1730 typedef typename Foam::Expression::UniformGeometricFieldWrap2<Type2> E2; \
1731 return operator Op(u, E2(v)); \
1732} \
1733template \
1734< \
1735 class E1, class Type2, \
1736 class = std::enable_if_t \
1737 < \
1738 (std::is_arithmetic_v<Type2> || Foam::is_vectorspace_v<Type2>) \
1739 > \
1740> \
1741auto operator Op \
1742( \
1743 Type2 const& u, \
1744 GeometricFieldExpression \
1745 < \
1746 E1, \
1747 typename E1::IntExpr, \
1748 typename E1::UncoupledPatchExpr, \
1749 typename E1::CoupledPatchExpr, \
1750 typename E1::value_type \
1751 > const& v \
1752) \
1753{ \
1754 typedef typename Foam::Expression::UniformGeometricFieldWrap2<Type2> E2; \
1755 return operator Op(E2(u), v); \
1756} \
1757
1758
1759#undef EXPRESSION_GF_FUNCTION2
1760#define EXPRESSION_GF_FUNCTION2(Func, BaseFunc, WrapType, OpFunc) \
1761template<typename E1, typename E2> \
1762class OpFunc \
1763: \
1764 public GeometricFieldExpression \
1765 < \
1766 OpFunc<E1, E2>, \
1767 WrapType \
1768 < \
1769 typename E1::IntExpr, \
1770 typename E2::IntExpr \
1771 >, \
1772 WrapType \
1773 < \
1774 typename E1::UncoupledPatchExpr, \
1775 typename E2::UncoupledPatchExpr \
1776 >, \
1777 WrapType \
1778 < \
1779 typename E1::CoupledPatchExpr, \
1780 typename E2::CoupledPatchExpr \
1781 >, \
1782 typename E1::value_type \
1783 > \
1784{ \
1785 /* cref if leaf, copy otherwise */ \
1786 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
1787 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
1788 \
1789public: \
1790 static constexpr bool is_leaf = false; \
1792 /* Type to return for internal field */ \
1793 typedef typename E1::value_type value_type; \
1794 \
1795 /* Type to return for patchField */ \
1796 typedef WrapType \
1797 < \
1798 typename E1::IntExpr, \
1799 typename E2::IntExpr \
1800 > IntExpr; \
1801 typedef WrapType \
1802 < \
1803 typename E1::UncoupledPatchExpr, \
1804 typename E2::UncoupledPatchExpr \
1805 > UncoupledPatchExpr; \
1806 typedef WrapType \
1807 < \
1808 typename E1::CoupledPatchExpr, \
1809 typename E2::CoupledPatchExpr \
1810 > CoupledPatchExpr; \
1811 \
1812 OpFunc(const E1& u, const E2& v) \
1813 : \
1814 GeometricFieldExpression \
1815 < \
1816 OpFunc<E1, E2>, \
1817 IntExpr, \
1818 UncoupledPatchExpr, \
1819 CoupledPatchExpr, \
1820 value_type \
1821 > \
1822 ( \
1823 BaseFunc(u.dimensions(), v.dimensions()), \
1824 BaseFunc(u.oriented(), v.oriented()) \
1825 ), \
1826 u_(u), \
1827 v_(v) \
1828 { \
1829 /*static_assert \
1830 ( \
1831 std::is_same_v \
1832 < \
1833 typename E1::value_type, \
1834 typename E2::value_type \
1835 > == true \
1836 );*/ \
1837 } \
1838 auto operator[](const label i) const \
1839 { \
1840 return BaseFunc(u_[i], v_[i]); \
1841 } \
1842 auto size() const noexcept {return Foam::max(u_.size(), v_.size()); } \
1843 \
1844 IntExpr internalField() const \
1845 { \
1846 return IntExpr(u_.internalField(), v_.internalField()); \
1847 } \
1848 \
1849 UncoupledPatchExpr patchField(const label i) const \
1850 { \
1851 return UncoupledPatchExpr(u_.patchField(i), v_.patchField(i)); \
1852 } \
1853 \
1854 CoupledPatchExpr coupledPatchField(const label i) const \
1855 { \
1856 return CoupledPatchExpr \
1857 ( \
1858 u_.coupledPatchField(i), \
1859 v_.coupledPatchField(i) \
1860 ); \
1861 } \
1862 \
1863 template<class AccessOp> \
1864 auto access(const AccessOp& cop, const label i) const \
1865 { \
1866 return UncoupledPatchExpr \
1867 ( \
1868 u_.access(cop, i), \
1869 v_.access(cop, i) \
1870 ); \
1871 } \
1872}; \
1873template<typename E1, typename E2> \
1874auto Func \
1875( \
1876 GeometricFieldExpression \
1877 < \
1878 E1, \
1879 typename E1::IntExpr, \
1880 typename E1::UncoupledPatchExpr, \
1881 typename E1::CoupledPatchExpr, \
1882 typename E1::value_type \
1883 > const& u, \
1884 GeometricFieldExpression \
1885 < \
1886 E2, \
1887 typename E2::IntExpr, \
1888 typename E2::UncoupledPatchExpr, \
1889 typename E2::CoupledPatchExpr, \
1890 typename E2::value_type \
1891 > const& v \
1892) \
1893{ \
1894 return OpFunc<E1, E2> \
1895 ( \
1896 static_cast<const E1&>(u), \
1897 static_cast<const E2&>(v) \
1898 ); \
1899} \
1900template \
1901< \
1902 typename E1, \
1903 class Type, template<class> class PatchField, class GeoMesh \
1904> \
1905auto Func \
1906( \
1907 GeometricFieldExpression \
1908 < \
1909 E1, \
1910 typename E1::IntExpr, \
1911 typename E1::UncoupledPatchExpr, \
1912 typename E1::CoupledPatchExpr, \
1913 typename E1::value_type \
1914 > const& u, \
1915 GeometricField<Type, PatchField, GeoMesh> const& fld \
1916) \
1917{ \
1918 typedef typename Expression::GeometricFieldConstRefWrap \
1919 <GeometricField<Type, PatchField, GeoMesh>> E2; \
1920 return Func(u, E2(fld)); \
1921} \
1922template \
1923< \
1924 class Type, template<class> class PatchField, class GeoMesh, \
1925 typename E1 \
1926> \
1927auto Func \
1928( \
1929 GeometricField<Type, PatchField, GeoMesh> const& fld, \
1930 GeometricFieldExpression \
1931 < \
1932 E1, \
1933 typename E1::IntExpr, \
1934 typename E1::UncoupledPatchExpr, \
1935 typename E1::CoupledPatchExpr, \
1936 typename E1::value_type \
1937 > const& u \
1938) \
1939{ \
1940 typedef typename Expression::GeometricFieldConstRefWrap \
1941 <GeometricField<Type, PatchField, GeoMesh>> E2; \
1942 return Func(E2(fld), u); \
1943} \
1944template \
1945< \
1946 class Type, template<class> class PatchField, class GeoMesh \
1947> \
1948auto Func \
1949( \
1950 GeometricField<Type, PatchField, GeoMesh> const& u, \
1951 GeometricField<Type, PatchField, GeoMesh> const& v \
1952) \
1953{ \
1954 typedef typename Expression::GeometricFieldConstRefWrap \
1955 <GeometricField<Type, PatchField, GeoMesh>> E2; \
1956 return Func(E2(u), E2(v)); \
1957} \
1958/* dimensioned types and geometric fields */ \
1959template \
1960< \
1961 class Type1, class Type2, template<class> class PatchField, class GeoMesh \
1962> \
1963auto Func \
1964( \
1965 GeometricField<Type1, PatchField, GeoMesh> const& u, \
1966 dimensioned<Type2> const& v \
1967) \
1968{ \
1969 typedef typename Foam::Expression::UniformGeometricFieldWrap \
1970 <GeometricField<Type1, PatchField, GeoMesh>, Type2> E2; \
1971 return Func(u, E2(u,v)); \
1972} \
1973template \
1974< \
1975 class Type1, class Type2, template<class> class PatchField, class GeoMesh \
1976> \
1977auto Func \
1978( \
1979 dimensioned<Type2> const& u, \
1980 GeometricField<Type1, PatchField, GeoMesh> const& v \
1981) \
1982{ \
1983 typedef typename Foam::Expression::UniformGeometricFieldWrap \
1984 <GeometricField<Type1, PatchField, GeoMesh>, Type2> E2; \
1985 return Func(E2(v, u), v); \
1986} \
1987template<typename E1, class Type> \
1988auto Func \
1989( \
1990 GeometricFieldExpression \
1991 < \
1992 E1, \
1993 typename E1::IntExpr, \
1994 typename E1::UncoupledPatchExpr, \
1995 typename E1::CoupledPatchExpr, \
1996 typename E1::value_type \
1997 > const& u, \
1998 dimensioned<Type> const& v \
1999) \
2000{ \
2001 typedef typename Foam::Expression::UniformGeometricFieldWrap2<Type> E2; \
2002 return Func(u, E2(v)); \
2003} \
2004template<typename E1, class Type> \
2005auto Func \
2006( \
2007 dimensioned<Type> const& u, \
2008 GeometricFieldExpression \
2009 < \
2010 E1, \
2011 typename E1::IntExpr, \
2012 typename E1::UncoupledPatchExpr, \
2013 typename E1::CoupledPatchExpr, \
2014 typename E1::value_type \
2015 > const& v \
2016) \
2017{ \
2018 typedef typename Foam::Expression::UniformGeometricFieldWrap2<Type> E2; \
2019 return Func(E2(u), v); \
2020} \
2021
2022
2023//- GeometricField expressions.
2024
2025// macro arguments:
2026// - 'sin' : name of new function (in Expression namespace)
2027// - '::sin' : per-element function to call
2028// - 'List_sin' : helper class to handle patchFields
2029// - 'GF_sin' : generated expression helper class
2030EXPRESSION_GF_FUNCTION1_DIMLESS(sin, ::sin, List_sin, GF_sin)
2031EXPRESSION_GF_FUNCTION1_DIMLESS(cos, ::cos, List_cos, GF_cos)
2032EXPRESSION_GF_FUNCTION1_DIMLESS(tan, ::tan, List_tan, GF_tan)
2033EXPRESSION_GF_FUNCTION1_DIMLESS(sinh, ::sinh, List_sinh, GF_sinh)
2034EXPRESSION_GF_FUNCTION1_DIMLESS(cosh, ::cosh, List_cosh, GF_cosh)
2035EXPRESSION_GF_FUNCTION1_DIMLESS(tanh, ::tanh, List_tanh, GF_tanh)
2036
2037#undef EXPRESSION_GF_FUNCTION1_DIMLESS
2038
2039EXPRESSION_GF_FUNCTION1(sqr, Foam::sqr, List_sqr, GF_sqr)
2040EXPRESSION_GF_FUNCTION1(sqrt, Foam::sqrt, List_sqrt, GF_sqrt)
2041EXPRESSION_GF_FUNCTION1(magSqr, Foam::magSqr, List_magSqr, GF_magSqr)
2042
2043EXPRESSION_GF_FUNCTION1(mag, Foam::mag, List_mag, GF_mag)
2044EXPRESSION_GF_FUNCTION1(symm, Foam::symm, List_symm, GF_symm)
2045EXPRESSION_GF_FUNCTION1(pow2, Foam::pow2, List_pow2, GF_pow2)
2046EXPRESSION_GF_FUNCTION1(pow3, Foam::pow3, List_pow3, GF_pow3)
2047EXPRESSION_GF_FUNCTION1(pow4, Foam::pow4, List_pow4, GF_pow4)
2048
2049#undef EXPRESSION_GF_FUNCTION1
2050
2051EXPRESSION_GF_FUNCTION2(min, Foam::min, List_min, GF_min)
2052EXPRESSION_GF_FUNCTION2(max, Foam::max, List_max, GF_max)
2053
2054#undef EXPRESSION_GF_FUNCTION2
2055
2061#undef EXPRESSION_GF_OPERATOR
2062
2063
2064
2065// Expressions on constants
2066// ~~~~~~~~~~~~~~~~~~~~~~~~
2068template<class GeoField, class Type = typename GeoField::value_type>
2073 UniformGeometricFieldWrap<GeoField, Type>,
2074 UniformListWrap<Type>,
2075 UniformListWrap<Type>,
2076 UniformListWrap<Type>,
2077 Type
2079{
2080public:
2081
2082 static constexpr bool is_leaf = false; //true;
2084 //- Type to return for internal field
2085 typedef Type value_type;
2086
2087 //- Type to return for patchField
2091
2092
2093private:
2094
2095 const GeoField& elems_;
2096
2097 const value_type val_;
2098
2099public:
2100
2101 // Construct from field (sizes only) and value
2102 UniformGeometricFieldWrap(const GeoField& elems, const value_type val)
2103 :
2105 <
2106 UniformGeometricFieldWrap<GeoField, Type>,
2107 IntExpr,
2111 >
2112 (
2114 orientedType()
2115 ),
2116 elems_(elems),
2117 val_(val)
2120 // Construct from field (sizes only) and value, dimension
2122 (
2123 const GeoField& elems,
2124 const dimensioned<value_type>& val
2125 )
2126 :
2128 <
2129 UniformGeometricFieldWrap<GeoField, Type>,
2130 IntExpr,
2134 >
2135 (
2136 val.dimensions(),
2137 orientedType()
2138 ),
2139 elems_(elems),
2140 val_(val.value())
2141 {}
2142
2143 value_type operator[](const label i) const
2144 {
2145 return val_;
2146 }
2147
2148 auto size() const noexcept
2149 {
2150 return elems_.size();
2152
2153 IntExpr internalField() const
2154 {
2155 return IntExpr(elems_.internalField().size(), val_);
2156 }
2157
2158 UncoupledPatchExpr patchField(const label i) const
2159 {
2160 return UncoupledPatchExpr(elems_.boundaryField()[i].size(), val_);
2161 }
2162
2163 CoupledPatchExpr coupledPatchField(const label i) const
2164 {
2165 return CoupledPatchExpr(elems_.boundaryField()[i].size(), val_);
2166 }
2167
2168 template<class AccessOp>
2169 auto access(const AccessOp& cop, const label i) const
2170 {
2171 // Size+value only
2172 return patchField(i);
2174};
2175
2176// Uniform value. Relies on size -1 being handled properly upstream.
2177template<class T>
2182 UniformGeometricFieldWrap2<T>,
2183 UniformListWrap<T>,
2184 UniformListWrap<T>,
2185 UniformListWrap<T>,
2186 T
2187 >
2189public:
2190
2191 static constexpr bool is_leaf = false; //true;
2192
2193 //- The value type the list contains
2194 typedef T value_type;
2195
2196 //- Type to return for patchField
2200
2201
2202private:
2203
2204 const T val_;
2205
2206
2207public:
2209 // Construct from (dimensionless) value
2210 UniformGeometricFieldWrap2(const T val)
2211 :
2213 <
2215 IntExpr,
2218 T
2219 >
2220 (
2222 orientedType()
2223 ),
2224 val_(val)
2225 {}
2227 // Construct from value, dimension
2229 (
2230 const dimensioned<T>& val
2234 <
2236 IntExpr,
2239 T
2240 >
2241 (
2242 val.dimensions(),
2243 orientedType()
2245 val_(val.value())
2246 {}
2247
2248 T operator[](const label i) const
2249 {
2250 return val_;
2251 }
2252
2253 auto size() const noexcept
2254 {
2255 // Force error if used. Requires lower levels to use max() and hope
2256 // that one of the arguments has size.
2257 return -1;
2258 }
2259
2260 IntExpr internalField() const
2261 {
2262 return IntExpr(-1, val_);
2263 }
2264
2265 UncoupledPatchExpr patchField(const label i) const
2266 {
2267 return UncoupledPatchExpr(-1, val_);
2268 }
2269
2270 CoupledPatchExpr coupledPatchField(const label i) const
2271 {
2272 return CoupledPatchExpr(-1, val_);
2273 }
2274
2275 template<class AccessOp>
2276 auto access(const AccessOp& cop, const label i) const
2277 {
2278 // Size+value only
2279 return patchField(i);
2280 }
2281};
2283//- Fully self-contained constant field wrapper. Not needed?
2284//template<class GeoField>
2285//class UniformGeometricFieldWrap2
2286//:
2287// public GeometricFieldExpression
2288// <
2289// UniformGeometricFieldWrap2<GeoField>,
2290// UniformListWrap<typename GeoField::value_type>,
2291// typename GeoField::value_type
2292// >
2293//{
2294//public:
2295//
2296// static constexpr bool is_leaf = true;
2297//
2298// //- Type to return for internal field
2299// typedef typename GeoField::value_type value_type;
2300//
2301// //- Type to return for patchField
2302// typedef UniformListWrap<value_type> PatchExpr;
2303//
2305//private:
2306//
2307// const value_type val_;
2308//
2309// const label nInternal_;
2311// labelList patchSizes_;
2312//
2313// //const dimensionSet& dimensions_;
2314//
2315//public:
2316//
2317// // Construct from field (sizes only) and value
2318// UniformGeometricFieldWrap2(const GeoField& elems, const value_type val)
2319// :
2320// val_(val),
2321// nInternal_(elems.size()),
2322// patchSizes_(elems.boundaryField().size())
2323// //dimensions_(elems.dimensions()),
2324// {
2325// for (const auto& pfld : elems.boundaryField())
2326// {
2327// patchSizes_[pfld.patch().index()] = pfld.size();
2328// }
2329// }
2330//
2331// // Construct from field (sizes only) and value, dimension
2332// UniformGeometricFieldWrap2
2333// (
2334// const GeoField& elems,
2335// const dimensioned<value_type> val
2336// )
2337// :
2338// val_(val.value()),
2339// nInternal_(elems.size()),
2340// patchSizes_(elems.boundaryField().size())
2341// //dimensions_(val.dimensions()),
2342// {
2343// for (const auto& pfld : elems.boundaryField())
2344// {
2345// patchSizes_[pfld.patch().index()] = pfld.size();
2346// }
2347// }
2348//
2349// value_type operator[](const label i) const
2350// {
2351// return val_;
2352// }
2353//
2354// auto size() const noexcept
2355// {
2356// return nInternal_;
2357// }
2358//
2359// PatchExpr internalField() const
2360// {
2361// return PatchExpr(nInternal_, val_);
2362// }
2363//
2364// PatchExpr patchField(const label i) const
2365// {
2366// return PatchExpr(patchSizes_[i], val_);
2367// }
2368//};
2369
2370
2371/*
2372// Some fvm functions using expressions
2373// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2374
2375// Supply a multiplier, either 1 or -1
2376template<class Expr, class Expr2>
2377void Su
2378(
2379 fvMatrix<typename Expr::value_type>& m,
2380 const Expr2& mult,
2381 const Expr& expression
2382)
2383{
2384 //- Wrap of List as an expression
2385 typedef ListConstRefWrap<typename Expr::value_type> expr;
2386 //- Evaluator of an expression
2387 typedef ListRefWrap<typename Expr::value_type> evaluator;
2388
2389 // Wrap mesh volume
2390 const expr V(m.psi().mesh().V());
2391
2392 // Add expression to source
2393 auto& s = m.source();
2394 evaluator(s, expr(s) + mult*V*expression);
2395}
2396
2397
2398// Always add
2399template<class Expr>
2400void Su
2401(
2402 fvMatrix<typename Expr::value_type>& m,
2403 const Expr& expression
2404)
2405{
2406 //- Wrap of List as an expression
2407 typedef ListConstRefWrap<typename Expr::value_type> expr;
2408 //- Evaluator of an expression
2409 typedef ListRefWrap<typename Expr::value_type> evaluator;
2410
2411 // Wrap mesh volume
2412 const expr V(m.psi().mesh().V());
2413
2414 // Add expression to source
2415 auto& s = m.source();
2416 evaluator(s, expr(s) + V*expression);
2417}
2418
2419
2420template<class Expr>
2421void rhs
2422(
2423 fvMatrix<typename Expr::value_type>& m,
2424 const Expr& expression
2425)
2426{
2427 Su(m, expression);
2429
2430
2431template<class Expr, class Expr2>
2432void Sp
2433(
2434 fvMatrix<typename Expr::value_type>& m,
2435 const Expr2& mult,
2436 const Expr& expression
2437)
2438{
2439 //- Wrap of List as an expression
2440 typedef ListConstRefWrap<typename Expr::value_type> expr;
2441 //- Evaluator of an expression
2442 typedef ListRefWrap<typename Expr::value_type> evaluator;
2443
2444 // Wrap mesh volume
2445 const expr V(m.psi().mesh().V());
2446
2447 // Add expression onto diag
2448 auto& d = m.diag();
2449 evaluator(d, expr(d) - mult*V*expression);
2450}
2451
2452
2453template<class Expr, class Expr2>
2454void SuSp
2455(
2456 fvMatrix<typename Expr::value_type>& m,
2457 const Expr2& mult,
2458 const Expr& expression
2459)
2460{
2461 //- Wrap of constant as a list expression
2462 typedef UniformListWrap<scalar> constant;
2463 //- Wrap of List as an expression
2464 typedef ListConstRefWrap<typename Expr::value_type> expr;
2465 //- Evaluator of an expression
2466 typedef ListRefWrap<typename Expr::value_type> evaluator;
2467
2468 const constant constantZero(expression.size(), 0.0);
2469
2470 // Wrap mesh volume
2471 const expr V(m.psi().mesh().V());
2472
2473 // Linearise expression
2474 auto& diag = m.diag();
2475 auto& source = m.source();
2476
2477 // diag() += domain*max(susp.field(), scalar(0));
2478 evaluator
2479 (
2480 diag,
2481 expr(diag) - mult*V*max(expression, constantZero)
2482 );
2483 // source() -= domain*min(susp.field(), scalar(0))*fld.primitiveField();
2484 evaluator
2485 (
2486 source,
2487 expr(source)
2488 + (
2489 mult
2490 *V
2491 *min(expression, constantZero)
2492 *expr(m.psi().internalField())
2493 )
2494 );
2495}
2496*/
2497
2498
2499} // End namespace Expression
2500
2501// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
2502
2503} // End namespace Foam
2504
2505// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
2506
2507#endif
2508
2509// ************************************************************************* //
#define EXPRESSION_GF_OPERATOR(Op, WrapType, OpFunc)
#define EXPRESSION_GF_FUNCTION2(Func, BaseFunc, WrapType, OpFunc)
#define EXPRESSION_GF_FUNCTION1(Func, BaseFunc, WrapType, OpFunc)
#define EXPRESSION_GF_FUNCTION1_DIMLESS(Func, BaseFunc, WrapType, OpFunc)
Expression templates for List.
label n
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
auto operator[](const label i) const
List_add< typename E1::UncoupledPatchExpr, typename E2::UncoupledPatchExpr > UncoupledPatchExpr
auto access(const AccessOp &cop, const label i) const
List_add< typename E1::CoupledPatchExpr, typename E2::CoupledPatchExpr > CoupledPatchExpr
UncoupledPatchExpr patchField(const label i) const
GF_add(const E1 &u, const E2 &v)
CoupledPatchExpr coupledPatchField(const label i) const
List_dot< typename E1::CoupledPatchExpr, typename E2::CoupledPatchExpr > CoupledPatchExpr
List_dot< typename E1::IntExpr, typename E2::IntExpr > IntExpr
List_dot< typename E1::UncoupledPatchExpr, typename E2::UncoupledPatchExpr > UncoupledPatchExpr
GeometricField expressions.
Expression wrap of const reference to GeometricField.
auto access(const AccessOp &cop, const label i) const
UncoupledPatchExpr patchField(const label i) const
CoupledPatchExpr coupledPatchField(const label i) const
Expression wrap of const tmp to GeometricField.
GeometricFieldConstTmpWrap(const GeometricFieldConstTmpWrap< GeoField > &w)
auto access(const AccessOp &cop, const label i) const
static constexpr bool is_leaf
Have expressions use copy to maintain tmp refCount.
ListConstRefWrap< value_type > IntExpr
Type to return for patchField.
UncoupledPatchExpr patchField(const label i) const
ListConstTmpWrap< Field< value_type > > CoupledPatchExpr
CoupledPatchExpr coupledPatchField(const label i) const
GeometricFieldConstTmpWrap(const tmp< this_type > &elems)
GeoField::value_type value_type
Type to return for internal field.
auto access(const Op &cop, const label i) const
GeometricFieldExpression(const dimensionSet &dimensions, const orientedType oriented)
GeoField & evaluate(GeoField &fld, const bool force=false) const
Helper to evaluate a GeometricField.
const dimensionSet & dimensions() const noexcept
UncoupledPatchExpr patchField(const label i) const
const orientedType & oriented() const noexcept
CoupledPatchExpr coupledPatchField(const label i) const
Expression wrap of non-const reference to GeometricField.
auto access(const AccessOp &cop, const label i) const
GeometricFieldRefWrap(this_type &elems)
Copy construct.
this_type & evaluate(const GeometricFieldExpression< E, typename E::IntExpr, typename E::UncoupledPatchExpr, typename E::CoupledPatchExpr, typename E::value_type > &expr)
Evaluate and return as GeoField. Rename to evaluate to make it clear it takes time?...
UncoupledPatchExpr patchField(const label i) const
CoupledPatchExpr coupledPatchField(const label i)
CoupledPatchExpr coupledPatchField(const label i) const
GeometricFieldRefWrap(this_type &elems, const GeometricFieldExpression< E, typename E::IntExpr, typename E::UncoupledPatchExpr, typename E::CoupledPatchExpr, typename E::value_type > &expr)
GeometricFieldRefWrap(this_type &&elems)
Move construct.
UncoupledPatchExpr patchField(const label i)
Expression wrap of const reference to UList.
Expression wrap of const tmp to List.
Expression wrap of non-const reference to List.
Expression wrap of tmp to List.
Expression wrapping function for unary cos function.
Expression wrapping function for unary cosh function.
Expression wrapping function for unary magSqr function.
Expression wrapping function for unary mag function.
Expression wrapping function for binary max function.
Expression wrapping function for binary min function.
Expression wrapping function for unary pow2 function.
Expression wrapping function for unary pow3 function.
Expression wrapping function for unary pow4 function.
Expression wrapping function for unary sin function.
Expression wrapping function for unary sinh function.
Expression wrapping function for unary sqr function.
Expression wrapping function for unary sqrt function.
Expression wrapping function for unary symm function.
Expression wrapping function for unary tan function.
Expression wrapping function for unary tanh function.
Expression wrap of multiple lists.
void evaluate(ListsRefWrap< E > &exprWarp, const Container &ds)
Assignment.
UniformListWrap< T > IntExpr
Type to return for patchField.
auto access(const AccessOp &cop, const label i) const
UncoupledPatchExpr patchField(const label i) const
CoupledPatchExpr coupledPatchField(const label i) const
auto access(const AccessOp &cop, const label i) const
Type value_type
Type to return for internal field.
UniformGeometricFieldWrap(const GeoField &elems, const value_type val)
UncoupledPatchExpr patchField(const label i) const
UniformListWrap< value_type > IntExpr
Type to return for patchField.
CoupledPatchExpr coupledPatchField(const label i) const
Expression wrap of a List with a uniform value.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
Generic mesh wrapper used by volMesh, surfaceMesh, pointMesh etc.
Definition GeoMesh.H:46
Generic GeometricField class.
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
Definition List.H:138
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
Generic dimensioned Type class.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition fvMatrix.H:118
Class to determine the 'oriented' status of surface fields.
constant condensation/saturation model.
A class for managing temporary objects.
Definition tmp.H:75
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
zeroField Su
Definition alphaSuSp.H:1
zeroField Sp
Definition alphaSuSp.H:2
A namespace for expression templates.
auto tanh(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
auto cos(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
ListRefWrap< typename Expr::value_type > evaluator
Evaluator of an expression.
auto sin(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
g_pow2< E1 > pow2(const GenericExpression< E1 > &u)
auto cosh(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
g_sqrt< E1 > sqrt(const GenericExpression< E1 > &u)
g_sqr< E1 > sqr(const GenericExpression< E1 > &u)
g_pow4< E1 > pow4(const GenericExpression< E1 > &u)
ListConstRefWrap< typename Expr::value_type > expr
Fully self-contained constant field wrapper. Not needed?
auto max(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u, GeometricFieldExpression< E2, typename E2::IntExpr, typename E2::UncoupledPatchExpr, typename E2::CoupledPatchExpr, typename E2::value_type > const &v)
g_symm< E1 > symm(const GenericExpression< E1 > &u)
auto sinh(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
auto tan(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
const expr V(m.psi().mesh().V())
g_pow3< E1 > pow3(const GenericExpression< E1 > &u)
auto min(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u, GeometricFieldExpression< E2, typename E2::IntExpr, typename E2::UncoupledPatchExpr, typename E2::CoupledPatchExpr, typename E2::value_type > const &v)
auto mag(GeometricFieldExpression< E1, typename E1::IntExpr, typename E1::UncoupledPatchExpr, typename E1::CoupledPatchExpr, typename E1::value_type > const &u)
g_magSqr< E1 > magSqr(const GenericExpression< E1 > &u)
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
dimensionedSymmTensor symm(const dimensionedSymmTensor &dt)
const dimensionSet dimless
Dimensionless.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar pow3(const dimensionedScalar &ds)
dimensionedScalar sqrt(const dimensionedScalar &ds)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
dimensionedScalar pow4(const dimensionedScalar &ds)
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
const direction noexcept
Definition scalarImpl.H:265
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
dimensionSet pow2(const dimensionSet &ds)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
void SuSp(fvMatrix< typename Expr::value_type > &m, const Expr2 &mult, const Expr &expression)
#define Op(opName, op)
Definition ops.H:99