Loading...
Searching...
No Matches
ListExpression.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 Copyright (C) 2025 Advanced Micro Devices, Inc.
11-------------------------------------------------------------------------------
12License
13 This file is part of OpenFOAM.
14
15 OpenFOAM is free software: you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27
28InNamespace
29 Foam::Expression
30
31Description
32 Expression templates for List
33
34SourceFiles
35 ListExpression.H
36
37\*---------------------------------------------------------------------------*/
38
39#ifndef Foam_ListExpression_H
40#define Foam_ListExpression_H
41
42// Assume execution headers are complete on the target system
43#define Foam_Expression_execution
44
45#include <cassert>
46
47// Parallel execution
48#if defined(_WIN32) || (defined(FOAM_REAL_GNUC) && (FOAM_REAL_GNUC < 10))
49// Ignore on mingw (needs tbb, which is less likely to be installed)
50// - older gcc also gives problems (has execution, but not everything...)
51#elif __has_include(<execution>) && defined(Foam_Expression_execution)
52 #include <execution>
53#endif
54
55#include "List.H"
56#include "labelPair.H"
57#include "dimensionedType.H"
58#include "orientedType.H"
59#include "scalar.H"
60
61// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
62
63namespace Foam
64{
65namespace Expression
66{
67
68/*---------------------------------------------------------------------------*\
69 Class ListExpression Declaration
70\*---------------------------------------------------------------------------*/
71
72//- Expression templates for List
73template<typename E>
76public:
77 static constexpr bool is_leaf = false;
78
79 auto operator[](const label i) const
80 {
81 // Delegation to the actual expression type. This avoids dynamic
82 // polymorphism (a.k.a. virtual functions in C++)
83 return static_cast<E const&>(*this)[i];
84 }
85 auto size() const noexcept { return static_cast<E const&>(*this).size(); }
86
87 //- Helper: assign to passed in list
88 template<class Container>
89 Container& fill(Container& lst) const
90 {
91#ifdef _OPENMP
92 int loopLen = this->size();
93 _Pragma("omp target teams distribute parallel for if(loopLen > 1000)")
94 for(int i = 0; i < loopLen; ++i)
95 {
96 auto src = static_cast<E const&>(*this).cbegin() + i;
97 lst[i] = *src;
98 }
99#else
100 std::copy
101 (
102 #if (defined(__APPLE__) && defined(__clang__)) || defined(_WIN32)
103 // Currently not working (2025-10-06) with par_unseq. Works with
104 // sequential.
105 #elif (__cpp_lib_execution >= 201902L)
106 std::execution::par_unseq,
107 #else
108 // Execution policy not supported
109 #endif
110 static_cast<E const&>(*this).cbegin(),
111 static_cast<E const&>(*this).cend(),
112 lst.begin()
113 );
114#endif
115 return lst;
116 }
117 //- Helper: assign to passed in list
118 template<class Container>
119 Container& evaluate(Container& lst) const
120 {
121 lst.resize_nocopy(this->size());
122 fill(lst);
123 return lst;
124 }
125};
126
127
128/*---------------------------------------------------------------------------*\
129 Class ListWrap Declaration
130\*---------------------------------------------------------------------------*/
131
132//- Expression wrap of a List
133template<class T>
134class ListWrap
135:
136 public ListExpression<ListWrap<T>>
137{
138 List<T> elems_;
139
140public:
141 static constexpr bool is_leaf = true;
142
143 typedef T value_type;
144
145 //- Copy construct
146 ListWrap(const ListWrap<T>& elems)
148 elems_(elems.data())
149 {}
150
151 //- Move construct
153 :
154 elems_(std::move(elems.data()))
155 {}
156
157 //- Construct from initializer list
158 ListWrap(std::initializer_list<T> elems)
159 :
160 elems_(elems)
161 {}
162
163 ListWrap(const UList<T>& elems)
164 :
165 elems_(elems)
166 {}
167
168 // Construct from ListExpression, forcing its evaluation.
169 template<typename E>
171 :
172 elems_(expr.size())
174 expr.evaluate(elems_);
175 }
176
177 // Access underlying data
178 const auto& data() const
179 {
180 return elems_;
181 }
182
183 // Access underlying data
184 auto& data()
185 {
186 return elems_;
187 }
189 value_type operator[](const label i) const
190 {
191 return elems_[i];
192 }
193
194 value_type& operator[](const label i)
195 {
196 return elems_[i];
197 }
198
199 auto size() const noexcept
200 {
201 return elems_.size();
202 }
203
205 auto cbegin() const
206 {
207 return elems_.cbegin();
208 }
209 auto cend() const
210 {
211 return elems_.cend();
212 }
213
214 typedef typename List<T>::iterator iterator;
215 auto begin()
216 {
217 return elems_.begin();
218 }
219 auto end()
220 {
221 return elems_.end();
222 }
223};
226/*---------------------------------------------------------------------------*\
227 Class ListRefWrap Declaration
228\*---------------------------------------------------------------------------*/
230//- Expression wrap of non-const reference to List
231template<class T>
232class ListRefWrap
233:
234 public ListExpression<ListRefWrap<T>>
235{
236 List<T>& elems_;
237
238public:
239 static constexpr bool is_leaf = false; //true;
240
241 typedef T value_type;
242
243 //- Copy construct
245 :
246 elems_(w.elems_)
247 {}
248
249 //- Move construct
252 elems_(elems)
253 {}
254
255 //- Construct from List and expected size. This is to enforce that
256 //- our size() member function returns the correct size. Use the
257 //- construct-from-expression otherwise.
258 ListRefWrap(const label size, List<T>& elems)
259 :
260 elems_(elems)
261 {
262 elems_.resize_nocopy(size);
263 }
264
265 // Construct from ListExpression, forcing its evaluation.
266 template<typename E>
268 (
269 List<T>& elems,
271 )
272 :
273 elems_(elems)
274 {
275 expr.evaluate(elems_);
277
278 //- Assignment
279 template<typename E>
280 void operator=(const ListExpression<E>& expr)
281 {
282 expr.evaluate(elems_);
283 }
284
285 // Access underlying data
286 const auto& data() const
287 {
288 return elems_;
289 }
290
291 // Access underlying data
292 auto& data()
293 {
294 return elems_;
295 }
296
297 value_type operator[](const label i) const
298 {
299 return elems_[i];
301
302 value_type& operator[](const label i)
303 {
304 return elems_[i];
305 }
307 auto size() const noexcept
308 {
309 return elems_.size();
310 }
311
313 auto cbegin() const
314 {
315 return elems_.cbegin();
316 }
317 auto cend() const
318 {
319 return elems_.cend();
320 }
321
322 typedef typename List<T>::iterator iterator;
323 auto begin()
324 {
325 return elems_.begin();
326 }
327 auto end()
328 {
329 return elems_.end();
330 }
331};
334/*---------------------------------------------------------------------------*\
335 Class ListConstRefWrap Declaration
336\*---------------------------------------------------------------------------*/
338//- Expression wrap of const reference to UList
339template<class T>
341:
342 public ListExpression<ListConstRefWrap<T>>
344 const UList<T>& elems_;
345
346public:
348 // ! Store as copy (since holds reference)
349 static constexpr bool is_leaf = false;
350
351 typedef T value_type;
352
353 // construct from components
354 ListConstRefWrap(const UList<T>& elems)
355 :
356 elems_(elems)
357 {}
358
359 // returns the underlying data
360 const auto& data() const
361 {
362 return elems_;
363 }
364
365 value_type operator[](const label i) const
366 {
367 return elems_[i];
368 }
369
370 auto size() const noexcept
372 return elems_.size();
374
375 //typedef typename UList<T>::const_iterator const_iterator;
376 struct const_iterator
377 {
378 // Minimalistic const_iter implementation
379 typedef typename UList<T>::const_iterator ConstIter;
380 typedef typename std::iterator_traits<ConstIter> ConstIterTraits;
381 using difference_type = typename ConstIterTraits::difference_type;
382 using value_type = typename ConstIterTraits::value_type;
383 using pointer = typename ConstIterTraits::pointer;
384 using reference = typename ConstIterTraits::reference;
385//using iterator_category = typename ConstIterTraits::iterator_category;
386 using iterator_category = std::random_access_iterator_tag;
389
390 const_iterator(ConstIter it) : base_(it) {}
391 const_iterator() : base_() {}
393 {
394 base_ = it;
395 return base_;
396 }
397
398 // Indexing operators
399
400 value_type operator*() const
402 return *base_;
404 //value_type operator->() const
405 //{
406 // return *base_;
407 //}
409 {
410 return *(base_+i);
411 }
413 // Increment/Decrement
416 {
417 ++base_;
418 return *this;
419 }
421 {
422 const_iterator old(*this);
423 ++base_;
424 return old;
425 }
427 {
428 --base_;
429 return *this;
432 {
433 const_iterator old(*this);
434 --base_;
435 return old;
436 }
438 // Arithmetic operators
439
441 {
443 }
445 {
446 return const_iterator(base_-i);
447 }
449 {
450 return (base_ - it.base_);
451 }
452
453 // Comparison operators
454
455 bool operator==(const const_iterator& it) const
456 {
457 return (base_ == it.base_);
458 }
459 bool operator!=(const const_iterator& it) const
460 {
461 return (base_ != it.base_);
463 bool operator<(const const_iterator& it) const
464 {
465 return (base_ < it.base_);
467 bool operator<=(const const_iterator& it) const
468 {
469 return (base_ <= it.base_);
471 bool operator>(const const_iterator& it) const
472 {
473 return (base_ > it.base_);
474 }
475 bool operator>=(const const_iterator& it) const
476 {
477 return (base_ >= it.base_);
478 }
479
480 // Compound assignment
485 return *this;
486 }
488 {
490 return *this;
491 }
492 };
493 auto cbegin() const
494 {
495 return const_iterator(elems_.cbegin());
496 }
497 auto cend() const
498 {
499 return const_iterator(elems_.cend());
500 }
501};
502
503
504/*---------------------------------------------------------------------------*\
505 Class ListTmpWrap Declaration
506\*---------------------------------------------------------------------------*/
507
508//- Expression wrap of tmp to List
509template<class T>
510class ListTmpWrap
511:
512 public ListExpression<ListTmpWrap<T>>
513{
514 tmp<T> elems_;
516public:
517
518 //- Have expressions use copy to maintain tmp refCount
519 static constexpr bool is_leaf = false;
520
521 typedef typename T::value_type value_type;
522
523 // Construct from components
524 ListTmpWrap(const tmp<T>& elems)
525 :
526 elems_(elems)
527 {}
528
529 // Construct from components
530 ListTmpWrap(tmp<T>& elems)
531 :
532 elems_(elems)
533 {}
535 // Construct from ListExpression, forcing its evaluation.
536 template<typename E>
538 (
539 tmp<T>& elems,
541 )
542 :
543 elems_(elems)
544 {
545 expr.evaluate(elems_.ref());
546 }
548 //- Assignment
549 template<typename E>
551 {
552 expr.evaluate(elems_.ref());
553 }
554
555 // returns the underlying data
556 const T& data() const
557 {
558 return elems_();
559 }
560
561 value_type operator[](const label i) const
562 {
563 return elems_()[i];
564 }
565
566 auto size() const noexcept
567 {
568 return elems_().size();
569 }
570
571 typedef typename T::const_iterator const_iterator;
572 auto cbegin() const
573 {
574 return elems_().cbegin();
575 }
576 auto cend() const
577 {
578 return elems_().cend();
579 }
580 typedef typename List<T>::iterator iterator;
581 auto begin()
582 {
583 return elems_().begin();
585 auto end()
586 {
587 return elems_().end();
588 }
590
591
592/*---------------------------------------------------------------------------*\
593 Class ListConstTmpWrap Declaration
594\*---------------------------------------------------------------------------*/
595
596//- Expression wrap of const tmp to List
597template<class T>
600 public ListExpression<ListConstTmpWrap<T>>
601{
602 const tmp<T> elems_;
603
604public:
605
606 //- Have expressions use copy to maintain tmp refCount
607 static constexpr bool is_leaf = false;
609 typedef typename T::value_type value_type;
610
611 // Construct from components
612 ListConstTmpWrap(const tmp<T>& elems)
614 elems_(elems)
615 {}
616
617 // returns the underlying data
618 const T& data() const
619 {
620 return elems_();
621 }
622
623 value_type operator[](const label i) const
624 {
625 return elems_()[i];
626 }
627
628 auto size() const noexcept
629 {
630 return elems_().size();
631 }
632
633 //- Define our own iterator so we can refer to it. 'normal', e.g. double*
634 // iterator will not work we'd have to use the iterator traits to get
635 // at its e.g. difference_type from other classes. TBD.
636 struct const_iterator
637 {
638 // Minimalistic const_iter implementation
639 typedef typename T::const_iterator ConstIter;
640 typedef typename std::iterator_traits<ConstIter> ConstIterTraits;
641 using difference_type = typename ConstIterTraits::difference_type;
642 using value_type = typename ConstIterTraits::value_type;
643 using pointer = typename ConstIterTraits::pointer;
644 using reference = typename ConstIterTraits::reference;
645 using iterator_category = typename ConstIterTraits::iterator_category;
646
648
649 const_iterator(ConstIter it) : base_(it) {}
651 {
652 return *base_;
653 }
656 return base_[i];
657 }
659 {
661 return *this;
662 }
664 {
665 const_iterator old(*this);
666 ++base_;
667 return old;
668 }
670 {
672 return *this;
673 }
676 const_iterator old(*this);
678 return old;
681 {
683 }
686 return const_iterator(base_-i);
687 }
690 return (base_ - it.base_);
691 }
692 bool operator==(const const_iterator& it) const
694 return (base_ == it.base_);
695 }
696 bool operator!=(const const_iterator& it) const
697 {
698 return (base_ != it.base_);
699 }
700 bool operator<(const const_iterator& it) const
701 {
702 return (base_ < it.base_);
703 }
704 bool operator<=(const const_iterator& it) const
705 {
706 return (base_ <= it.base_);
707 }
708 bool operator>(const const_iterator& it) const
710 return (base_ > it.base_);
711 }
712 bool operator>=(const const_iterator& it) const
713 {
714 return (base_ >= it.base_);
717 {
718 base_ += n;
719 return base_;
720 }
722 {
724 return base_;
725 }
726 };
727 //typedef typename T::const_iterator const_iterator;
728 auto cbegin() const
729 {
730 return const_iterator(elems_().cbegin());
732 auto cend() const
733 {
734 return const_iterator(elems_().cend());
736};
737
738
739/*---------------------------------------------------------------------------*\
740 Class IndirectConstWrap Declaration
741\*---------------------------------------------------------------------------*/
742
743//- Expression wrap of indirection
744//
745// \tparam E1 : expression to get value of element i
746template<typename E1>
748:
749 public ListExpression
750 <
751 IndirectConstWrap<E1>
752 >
753{
754 //- Expression for cell values
755 typename std::conditional
757 E1::is_leaf,
758 const E1&,
759 const E1
760 >::type values_;
761
762 const labelUList& addr_;
764public:
765
766 // ! Store as copy (since holds reference)
767 static constexpr bool is_leaf = false;
768
769 typedef typename E1::value_type value_type;
770
771 // construct from components
773 (
774 const E1& values,
775 const labelUList& addr
776 )
777 :
778 values_(values),
779 addr_(addr)
780 {}
781
782 value_type operator[](const label i) const
783 {
784 return values_[addr_[i]];
786 label size() const
787 {
788 return addr_.size();
789 }
790
791 struct const_iterator
792 {
793 // See IndirectListBase::const_iterator
794
795 //- Step type for addressing
796 using difference_type = label;
797
798 //- Iterator definition for E1
799 typedef typename E1::const_iterator ConstIter;
800 //using difference_type = typename ConstIter::difference_type;
801 using value_type = typename ConstIter::value_type;
802 using pointer = typename ConstIter::pointer;
803 using reference = typename ConstIter::reference;
804 using iterator_category = std::random_access_iterator_tag;
805
808
810 (
811 ConstIter begin,
813 )
814 :
815 begin_(begin),
816 iter_(addrIter)
817 {}
818 auto operator*() const
819 {
820 return *(begin_ + *iter_);
821 }
823 {
824 return *(begin_+iter_[i]);
825 }
827 {
828 ++iter_;
829 return *this;
830 }
832 {
833 const_iterator old(*this);
834 ++iter_;
835 return old;
836 }
839 --iter_;
840 return *this;
841 }
844 const_iterator old(*this);
846 return old;
849 {
854 return const_iterator(begin_, iter_-i);
855 }
857 {
858 return (iter_ - it.iter_);
859 }
860 bool operator==(const const_iterator& it) const
861 {
862 return iter_ == it.iter_;
863 }
864 bool operator!=(const const_iterator& it) const
865 {
866 return iter_ != it.iter_;
867 }
868 bool operator<(const const_iterator& it) const
869 {
870 return (iter_ < it.iter_);
871 }
872 bool operator<=(const const_iterator& it) const
873 {
874 return (iter_ <= it.iter_);
876 bool operator>(const const_iterator& it) const
877 {
878 return (iter_ > it.iter_);
879 }
880 bool operator>=(const const_iterator& it) const
882 return (iter_ >= it.iter_);
883 }
885 {
887 return *this;
888 }
890 {
891 iter_ -= n;
892 return *this;
893 }
894 };
895 auto cbegin() const
897 return const_iterator(values_.cbegin(), addr_.cbegin());
898 }
899 auto cend() const
901 return const_iterator(values_.cbegin(), addr_.cend());
902 }
903};
905
906// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
907
908// Expresssions on List
909// ~~~~~~~~~~~~~~~~~~~~
910
911#undef EXPRESSION_FUNCTION1
912#define EXPRESSION_FUNCTION1(Func, BaseFunc, OpFunc) \
913 \
914template<typename E1> \
915class OpFunc \
916: \
917 public ListExpression< \
918 OpFunc<E1> \
919 > \
920{ \
921 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
922 \
923public: \
924 static constexpr bool is_leaf = false; \
925 \
926 typedef decltype(BaseFunc(std::declval<typename E1::value_type>())) \
927 value_type; \
929 OpFunc(const E1& u) \
930 : \
931 u_(u) \
932 {} \
934 auto operator[](const label i) const \
935 { \
936 return BaseFunc(u_[i]); \
937 } \
938 \
939 auto size() const noexcept { return u_.size(); } \
940 \
941 struct const_iterator \
942 { \
943 typedef typename E1::const_iterator ConstIter; \
944 using difference_type = typename ConstIter::difference_type; \
945 using value_type = typename ConstIter::value_type; \
946 using pointer = typename ConstIter::pointer; \
947 using reference = typename ConstIter::reference; \
948 using iterator_category = typename ConstIter::iterator_category; \
949 \
950 ConstIter base_; \
951 \
952 const_iterator(ConstIter it) : base_(it) {} \
953 auto operator*() const \
954 { \
955 return BaseFunc(*base_); \
956 } \
957 auto operator[](const difference_type i) const \
958 { \
959 return BaseFunc(base_[i]); \
960 } \
961 const_iterator& operator++() \
962 { \
963 ++base_; \
964 return *this; \
965 } \
966 const_iterator operator++(int) \
967 { \
968 const_iterator old(*this); \
969 ++base_; \
970 return old; \
971 } \
972 const_iterator& operator--() \
973 { \
974 --base_; \
975 return *this; \
976 } \
977 const_iterator operator--(int) \
978 { \
979 const_iterator old(*this); \
980 --base_; \
981 return old; \
982 } \
983 const_iterator operator+(const difference_type i) const \
984 { \
985 return const_iterator(base_+i); \
986 } \
987 const_iterator operator-(const difference_type i) const \
988 { \
989 return const_iterator(base_-i); \
990 } \
991 difference_type operator-(const const_iterator& it) const \
992 { \
993 return (base_ - it.base_); \
994 } \
995 bool operator==(const const_iterator& it) const \
996 { \
997 return base_ == it.base_; \
998 } \
999 bool operator!=(const const_iterator& it) const \
1000 { \
1001 return base_ != it.base_; \
1002 } \
1003 bool operator<(const const_iterator& it) const \
1004 { \
1005 return (base_ < it.base_); \
1006 } \
1007 bool operator<=(const const_iterator& it) const \
1008 { \
1009 return (base_ <= it.base_); \
1010 } \
1011 bool operator>(const const_iterator& it) const \
1012 { \
1013 return (base_ > it.base_); \
1014 } \
1015 bool operator>=(const const_iterator& it) const \
1016 { \
1017 return (base_ >= it.base_); \
1018 } \
1019 const_iterator& operator+=(const difference_type n) \
1020 { \
1021 base_ += n; \
1022 return *this; \
1023 } \
1024 const_iterator& operator-=(const difference_type n) \
1025 { \
1026 base_ -= n; \
1027 return *this; \
1028 } \
1029 }; \
1030 const_iterator cbegin() const \
1031 { \
1032 return const_iterator(u_.cbegin()); \
1033 } \
1034 const_iterator cend() const \
1035 { \
1036 return const_iterator(u_.cend()); \
1037 } \
1038}; \
1039template<typename E1> \
1040auto Func \
1041( \
1042 const ListExpression<E1>& u \
1043) \
1044{ \
1045 return OpFunc<E1>(static_cast<const E1&>(u)); \
1046} \
1047template<class Type> \
1048auto Func(UList<Type> const& u) \
1049{ \
1050 typedef typename Expression::ListConstRefWrap<Type> E2; \
1051 return Func(E2(u)); \
1052}
1053
1054
1055//- List negation
1056// Do '-' separately until we work out macro expansion...
1057template<typename E1>
1058class List_negate
1059:
1060 public ListExpression<List_negate<E1>>
1061{
1062 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
1063
1064public:
1065 static constexpr bool is_leaf = false;
1066
1067 typedef typename E1::value_type value_type;
1068
1069 List_negate(const E1& u)
1070 :
1071 u_(u)
1072 {}
1073
1074 auto operator[](const label i) const
1075 {
1076 return -u_[i];
1077 }
1078
1079 auto size() const noexcept { return u_.size(); }
1080
1081 struct const_iterator
1082 {
1083 // Minimalistic const_iter implementation
1084
1085 typedef typename E1::const_iterator ConstIter;
1086 using difference_type = typename ConstIter::difference_type;
1087 using value_type = typename ConstIter::value_type;
1088 using pointer = typename ConstIter::pointer;
1089 using reference = typename ConstIter::reference;
1090 using iterator_category = typename ConstIter::iterator_category;
1091
1093
1094 const_iterator(ConstIter it) : base_(it) {}
1095 value_type operator*() const
1096 {
1097 return -(*base_);
1098 }
1100 {
1101 return -*(base_+i);
1102 }
1104 {
1106 return *this;
1107 }
1109 {
1110 const_iterator old(*this);
1111 ++base_;
1112 return old;
1113 }
1114 const_iterator& operator--()
1115 {
1117 return *this;
1118 }
1120 {
1121 const_iterator old(*this);
1122 --base_;
1123 return old;
1124 }
1127 return const_iterator(base_+i);
1130 {
1131 return const_iterator(base_-i);
1135 return (base_ - it.base_);
1137 bool operator==(const const_iterator& it) const
1138 {
1139 return base_ == it.base_;
1140 }
1141 bool operator!=(const const_iterator& it) const
1143 return base_ != it.base_;
1144 }
1145 bool operator<(const const_iterator& it) const
1147 return (base_ < it.base_);
1148 }
1149 bool operator<=(const const_iterator& it) const
1151 return (base_ <= it.base_);
1152 }
1153 bool operator>(const const_iterator& it) const
1154 {
1155 return (base_ > it.base_);
1156 }
1157 bool operator>=(const const_iterator& it) const
1158 {
1159 return (base_ >= it.base_);
1160 }
1162 {
1163 base_ += n;
1164 return base_;
1165 }
1167 {
1168 base_ -= n;
1169 return base_;
1170 }
1171 };
1173 {
1174 return const_iterator(u_.cbegin());
1175 }
1177 {
1178 return const_iterator(u_.cend());
1179 }
1181template<typename E1>
1182auto operator-(const ListExpression<E1>& u)
1183{
1184 return List_negate<E1>(static_cast<const E1&>(u));
1185}
1186template<class Type>
1187auto operator-(UList<Type> const& u)
1189 typedef typename Expression::ListConstRefWrap<Type> E2;
1190 return List_negate(E2(u));
1191}
1193#undef EXPRESSION_FUNCTION2
1194#define EXPRESSION_FUNCTION2(Func, BaseFunc, OpFunc) \
1195 \
1196template<typename E1, typename E2> \
1197class OpFunc \
1198: \
1199 public ListExpression \
1200 < \
1201 OpFunc<E1, E2> \
1202 > \
1203{ \
1204 /* cref if leaf, copy otherwise */ \
1205 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
1206 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
1207 \
1208public: \
1209 static constexpr bool is_leaf = false; \
1210 \
1211 /* Type to return for internal field */ \
1212 typedef typename E1::value_type value_type; \
1214 OpFunc(const E1& u, const E2& v) \
1215 : \
1216 u_(u), v_(v) \
1217 { \
1218 assert(u_.size() == -1 || v_.size() == -1 || u_.size() == v_.size()); \
1219 } \
1220 auto operator[](const label i) const \
1221 { \
1222 return BaseFunc(u_[i], v_[i]); \
1223 } \
1224 auto size() const noexcept { return Foam::max(u_.size(), v_.size()); } \
1225 \
1226 struct const_iterator \
1227 { \
1228 typedef typename E1::const_iterator E1Iter; \
1229 typedef typename E2::const_iterator E2Iter; \
1230 using difference_type = typename E1Iter::difference_type; \
1231 using value_type = typename E1Iter::value_type; \
1232 using pointer = typename E1Iter::pointer; \
1233 using reference = typename E1Iter::reference; \
1234 using iterator_category = typename E1Iter::iterator_category; \
1235 \
1236 E1Iter uIter_; \
1237 E2Iter vIter_; \
1238 \
1239 const_iterator(E1Iter uIter, E2Iter vIter) \
1240 : \
1241 uIter_(uIter), \
1242 vIter_(vIter) \
1243 {} \
1244 auto operator*() const \
1245 { \
1246 return BaseFunc(*uIter_, *vIter_); \
1247 } \
1248 const_iterator& operator++() \
1249 { \
1250 ++uIter_; \
1251 ++vIter_; \
1252 return *this; \
1253 } \
1254 difference_type operator-(const const_iterator& it) const \
1255 { \
1256 return (uIter_ - it.uIter_); \
1257 } \
1258 const_iterator operator+(const label i) const \
1259 { \
1260 return const_iterator(uIter_+i, vIter_+i); \
1261 } \
1262 bool operator==(const const_iterator& it) const \
1263 { \
1264 return uIter_ == it.uIter_ && vIter_ == it.vIter_; \
1265 } \
1266 bool operator!=(const const_iterator& it) const \
1267 { \
1268 return !operator==(it); \
1269 } \
1270 bool operator<(const const_iterator& it) const \
1271 { \
1272 return (uIter_ < it.uIter_); \
1273 } \
1274 }; \
1275 const_iterator cbegin() const \
1276 { \
1277 return const_iterator(u_.cbegin(), v_.cbegin()); \
1278 } \
1279 const_iterator cend() const \
1280 { \
1281 return const_iterator(u_.cend(), v_.cend()); \
1282 } \
1283}; \
1284template<typename E1, typename E2> \
1285auto Func \
1286( \
1287 ListExpression \
1288 < \
1289 E1 \
1290 > const& u, \
1291 ListExpression \
1292 < \
1293 E2 \
1294 > const& v \
1295) \
1296{ \
1297 return OpFunc<E1, E2> \
1298 ( \
1299 static_cast<const E1&>(u), \
1300 static_cast<const E2&>(v) \
1301 ); \
1302} \
1303template<typename E1, class Type> \
1304auto Func \
1305( \
1306 ListExpression \
1307 < \
1308 E1 \
1309 > const& u, \
1310 UList<Type> const& v \
1311) \
1312{ \
1313 typedef typename Expression::ListConstRefWrap<Type> E2; \
1314 return Func(u, E2(v)); \
1315} \
1316template<typename E1, class Type> \
1317auto Func \
1318( \
1319 UList<Type> const& u, \
1320 ListExpression \
1321 < \
1322 E1 \
1323 > const& v \
1324) \
1325{ \
1326 typedef typename Expression::ListConstRefWrap<Type> E2; \
1327 return Func(E2(u), v); \
1328} \
1329template<class Type1, class Type2> \
1330auto Func(UList<Type1> const& u, UList<Type2> const& v) \
1331{ \
1332 typedef typename Expression::ListConstRefWrap<Type1> E1; \
1333 typedef typename Expression::ListConstRefWrap<Type2> E2; \
1334 return Func(E1(u), E2(v)); \
1335} \
1336template \
1337< \
1338 typename E1, \
1339 class Type, \
1340 class = std::enable_if_t \
1341 < \
1342 (std::is_arithmetic_v<Type> || Foam::is_vectorspace_v<Type>) \
1343 > \
1344> \
1345auto Func \
1346( \
1347 ListExpression \
1348 < \
1349 E1 \
1350 > const& u, \
1351 const Type& v \
1352) \
1353{ \
1354 typedef typename Expression::UniformListWrap<Type> E2; \
1355 return Func(u, E2(u.size(), v)); \
1356} \
1357template \
1358< \
1359 typename E1, \
1360 class Type, \
1361 class = std::enable_if_t \
1362 < \
1363 (std::is_arithmetic_v<Type> || Foam::is_vectorspace_v<Type>) \
1364 > \
1365> \
1366auto Func \
1367( \
1368 const Type& u, \
1369 ListExpression \
1370 < \
1371 E1 \
1372 > const& v \
1373) \
1374{ \
1375 typedef typename Expression::UniformListWrap<Type> E2; \
1376 return Func(E2(v.size(), u), v); \
1377} \
1378template \
1379< \
1380 class Type, \
1381 class TypeT = Type, \
1382 class = std::enable_if_t \
1383 < \
1384 (std::is_arithmetic_v<TypeT> || Foam::is_vectorspace_v<TypeT>) \
1385 > \
1386> \
1387auto Func \
1388( \
1389 UList<Type> const& u, \
1390 TypeT const& v \
1391) \
1392{ \
1393 typedef typename Expression::ListConstRefWrap<Type> E1; \
1394 typedef typename Expression::UniformListWrap<TypeT> E2; \
1395 return Func(E1(u), E2(u.size(), v)); \
1396} \
1397template \
1398< \
1399 class Type, \
1400 class TypeT = Type, \
1401 class = std::enable_if_t \
1402 < \
1403 (std::is_arithmetic_v<TypeT> || Foam::is_vectorspace_v<TypeT>) \
1404 > \
1405> \
1406auto Func \
1407( \
1408 TypeT const& u, \
1409 UList<Type> const& v \
1410) \
1411{ \
1412 typedef typename Expression::ListConstRefWrap<Type> E1; \
1413 typedef typename Expression::UniformListWrap<TypeT> E2; \
1414 return Func(E2(v.size(), u), E1(v)); \
1415}
1416
1417
1418#undef EXPRESSION_OPERATOR
1419#define EXPRESSION_OPERATOR(Op, OpFunc) \
1420template<typename E1, typename E2> \
1421class OpFunc \
1422: \
1423 public ListExpression \
1424 < \
1425 OpFunc<E1, E2> \
1426 > \
1427{ \
1428 /* cref if leaf, copy otherwise */ \
1429 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
1430 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
1431 \
1432public: \
1433 static constexpr bool is_leaf = false; \
1434 \
1435 /* Type to return for internal field */ \
1436 typedef typename E1::value_type value_type; \
1437 \
1438 OpFunc(const E1& u, const E2& v) \
1439 : \
1440 u_(u), v_(v) \
1441 { \
1442 assert(u_.size() == -1 || v_.size() == -1 || u_.size() == v_.size()); \
1443 } \
1444 auto operator[](const label i) const \
1445 { \
1446 return u_[i] Op v_[i]; \
1447 } \
1448 auto size() const noexcept { return Foam::max(u_.size(), v_.size()); } \
1449 \
1450 struct const_iterator \
1451 { \
1452 typedef typename E1::const_iterator E1Iter; \
1453 typedef typename E2::const_iterator E2Iter; \
1454 using difference_type = typename E1Iter::difference_type; \
1455 using value_type = typename E1Iter::value_type; \
1456 using pointer = typename E1Iter::pointer; \
1457 using reference = typename E1Iter::reference; \
1458 using iterator_category = typename E1Iter::iterator_category; \
1459 \
1460 E1Iter uIter_; \
1461 E2Iter vIter_; \
1462 \
1463 const_iterator(E1Iter uIter, E2Iter vIter) \
1464 : \
1465 uIter_(uIter), \
1466 vIter_(vIter) \
1467 {} \
1468 auto operator*() const \
1469 { \
1470 return *uIter_ Op *vIter_; \
1471 } \
1472 auto operator[](const difference_type i) const \
1473 { \
1474 return uIter_[i] Op vIter_[i]; \
1475 } \
1476 const_iterator& operator++() \
1477 { \
1478 ++uIter_; \
1479 ++vIter_; \
1480 return *this; \
1481 } \
1482 const_iterator operator++(int) \
1483 { \
1484 const_iterator old(*this); \
1485 ++uIter_; \
1486 ++vIter_; \
1487 return old; \
1488 } \
1489 const_iterator& operator--() \
1490 { \
1491 --uIter_; \
1492 --vIter_; \
1493 return *this; \
1494 } \
1495 const_iterator operator--(int) \
1496 { \
1497 const_iterator old(*this); \
1498 --uIter_; \
1499 --vIter_; \
1500 return old; \
1501 } \
1502 const_iterator operator+(const difference_type i) const \
1503 { \
1504 return const_iterator(uIter_+i, vIter_+i); \
1505 } \
1506 const_iterator operator-(const difference_type i) const \
1507 { \
1508 return const_iterator(uIter_-i, vIter_-i); \
1509 } \
1510 difference_type operator-(const const_iterator& it) const \
1511 { \
1512 return (uIter_ - it.uIter_); \
1513 } \
1514 bool operator==(const const_iterator& it) const \
1515 { \
1516 return uIter_ == it.uIter_ && vIter_ == it.vIter_; \
1517 } \
1518 bool operator!=(const const_iterator& it) const \
1519 { \
1520 return !operator==(it); \
1521 } \
1522 bool operator<(const const_iterator& it) const \
1523 { \
1524 return (uIter_ < it.uIter_); \
1525 } \
1526 bool operator<=(const const_iterator& it) const \
1527 { \
1528 return (uIter_ <= it.uIter_); \
1529 } \
1530 bool operator>(const const_iterator& it) const \
1531 { \
1532 return (uIter_ > it.uIter_); \
1533 } \
1534 bool operator>=(const const_iterator& it) const \
1535 { \
1536 return (uIter_ >= it.uIter_); \
1537 } \
1538 const_iterator& operator+=(const difference_type n) \
1539 { \
1540 uIter_ += n; \
1541 vIter_ += n; \
1542 return *this; \
1543 } \
1544 const_iterator& operator-=(const difference_type n) \
1545 { \
1546 uIter_ -= n; \
1547 vIter_ -= n; \
1548 return *this; \
1549 } \
1550 }; \
1551 const_iterator cbegin() const \
1552 { \
1553 return const_iterator(u_.cbegin(), v_.cbegin()); \
1554 } \
1555 const_iterator cend() const \
1556 { \
1557 return const_iterator(u_.cend(), v_.cend()); \
1558 } \
1559}; \
1560template<typename E1, typename E2> \
1561auto operator Op \
1562( \
1563 ListExpression \
1564 < \
1565 E1 \
1566 > const& u, \
1567 ListExpression \
1568 < \
1569 E2 \
1570 > const& v \
1571) \
1572{ \
1573 return OpFunc<E1, E2> \
1574 ( \
1575 static_cast<const E1&>(u), \
1576 static_cast<const E2&>(v) \
1577 ); \
1578} \
1579template<typename E1, class Type> \
1580auto operator Op \
1581( \
1582 ListExpression \
1583 < \
1584 E1 \
1585 > const& u, \
1586 UList<Type> const& v \
1587) \
1588{ \
1589 typedef typename Expression::ListConstRefWrap<Type> E2; \
1590 return operator Op(u, E2(v)); \
1591} \
1592template<typename E1, class Type> \
1593auto operator Op \
1594( \
1595 UList<Type> const& u, \
1596 ListExpression \
1597 < \
1598 E1 \
1599 > const& v \
1600) \
1601{ \
1602 typedef typename Expression::ListConstRefWrap<Type> E2; \
1603 return operator Op(E2(u), v); \
1604} \
1605template<class Type1, class Type2> \
1606auto operator Op(UList<Type1> const& u, UList<Type2> const& v) \
1607{ \
1608 typedef typename Expression::ListConstRefWrap<Type1> E1; \
1609 typedef typename Expression::ListConstRefWrap<Type2> E2; \
1610 return operator Op(E1(u), E2(v)); \
1611} \
1612template \
1613< \
1614 typename E1, \
1615 class Type, \
1616 class = std::enable_if_t \
1617 < \
1618 (std::is_arithmetic_v<Type> || Foam::is_vectorspace_v<Type>) \
1619 > \
1620> \
1621auto operator Op \
1622( \
1623 ListExpression \
1624 < \
1625 E1 \
1626 > const& u, \
1627 const Type& v \
1628) \
1629{ \
1630 typedef typename Expression::UniformListWrap<Type> E2; \
1631 return operator Op(u, E2(u.size(), v)); \
1632} \
1633template \
1634< \
1635 typename E1, \
1636 class Type, \
1637 class = std::enable_if_t \
1638 < \
1639 (std::is_arithmetic_v<Type> || Foam::is_vectorspace_v<Type>) \
1640 > \
1641> \
1642auto operator Op \
1643( \
1644 const Type& u, \
1645 ListExpression \
1646 < \
1647 E1 \
1648 > const& v \
1649) \
1650{ \
1651 typedef typename Expression::UniformListWrap<Type> E2; \
1652 return operator Op(E2(v.size(), u), v); \
1653} \
1654template \
1655< \
1656 class Type, \
1657 class TypeT = Type, \
1658 class = std::enable_if_t \
1659 < \
1660 (std::is_arithmetic_v<TypeT> || Foam::is_vectorspace_v<TypeT>) \
1661 > \
1662> \
1663auto operator Op \
1664( \
1665 UList<Type> const& u, \
1666 TypeT const& v \
1667) \
1668{ \
1669 typedef typename Expression::ListConstRefWrap<Type> E1; \
1670 typedef typename Expression::UniformListWrap<TypeT> E2; \
1671 return operator Op(E1(u), E2(u.size(), v)); \
1672} \
1673template \
1674< \
1675 class Type, \
1676 class TypeT = Type, \
1677 class = std::enable_if_t \
1678 < \
1679 (std::is_arithmetic_v<TypeT> || Foam::is_vectorspace_v<TypeT>) \
1680 > \
1681> \
1682auto operator Op \
1683( \
1684 TypeT const& u, \
1685 UList<Type> const& v \
1686) \
1687{ \
1688 typedef typename Expression::ListConstRefWrap<Type> E1; \
1689 typedef typename Expression::UniformListWrap<TypeT> E2; \
1690 return operator Op(E2(v.size(), u), E1(v)); \
1691}
1692
1693
1694// List functions
1695// ~~~~~~~~~~~~~~
1696// macro arguments:
1697// - 'sin' : name of new function (in Expression namespace)
1698// - '::sin' : per-element function to call
1699// - 'List_sin' : generated expression helper class
1700
1701EXPRESSION_FUNCTION1(sin, ::sin, List_sin)
1702EXPRESSION_FUNCTION1(cos, ::cos, List_cos)
1703EXPRESSION_FUNCTION1(tan, ::tan, List_tan)
1704EXPRESSION_FUNCTION1(sinh, ::sinh, List_sinh)
1705EXPRESSION_FUNCTION1(cosh, ::cosh, List_cosh)
1706EXPRESSION_FUNCTION1(tanh, ::tanh, List_tanh)
1712//EXPRESSION_FUNCTION1(-, -, List_negate)
1716
1717#undef EXPRESSION_FUNCTION1
1718
1721
1722#undef EXPRESSION_FUNCTION2
1723
1724//- List operators
1725EXPRESSION_OPERATOR(+, List_add)
1726EXPRESSION_OPERATOR(-, List_subtract)
1727EXPRESSION_OPERATOR(*, List_multiply)
1728EXPRESSION_OPERATOR(/, List_divide)
1729EXPRESSION_OPERATOR(&, List_dot)
1730
1731#undef EXPRESSION_OPERATOR
1732
1733//- Not possible: a *= b has to return a new type so it can never be in-place
1734//EXPRESSION_LIST_OPERATOR(+=, List_inplace_add)
1735//EXPRESSION_LIST_OPERATOR(-=, List_inplace_subtract)
1736//EXPRESSION_LIST_OPERATOR(*=, List_inplace_multiply)
1737//EXPRESSION_LIST_OPERATOR(/=, List_inplace_divide)
1738
1739
1740// Interpolation
1741// ~~~~~~~~~~~~~
1742
1743// E1 : expression to get value of element i
1744// E2 : expression to get value of element i
1745// E3 : expression to get interpolation weight
1746template<typename E1, typename E2, typename E3>
1747class List_interpolate
1751 List_interpolate<E1, E2, E3>
1754 //- Expression for cell values1
1755 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
1757 //- Expression for cell values2
1758 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_;
1759
1760 //- Expression for interpolation weight
1761 typename std::conditional<E3::is_leaf, const E3&, const E3>::type weight_;
1763
1764public:
1765
1766 // ! Store as copy (since holds reference)
1767 static constexpr bool is_leaf = false;
1768
1769 typedef typename E1::value_type value_type;
1770
1771 // construct from components
1772 List_interpolate(const E1& u, const E2& v, const E3& weight)
1773 :
1774 u_(u),
1775 v_(v),
1776 weight_(weight)
1779 value_type operator[](const label i) const
1780 {
1781 const auto ownVal = u_[i];
1782 const auto neiVal = v_[i];
1783 return weight_[i]*(ownVal-neiVal) + neiVal;
1784 }
1785 label size() const
1786 {
1787 return Foam::max(Foam::max(u_.size(), v_.size()), weight_.size());
1788 }
1789
1790 struct const_iterator
1791 {
1792 typedef typename E1::const_iterator E1Iter;
1793 typedef typename E2::const_iterator E2Iter;
1794 typedef typename E3::const_iterator E3Iter;
1795 using difference_type = typename E3Iter::difference_type;
1796 using value_type = typename E1Iter::value_type;
1797 using pointer = typename E1Iter::pointer;
1798 using reference = typename E1Iter::reference;
1799 using iterator_category = typename E3Iter::iterator_category;
1800 E1Iter uIter_;
1801 E2Iter vIter_;
1803
1804 const_iterator(E1Iter uIter, E2Iter vIter, E3Iter weightIter)
1805 :
1806 uIter_(uIter),
1807 vIter_(vIter),
1808 weightIter_(weightIter)
1809 {}
1810 value_type operator*() const
1811 {
1812 const auto ownVal = *uIter_;
1813 const auto neiVal = *vIter_;
1814 return *weightIter_*(ownVal-neiVal) + neiVal;
1815 }
1817 {
1818 const auto ownVal = uIter_[i];
1819 const auto neiVal = vIter_[i];
1820 return weightIter_[i]*(ownVal-neiVal) + neiVal;
1821 }
1823 {
1824 ++uIter_;
1826 ++weightIter_;
1827 return *this;
1828 }
1831 const_iterator old(*this);
1832 ++uIter_;
1833 ++vIter_;
1834 ++weightIter_;
1835 return old;
1836 }
1837 const_iterator& operator--()
1838 {
1839 --uIter_;
1840 --vIter_;
1841 --weightIter_;
1842 return *this;
1845 {
1846 const_iterator old(*this);
1847 --uIter_;
1849 --weightIter_;
1850 return old;
1852 const_iterator operator+(const label i) const
1856 const_iterator operator-(const label i) const
1861 {
1862 return (uIter_ - it.uIter_);
1863 }
1864 bool operator==(const const_iterator& it) const
1865 {
1866 return
1867 uIter_ == it.uIter_
1868 && vIter_ == it.vIter_
1869 && weightIter_ == it.weightIter_;
1870 }
1871 bool operator!=(const const_iterator& it) const
1872 {
1873 return !operator==(it);
1875 bool operator<(const const_iterator& it) const
1876 {
1877 return (uIter_ < it.uIter_);
1878 }
1879 bool operator<=(const const_iterator& it) const
1881 return (uIter_ <= it.uIter_);
1882 }
1883 bool operator>(const const_iterator& it) const
1884 {
1885 return (uIter_ > it.uIter_);
1886 }
1887 bool operator>=(const const_iterator& it) const
1888 {
1889 return (uIter_ >= it.uIter_);
1890 }
1892 {
1893 uIter_ += n;
1894 vIter_ += n;
1896 return *this;
1897 }
1899 {
1900 uIter_ -= n;
1901 vIter_ -= n;
1903 return *this;
1904 }
1905 };
1906 const_iterator cbegin() const
1907 {
1908 return const_iterator(u_.cbegin(), v_.cbegin(), weight_.cbegin());
1909 }
1911 {
1912 return const_iterator(u_.cend(), v_.cend(), weight_.cend());
1913 }
1915
1916
1917// Expressions on constants
1918// ~~~~~~~~~~~~~~~~~~~~~~~~
1919
1920//- Expression wrap of a List with a uniform value
1921template<class T>
1923:
1924 public ListExpression<UniformListWrap<T>>
1925{
1926private:
1927
1928 const label size_;
1930 const T val_;
1931
1932
1933public:
1934
1935 static constexpr bool is_leaf = false;
1936
1937 typedef T value_type;
1938
1939 // construct from components
1940 UniformListWrap(const label size, const T val)
1942 size_(size),
1943 val_(val)
1944 {}
1946 // construct from components
1947 UniformListWrap(const label size, const dimensioned<T>& val)
1948 :
1949 size_(size),
1950 val_(val.value())
1951 {}
1952
1953 T operator[](const label i) const
1954 {
1955 return val_;
1957 auto size() const noexcept
1958 {
1959 return size_;
1960 }
1961
1962 struct const_iterator
1963 {
1964 // Minimalistic const_iter implementation
1965 using difference_type = label;
1966 using value_type = const T;
1967 using pointer = const T*;
1968 using reference = const T&;
1969 using iterator_category = std::random_access_iterator_tag;
1970
1972
1973 const T val_;
1974
1975 const_iterator(const difference_type count, const T val)
1976 :
1977 count_(count),
1978 val_(val)
1979 {}
1980 value_type operator*() const
1981 {
1982 return val_;
1983 }
1985 {
1986 return val_;
1987 }
1989 {
1990 count_++;
1991 return *this;
1992 }
1994 {
1995 const_iterator old(*this);
1996 ++count_;
1997 return old;
1998 }
2001 count_--;
2002 return *this;
2003 }
2005 {
2006 const_iterator old(*this);
2008 return old;
2009 }
2011 {
2012 return const_iterator(count_+i, val_);
2015 {
2016 return const_iterator(count_-i, val_);
2019 {
2020 return (count_ - it.count_);
2021 }
2022 bool operator==(const const_iterator& it) const
2023 {
2024 return val_ == it.val_ && count_ == it.count_;
2026 bool operator!=(const const_iterator& it) const
2028 return !operator==(it);
2030 bool operator<(const const_iterator& it) const
2032 return (count_ < it.count_);
2034 bool operator<=(const const_iterator& it) const
2036 return (count_ <= it.count_);
2037 }
2038 bool operator>(const const_iterator& it) const
2039 {
2040 return (count_ > it.count_);
2041 }
2042 bool operator>=(const const_iterator& it) const
2043 {
2044 return (count_ >= it.count_);
2045 }
2047 {
2049 return *this;
2050 }
2052 {
2054 return *this;
2055 }
2056 };
2057 auto cbegin() const
2058 {
2060 }
2061 auto cend() const
2062 {
2063 return const_iterator(size_, val_);
2065};
2066
2067//- Expression wrap of a uniform value without a List size
2068template<class T>
2069class UniformListWrap2
2071 public ListExpression<UniformListWrap2<T>>
2072{
2073private:
2075 const T val_;
2076
2077
2078public:
2079
2080 static constexpr bool is_leaf = false;
2081
2082 typedef T value_type;
2083
2084 // construct from components
2085 UniformListWrap2(const T val)
2087 val_(val)
2088 {}
2089
2090 // construct from components
2092 :
2093 val_(val.value())
2095
2096 T operator[](const label i) const
2097 {
2098 return val_;
2099 }
2100 auto size() const noexcept
2101 {
2102 // Force error if used. Requires lower levels to use max() and hope
2103 // that one of the arguments has size.
2104 return -1;
2105 }
2107 struct const_iterator
2108 {
2109 // Minimalistic const_iter implementation
2110 using difference_type = label;
2111 using value_type = const T;
2112 using pointer = const T*;
2113 using reference = const T&;
2114 using iterator_category = std::random_access_iterator_tag;
2115
2116 const T val_;
2118 const_iterator(const T val)
2119 :
2120 val_(val)
2122 value_type operator*() const
2123 {
2124 return val_;
2125 }
2127 {
2128 return val_;
2129 }
2132 return *this;
2133 }
2135 {
2136 const_iterator old(*this);
2137 return old;
2138 }
2140 {
2141 return *this;
2145 const_iterator old(*this);
2146 return old;
2149 {
2150 return const_iterator(val_);
2151 }
2154 return const_iterator(val_);
2155 }
2157 {
2158 return 0;
2159 }
2160 bool operator==(const const_iterator& it) const
2161 {
2162 return val_ == it.val_;
2163 }
2164 bool operator!=(const const_iterator& it) const
2165 {
2166 return !operator==(it);
2167 }
2168 bool operator<(const const_iterator& it) const
2170 return false;
2171 }
2172 bool operator<=(const const_iterator& it) const
2174 return false;
2176 bool operator>(const const_iterator& it) const
2177 {
2178 return false;
2179 }
2180 bool operator>=(const const_iterator& it) const
2181 {
2182 return false;
2183 }
2185 {
2186 return *this;
2187 }
2189 {
2190 return *this;
2191 }
2193 auto cbegin() const
2194 {
2195 return const_iterator(val_);
2197 auto cend() const
2198 {
2199 return const_iterator(val_);
2200 }
2202
2203
2204//- Expression wrap of multiple lists (e.g. FieldField)
2205template <class V>
2207:
2208 public ListExpression<ListsConstRefWrap<V>>
2209{
2211 List<size_t> offsets_;
2212 size_t total_size_ = 0;
2213
2214 void init()
2215 {
2216 offsets_.resize_nocopy(data_.size());
2217 total_size_ = 0;
2218 for (label i = 0; i < data_.size(); ++i)
2219 {
2220 offsets_[i] = total_size_;
2221 total_size_ += data_[i]->size();
2223 }
2224
2225public:
2226 static constexpr bool is_leaf = false; //true;
2227
2228 using value_type = typename V::value_type; //T;
2231 ListsConstRefWrap() = delete;
2232
2235 data_(d)
2236 {
2237 init();
2240 :
2241 data_(d)
2243 init();
2244 }
2245 template<class Container>
2246 ListsConstRefWrap(const Container& ds)
2247 {
2248 data_.resize_nocopy(ds.size());
2249 forAll(ds, i)
2251 const V& vals = static_cast<const V&>(ds[i]);
2252 data_[i] = &vals;
2253 }
2254 init();
2256 template<class Container>
2257 ListsConstRefWrap(const Container& ds, const labelUList& elems)
2258 {
2259 data_.resize_nocopy(elems.size());
2260 forAll(ds, i)
2261 {
2262 const V& vals = static_cast<const V&>(ds[elems[i]]);
2263 data_[i] = &vals;
2264 }
2265 init();
2266 }
2267
2268 void push_back(const V* vec)
2269 {
2270 data_.push_back(vec);
2271 offsets_.push_back(total_size_);
2272 total_size_ += vec->size();
2273 }
2274
2275 value_type operator[](label i) const
2276 {
2277 const label vec_index =
2278 std::upper_bound
2279 (
2280 offsets_.begin(),
2281 offsets_.end(),
2282 i
2283 )
2284 - offsets_.begin() - 1;
2285 const label elem_index = i - offsets_[vec_index];
2286 return (*data_[vec_index])[elem_index];
2287 }
2288 label size() const { return total_size_; }
2289
2291 typedef value_type* pointer;
2294 typedef const value_type& const_reference;
2295 typedef label difference_type;
2296
2298 {
2299 using iterator_category = std::random_access_iterator_tag;
2304
2305 const this_type& base_;
2306 label index_;
2307
2308 const_iterator(const this_type& base, const label index)
2309 :
2310 base_(base),
2311 index_(index)
2312 {}
2314 :
2315 base_(it.base_),
2316 index_(it.index_)
2317 {}
2318 const_iterator() = delete; //: base_(0) {}
2319 const_iterator& operator=(const_iterator& it) = default;
2320
2321 // Indexing operators
2322
2323 value_type operator*() const
2324 {
2325 return base_[index_];
2326 }
2327 //value_type operator->() const
2328 //{
2329 // return *base_;
2330 //}
2333 return base_[index_];
2334 }
2335
2336 // Increment/Decrement
2337
2340 ++index_;
2341 return *this;
2342 }
2344 {
2345 const_iterator old(*this);
2346 ++index_;
2347 return old;
2348 }
2350 {
2351 --index_;
2352 return *this;
2353 }
2356 const_iterator old(*this);
2358 return old;
2360
2361 // Arithmetic operators
2362
2368 {
2373 return (index_ - it.index_);
2374 }
2375
2376 // Comparison operators
2378 bool operator==(const const_iterator& it) const
2379 {
2380 return (index_ == it.index_);
2381 }
2382 bool operator!=(const const_iterator& it) const
2384 return (index_ != it.index_);
2385 }
2386 bool operator<(const const_iterator& it) const
2388 return (index_ < it.index_);
2389 }
2390 bool operator<=(const const_iterator& it) const
2391 {
2392 return (index_ <= it.index_);
2393 }
2394 bool operator>(const const_iterator& it) const
2396 return (index_ > it.index_);
2397 }
2398 bool operator>=(const const_iterator& it) const
2399 {
2400 return (index_ >= it.index_);
2401 }
2403 // Compound assignment
2404
2406 {
2408 return *this;
2409 }
2411 {
2412 index_ -= n;
2413 return *this;
2414 }
2415 };
2416 auto cbegin() const
2417 {
2418 return const_iterator(*this, 0);
2419 }
2420 auto cend() const
2421 {
2422 return const_iterator(*this, this->size());
2423 }
2424};
2425
2426
2427//- Expression wrap of multiple lists
2428template <class V>
2429class ListsRefWrap
2430:
2431 public ListExpression<ListsRefWrap<V>>
2432{
2433 List<V*> data_;
2434 List<size_t> offsets_;
2435 size_t total_size_ = 0;
2436
2437 void init()
2438 {
2439 offsets_.resize_nocopy(data_.size());
2440 total_size_ = 0;
2441 for (label i = 0; i < data_.size(); ++i)
2443 offsets_[i] = total_size_;
2444 total_size_ += data_[i]->size();
2445 }
2447 labelPair whichVecElem(const label i) const
2448 {
2449 const label vec_index =
2450 std::upper_bound
2451 (
2452 offsets_.begin(),
2453 offsets_.end(),
2455 )
2456 - offsets_.begin() - 1;
2457 const label elem_index = i - offsets_[vec_index];
2458 return labelPair(vec_index, elem_index);
2459 }
2460
2461public:
2462 static constexpr bool is_leaf = false; //true;
2463
2464 using value_type = typename V::value_type; //T;
2465 typedef ListsRefWrap<V> this_type;
2466
2467 ListsRefWrap() = delete;
2468
2470 :
2471 data_(d)
2472 {
2473 init();
2476 :
2477 data_(d)
2478 {
2479 init();
2481 template<class Container>
2482 ListsRefWrap(Container& ds)
2483 {
2484 data_.resize_nocopy(ds.size());
2485 const label n = ds.size();
2486 for (label i = 0; i < n; ++i)
2487 {
2488 V& vals = static_cast<V&>(ds[i]);
2489 data_[i] = &vals;
2490 }
2491 init();
2492 }
2493 // Special constructor that only adds lists of correct type.
2494 // Used to work with pointFields.
2495 template<class Container, class ElemOp>
2496 ListsRefWrap(Container& ds, const ElemOp& insertOp)
2497 {
2498 data_.resize_nocopy(ds.size());
2499 const label n = ds.size();
2500 label dataIndex = 0;
2501 for (label i = 0; i < n; ++i)
2502 {
2503 insertOp(data_, dataIndex, ds[i]);
2504 }
2505 data_.setSize(dataIndex);
2506 init();
2507 }
2508 // template<class Container>
2509 // ListsRefWrap(Container& ds, const labelUList& elems)
2510 // {
2511 // data_.resize_nocopy(elems.size());
2512 // const label n = ds.size();
2513 // for (label i = 0; i < n; ++i)
2514 // {
2515 // V& vals = static_cast<V&>(ds[i]);
2516 // data_[i] = &vals;
2517 // }
2518 // init();
2519 // }
2520
2521 void push_back(V* vec)
2522 {
2523 data_.push_back(vec);
2524 offsets_.push_back(total_size_);
2525 total_size_ += vec->size();
2526 }
2527
2528 //- Dummy resizing so we can pass *this to
2529 //- ListExpression::evaluate. Maybe do resizing externally?
2530 void resize_nocopy(const label)
2532 //- Assignment
2533 template<typename E, class Container >
2534 void evaluate(ListsRefWrap<E>& exprWarp, const Container & ds)
2536 const label loop_len = this->size();
2537#ifdef _OPENMP
2538 _Pragma("omp target teams distribute parallel for if(loop_len > 1000)")
2539#endif
2540 for (label i = 0; i < loop_len; ++i)
2542 auto src = (*this).cbegin() + i;
2543 const auto ve(whichVecElem(i));
2544 exprWarp(ds[ve.first()],ve.second()) = *src;
2545 }
2546 }
2547
2548 template<typename E>
2549 void operator=(const ListExpression<E>& expr)
2550 {
2551 expr.evaluate(*this);
2552 }
2553
2554 value_type operator[](const label i) const
2555 {
2556 const auto ve(whichVecElem(i));
2557 return (*data_[ve.first()])[ve.second()];
2558 }
2559 value_type& operator[](const label i)
2560 {
2561 const auto ve(whichVecElem(i));
2562 auto& elems = *data_[ve.first()];
2563 return elems[ve.second()];
2564 }
2565
2566 value_type& operator()(const label i, const label j)
2567 {
2568 auto& elems = *data_[i];
2569 return elems[j];
2570 }
2571
2572 label size() const { return total_size_; }
2573
2574
2575 typedef value_type* pointer;
2576 typedef value_type& reference;
2577 typedef const value_type* const_pointer;
2578 typedef const value_type& const_reference;
2579 typedef label difference_type;
2580
2581 struct const_iterator
2582 {
2583 using iterator_category = std::random_access_iterator_tag;
2588
2589 const this_type& base_;
2590 label index_;
2591
2592 const_iterator(const this_type& base, const label index)
2593 :
2594 base_(base),
2595 index_(index)
2596 {}
2599 base_(it.base_),
2600 index_(it.index_)
2601 {}
2603 :
2605 index_(it.index_)
2606 {}
2607 const_iterator() = delete; //: base_(0) {}
2608 const_iterator& operator=(const_iterator& it) = default;
2609
2610 // Indexing operators
2611
2612 value_type operator*() const
2613 {
2614 return base_[index_];
2615 }
2616 //value_type operator->() const
2617 //{
2618 // return *base_;
2619 //}
2621 {
2622 return base_[index_+i];
2623 }
2625 // Increment/Decrement
2626
2628 {
2630 return *this;
2631 }
2633 {
2634 const_iterator old(*this);
2635 ++index_;
2636 return old;
2637 }
2639 {
2640 --index_;
2641 return *this;
2644 {
2645 const_iterator old(*this);
2647 return old;
2650 // Arithmetic operators
2658 return const_iterator(base_, index_-i);
2661 {
2662 return (index_ - it.index_);
2663 }
2664
2665 // Comparison operators
2666
2667 bool operator==(const const_iterator& it) const
2668 {
2669 return (index_ == it.index_);
2670 }
2671 bool operator!=(const const_iterator& it) const
2673 return (index_ != it.index_);
2674 }
2675 bool operator<(const const_iterator& it) const
2676 {
2677 return (index_ < it.index_);
2679 bool operator<=(const const_iterator& it) const
2680 {
2681 return (index_ <= it.index_);
2683 bool operator>(const const_iterator& it) const
2684 {
2685 return (index_ > it.index_);
2686 }
2687 bool operator>=(const const_iterator& it) const
2688 {
2689 return (index_ >= it.index_);
2691
2692 // Compound assignment
2693
2695 {
2696 index_ += n;
2697 return *this;
2698 }
2700 {
2701 index_ -= n;
2702 return *this;
2703 }
2704 };
2705 auto cbegin() const
2706 {
2707 return const_iterator(*this, 0);
2709 auto cend() const
2710 {
2711 return const_iterator(*this, this->size());
2712 }
2714 struct iterator
2715 {
2716 using iterator_category = std::random_access_iterator_tag;
2721
2723 label index_;
2724
2725 iterator(this_type& base, const label index)
2727 base_(base),
2728 index_(index)
2729 {}
2730 iterator(const iterator& it) = default;
2731 iterator() = delete;
2732 iterator& operator=(const iterator& it)
2733 {
2734 base_ = it.base_;
2735 index_ = it.index_;
2736 return *this;
2738
2739 // Indexing operators
2740
2742 {
2743 return base_[index_];
2744 }
2746 {
2747 return base_[index_];
2748 }
2750 {
2751 return base_[index_];
2752 }
2754 {
2755 return base_[index_];
2756 }
2758 {
2759 return base_[index_+i];
2760 }
2762 {
2763 return base_[index_+i];
2765
2766 // Increment/Decrement
2767
2770 ++index_;
2771 return *this;
2772 }
2773 iterator operator++(int)
2774 {
2775 iterator old(*this);
2776 ++index_;
2777 return old;
2778 }
2780 {
2781 --index_;
2782 return *this;
2783 }
2785 {
2786 iterator old(*this);
2788 return old;
2791 // Arithmetic operators
2794 {
2796 }
2797 iterator operator-(const difference_type i) const
2798 {
2799 return iterator(base_, index_-i);
2803 return (index_ - it.index_);
2804 }
2805
2806 // Comparison operators
2807
2808 bool operator==(const iterator& it) const
2809 {
2810 return (index_ == it.index_);
2812 bool operator!=(const iterator& it) const
2813 {
2814 return (index_ != it.index_);
2816 bool operator<(const iterator& it) const
2817 {
2818 return (index_ < it.index_);
2820 bool operator<=(const iterator& it) const
2821 {
2822 return (index_ <= it.index_);
2824 bool operator>(const iterator& it) const
2825 {
2826 return (index_ > it.index_);
2828 bool operator>=(const iterator& it) const
2829 {
2830 return (index_ >= it.index_);
2832
2833 // Compound assignment
2834
2836 {
2837 index_ += n;
2838 return *this;
2839 }
2841 {
2842 index_ -= n;
2843 return *this;
2844 }
2845 };
2846 auto begin()
2847 {
2848 auto& this_vals = *this;
2849 return iterator(this_vals, 0);
2850 }
2851 auto end()
2852 {
2853 auto& this_vals = *this;
2854 return iterator(this_vals, this->size());
2855 }
2856};
2857
2858
2859// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
2860
2861} // End namespace Expression
2862} // End namespace Foam
2864// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
2865
2866#endif
2868// ************************************************************************* //
#define EXPRESSION_OPERATOR(BaseClass, Op, BaseOp, OpFunc)
#define EXPRESSION_FUNCTION2(BaseClass, Func, BaseFunc, OpFunc)
#define EXPRESSION_FUNCTION1(BaseClass, Func, BaseFunc, OpFunc)
label n
Expression wrap of indirection.
IndirectConstWrap(const E1 &values, const labelUList &addr)
value_type operator[](const label i) const
Expression wrap of const reference to UList.
value_type operator[](const label i) const
ListConstRefWrap(const UList< T > &elems)
Expression wrap of const tmp to List.
ListConstTmpWrap(const tmp< T > &elems)
value_type operator[](const label i) const
Expression templates for List.
auto operator[](const label i) const
Container & evaluate(Container &lst) const
Helper: assign to passed in list.
static constexpr bool is_leaf
Container & fill(Container &lst) const
Helper: assign to passed in list.
Expression wrap of non-const reference to List.
ListRefWrap(const label size, List< T > &elems)
Construct from List and expected size. This is to enforce that our size() member function returns the...
ListRefWrap(ListRefWrap< T > &&elems)
Move construct.
void operator=(const ListExpression< E > &expr)
Assignment.
value_type & operator[](const label i)
value_type operator[](const label i) const
List< value_type >::const_iterator const_iterator
ListRefWrap(ListRefWrap< T > &w)
Copy construct.
ListRefWrap(List< T > &elems, const ListExpression< E > &expr)
Expression wrap of tmp to List.
Field< value_type >::const_iterator const_iterator
auto size() const noexcept
ListTmpWrap(tmp< T > &elems, const ListExpression< E > &expr)
void operator=(const ListExpression< E > &expr)
Assignment.
value_type operator[](const label i) const
ListTmpWrap(const tmp< T > &elems)
List< Field< value_type > >::iterator iterator
const auto & data() const
static constexpr bool is_leaf
auto size() const noexcept
ListWrap(const ListExpression< E > &expr)
ListWrap(const ListWrap< T > &elems)
Copy construct.
ListWrap(const UList< T > &elems)
value_type & operator[](const label i)
value_type operator[](const label i) const
List< T >::const_iterator const_iterator
List< T >::iterator iterator
ListWrap(ListWrap< T > &&elems)
Move construct.
ListWrap(std::initializer_list< T > elems)
Construct from initializer list.
List_add(const E1 &u, const E2 &v)
List_divide(const E1 &u, const E2 &v)
List_dot(const E1 &u, const E2 &v)
List_interpolate(const E1 &u, const E2 &v, const E3 &weight)
value_type operator[](const label i) const
static constexpr bool is_leaf
List_max(const E1 &u, const E2 &v)
List_min(const E1 &u, const E2 &v)
List_multiply(const E1 &u, const E2 &v)
auto operator[](const label i) const
const_iterator cbegin() const
const_iterator cend() const
List_subtract(const E1 &u, const E2 &v)
Expression wrap of multiple lists (e.g. FieldField).
ListsConstRefWrap(const Container &ds, const labelUList &elems)
ListsConstRefWrap(List< const V * > &&d)
value_type operator[](label i) const
ListsConstRefWrap(const UList< const V * > &d)
Expression wrap of multiple lists.
ListsRefWrap(Container &ds, const ElemOp &insertOp)
void evaluate(ListsRefWrap< E > &exprWarp, const Container &ds)
Assignment.
typename V::value_type value_type
static constexpr bool is_leaf
void resize_nocopy(const label)
Dummy resizing so we can pass *this to ListExpression::evaluate. Maybe do resizing externally?
void operator=(const ListExpression< E > &expr)
value_type & operator()(const label i, const label j)
value_type & operator[](const label i)
value_type operator[](const label i) const
Expression wrap of a uniform value without a List size.
UniformListWrap2(const dimensioned< T > &val)
Expression wrap of a List with a uniform value.
T operator[](const label i) const
UniformListWrap(const label size, const dimensioned< T > &val)
UniformListWrap(const label size, const T val)
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition ListI.H:171
void push_back(const T &val)
Append an element at the end of the list.
Definition ListI.H:221
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
const T * const_iterator
Random access iterator for traversing a UList.
Definition UList.H:183
T * iterator
Random access iterator for traversing a UList.
Definition UList.H:178
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Generic dimensioned Type class.
A class for managing temporary objects.
Definition tmp.H:75
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)
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)
fvm_subtract< E1, E2 > operator-(fvMatrixExpression< E1, typename E1::DiagExpr, typename E1::UpperExpr, typename E1::LowerExpr, typename E1::FaceFluxExpr, typename E1::SourceExpr > const &u, fvMatrixExpression< E2, typename E2::DiagExpr, typename E2::UpperExpr, typename E2::LowerExpr, typename E2::FaceFluxExpr, typename E2::SourceExpr > const &v)
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.
Pair< label > labelPair
A pair of labels.
Definition Pair.H:54
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)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar pow3(const dimensionedScalar &ds)
dimensionedScalar sqrt(const dimensionedScalar &ds)
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)
const direction noexcept
Definition scalarImpl.H:265
UList< label > labelUList
A UList of labels.
Definition UList.H:75
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)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
E1::const_iterator ConstIter
Iterator definition for E1.
bool operator==(const const_iterator &it) const
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
std::random_access_iterator_tag iterator_category
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
const_iterator(ConstIter begin, typename labelUList::const_iterator addrIter)
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
typename ConstIterTraits::value_type value_type
bool operator==(const const_iterator &it) const
typename ConstIterTraits::reference reference
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
std::random_access_iterator_tag iterator_category
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
typename ConstIterTraits::difference_type difference_type
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
std::iterator_traits< ConstIter > ConstIterTraits
Define our own iterator so we can refer to it. 'normal', e.g. double*.
typename ConstIterTraits::value_type value_type
bool operator==(const const_iterator &it) const
typename ConstIterTraits::reference reference
bool operator<(const const_iterator &it) const
typename ConstIterTraits::iterator_category iterator_category
const_iterator & operator-=(const difference_type n)
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
typename ConstIterTraits::difference_type difference_type
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
std::iterator_traits< ConstIter > ConstIterTraits
typename E3Iter::iterator_category iterator_category
const_iterator operator+(const label i) const
bool operator==(const const_iterator &it) const
const_iterator(E1Iter uIter, E2Iter vIter, E3Iter weightIter)
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
typename E3Iter::difference_type difference_type
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
const_iterator & operator+=(const difference_type n)
value_type operator[](const difference_type i) const
const_iterator operator-(const label i) const
difference_type operator-(const const_iterator &it) const
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
bool operator==(const const_iterator &it) const
typename ConstIter::value_type value_type
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
typename ConstIter::difference_type difference_type
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
typename ConstIter::iterator_category iterator_category
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
bool operator==(const const_iterator &it) const
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
const_iterator & operator=(const_iterator &it)=default
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
const_iterator(const this_type &base, const label index)
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
bool operator==(const const_iterator &it) const
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
const_iterator & operator=(const_iterator &it)=default
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
const_iterator(const this_type &base, const label index)
std::random_access_iterator_tag iterator_category
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
iterator operator-(const difference_type i) const
bool operator>(const iterator &it) const
iterator & operator-=(const difference_type n)
iterator & operator+=(const difference_type n)
difference_type operator-(const iterator &it) const
bool operator==(const iterator &it) const
std::random_access_iterator_tag iterator_category
iterator operator+(const difference_type i) const
this_type::difference_type difference_type
iterator(const iterator &it)=default
bool operator<=(const iterator &it) const
value_type & operator[](const difference_type i)
value_type operator[](const difference_type i) const
bool operator!=(const iterator &it) const
iterator & operator=(const iterator &it)
bool operator<(const iterator &it) const
bool operator>=(const iterator &it) const
iterator(this_type &base, const label index)
bool operator==(const const_iterator &it) const
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
std::random_access_iterator_tag iterator_category
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
bool operator==(const const_iterator &it) const
bool operator<(const const_iterator &it) const
const_iterator & operator-=(const difference_type n)
bool operator>=(const const_iterator &it) const
bool operator<=(const const_iterator &it) const
std::random_access_iterator_tag iterator_category
const_iterator & operator+=(const difference_type n)
const_iterator operator+(const difference_type i) const
value_type operator[](const difference_type i) const
const_iterator operator-(const difference_type i) const
difference_type operator-(const const_iterator &it) const
bool operator>(const const_iterator &it) const
bool operator!=(const const_iterator &it) const
const_iterator(const difference_type count, const T val)