Loading...
Searching...
No Matches
fvMatrixExpression.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) 2025 M. Janssens
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26InNamespace
27 Foam::Expression
28
29Description
30 Expression templates for fvMatrix.
31
32 TBD:
33 - useImplicit_ etc.
34 - lduMatrix::lowerCSR ?
35
36SourceFiles
37 fvMatrixExpression.H
38
39\*---------------------------------------------------------------------------*/
40
41#ifndef Foam_fvMatrixExpression_H
42#define Foam_fvMatrixExpression_H
43
44#include "ListExpression.H"
46//#include <boost/core/demangle.hpp>
47//#include <typeinfo>
48//#include <iostream>
49
50// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51
52namespace Foam
53{
54namespace Expression
55{
56
57/*---------------------------------------------------------------------------*\
58 Class fvMatrixExpression Declaration
59\*---------------------------------------------------------------------------*/
60
61//- Expression of fvMatrix
62//
63// Bit different:
64// - immediately stores state (hasDiag, hasUpper etc.)
65// - delays execution of building coefficients
66// - big problem: individual components can be built differently so
67// different template argument ... Needs to be templated on all outputs
68// separately!
69template
70<
71 typename E,
72 typename DiagExpr,
73 typename UpperExpr,
74 typename LowerExpr,
75 typename FaceFluxExpr,
76 typename SourceExpr
79{
80protected:
82 const bool hasDiag_;
83 const bool hasUpper_;
84 const bool hasLower_;
87
88public:
89 static constexpr bool is_leaf = false;
90
91 // Constructors
94 (
95 const bool hasDiag,
96 const bool hasUpper,
97 const bool hasLower,
98 const bool hasFaceFluxCorrection,
100 )
101 :
107 {
108 //Pout<< "fvMatrixExpression :" << nl
109 // << " E : "
110 // << boost::core::demangle(typeid(E).name())
111 // << nl
112 // << " DiagExpr : "
113 // << boost::core::demangle(typeid(DiagExpr).name())
114 // << endl;
115 }
116
117
118 // lduMatrix part
120 DiagExpr diag() const
121 {
122 return static_cast<const E&>(*this).diag();
123 }
125 DiagExpr diag()
126 {
127 return static_cast<E&>(*this).diag();
128 }
130 UpperExpr upper() const
131 {
132 return static_cast<const E&>(*this).upper();
133 }
135 UpperExpr upper()
136 {
137 return static_cast<E&>(*this).upper();
138 }
140 LowerExpr lower() const
141 {
142 return static_cast<const E&>(*this).lower();
143 }
145 LowerExpr lower()
146 {
147 return static_cast<E&>(*this).lower();
148 }
150 bool hasDiag() const
151 {
152 return hasDiag_;
154 bool hasUpper() const
155 {
156 return hasUpper_;
158 bool hasLower() const
159 {
160 return hasLower_;
162 bool diagonal() const
163 {
164 return (hasDiag() && !hasLower() && !hasUpper());
166 bool symmetric() const
167 {
168 return (hasDiag() && !hasLower() && hasUpper());
170 bool asymmetric() const
171 {
172 return (hasDiag() && hasLower() && hasUpper());
174 bool hasFaceFluxCorrection() const
175 {
177 }
178
179
180 // fvMatrix
182 SourceExpr source()
183 {
184 return static_cast<E&>(*this).source();
185 }
187 SourceExpr source() const
188 {
189 return static_cast<const E&>(*this).source();
190 }
192 UpperExpr internalCoeffs(const label i)
193 {
194 return static_cast<E&>(*this).internalCoeffs(i);
195 }
197 UpperExpr internalCoeffs(const label i) const
198 {
199 return static_cast<const E&>(*this).internalCoeffs(i);
200 }
202 UpperExpr boundaryCoeffs(const label i)
203 {
204 return static_cast<E&>(*this).boundaryCoeffs(i);
205 }
207 UpperExpr boundaryCoeffs(const label i) const
208 {
209 return static_cast<const E&>(*this).boundaryCoeffs(i);
210 }
212 FaceFluxExpr faceFluxCorrection() const
213 {
214 return static_cast<const E&>(*this).faceFluxCorrection();
215 }
217 FaceFluxExpr faceFluxCorrection()
218 {
219 return static_cast<E&>(*this).faceFluxCorrection();
220 }
222 const dimensionSet& dimensions() const noexcept
223 {
224 return dimensions_;
225 }
226
227
228 // Other
229
230 //- Helper to evaluate (=construct) an fvMatrix
231 template<class Matrix>
232 Matrix& evaluate(Matrix& m) const
234 if (hasDiag())
235 {
236 // Assign to diag. Also sets hasDiag.
237 diag().evaluate(m.diag());
238 }
239 if (hasUpper())
240 {
241 upper().evaluate(m.upper());
242 }
243 if (hasLower())
244 {
245 lower().evaluate(m.lower());
246 }
248 {
249 faceFluxCorrection().evaluate(*m.faceFluxCorrectionPtr());
250 }
251
252 // Do boundary
253 auto& intCoeffs = m.internalCoeffs();
254 auto& bouCoeffs = m.boundaryCoeffs();
255 const label n = intCoeffs.size();
256 for (label i = 0; i < n; ++i)
257 {
258 if (intCoeffs.set(i) && intCoeffs[i].size())
259 {
260 const auto intExpr = internalCoeffs(i);
261 intExpr.evaluate(intCoeffs[i]);
262 }
263 if (bouCoeffs.set(i) && bouCoeffs[i].size())
264 {
265 const auto bouExpr = boundaryCoeffs(i);
266 bouExpr.evaluate(bouCoeffs[i]);
267 }
268 }
269
270 const_cast<dimensionSet&>(m.dimensions()) = dimensions();
271
272 return m;
273 }
274};
275
276
277/*---------------------------------------------------------------------------*\
278 Class fvMatrixRefWrap Declaration
279\*---------------------------------------------------------------------------*/
280
281//- Expression wrap of non-const reference to fvMatrix
282template<class Matrix>
283class fvMatrixRefWrap
284:
285 public fvMatrixExpression
287 fvMatrixRefWrap<Matrix>,
288 ListRefWrap<typename Matrix::psiFieldType::value_type>, // diag
289 ListRefWrap<typename Matrix::psiFieldType::value_type>, // upper
290 ListRefWrap<typename Matrix::psiFieldType::value_type>, // lower
291 //ListRefWrap<typename Matrix::psiFieldType::value_type>, // faceflux
292 GeometricFieldRefWrap<typename Matrix::faceFluxFieldType>,
293 ListRefWrap<typename Matrix::psiFieldType::value_type> // source
294 >
295{
296public:
297
298 static constexpr bool is_leaf = false; //true;
299
300 //- The fvMatrix type
302
303 //- Type to return for internal field
304 typedef typename Matrix::psiFieldType::value_type value_type;
305
306 //- Type to return for containers
310 //typedef ListRefWrap<value_type> FaceFluxExpr;
312 <
313 typename Matrix::faceFluxFieldType
314 > FaceFluxExpr;
318private:
319
320 this_type& elems_;
321
322
323public:
325 //- Copy construct
327 :
329 <
331 DiagExpr,
332 UpperExpr,
333 LowerExpr,
336 >
338 elems.hasDiag(),
339 elems.hasUpper(),
340 elems.hasLower(),
341 elems.hasFaceFluxCorrection(),
342 elems.dimensions()
343 ),
344 elems_(elems)
345 {}
346
347 //- Move construct
349 :
351 <
353 DiagExpr,
354 UpperExpr,
355 LowerExpr,
358 >
359 (
360 elems.hasDiag(),
361 elems.hasUpper(),
362 elems.hasLower(),
363 elems.hasFaceFluxCorrection(),
364 elems.dimensions()
365 ),
366 elems_(elems)
367 {}
368
369 // Construct from Matrix, forcing its evaluation.
370 template<typename E>
372 (
373 this_type& elems,
375 <
376 E,
377 typename E::DiagExpr,
378 typename E::UpperExpr,
379 typename E::LowerExpr,
380 typename E::FaceFluxExpr,
381 typename E::SourceExpr
382 >& expr
383 )
386 <
388 DiagExpr,
389 UpperExpr,
390 LowerExpr,
393 >
394 (
395 expr.hasDiag(),
396 expr.hasUpper(),
397 expr.hasLower(),
398 elems.hasFaceFluxCorrection(),
399 elems.dimensions()
400 ),
401 elems_(elems)
402 {
403 expr.evaluate(elems_);
404 }
405
406 //- Assignment
407 template<typename E>
408 void operator=
409 (
411 <
412 E,
413 typename E::DiagExpr,
414 typename E::UpperExpr,
415 typename E::LowerExpr,
416 typename E::FaceFluxExpr,
417 typename E::SourceExpr
418 >& expr
419 )
420 {
421 expr.evaluate(elems_);
422 }
424 //- Evaluate and return as GeoField. Rename to evaluate to make it clear
425 //- it takes time? Or leave as indexing for convenience?
426 template<typename E>
428 (
430 <
431 E,
432 typename E::DiagExpr,
433 typename E::UpperExpr,
434 typename E::LowerExpr,
435 typename E::FaceFluxExpr,
436 typename E::SourceExpr
437 >& expr
438 )
439 {
440 return expr.evaluate(elems_);
441 }
442
443
444 // lduMatrix part
445
446 DiagExpr diag() const
447 {
448 return elems_.diag();
449 }
450
451 DiagExpr diag()
452 {
453 return elems_.diag();
454 }
455
456 UpperExpr upper() const
457 {
458 return elems_.upper();
459 }
460
462 {
463 return elems_.upper();
464 }
465
466 LowerExpr lower() const
467 {
468 return elems_.lower();
469 }
470
472 {
473 return elems_.lower();
474 }
475
476
477 // fvMatrix
479 SourceExpr source() const
480 {
481 return elems_.source();
482 }
485 {
486 return elems_.source();
487 }
489 UpperExpr internalCoeffs(const label i)
490 {
491 return
492 (
493 elems_.internalCoeffs().set(i)
494 ? elems_.internalCoeffs()[i]
496 );
497 }
498
499 UpperExpr internalCoeffs(const label i) const
500 {
501 return
502 (
503 elems_.internalCoeffs().set(i)
504 ? elems_.internalCoeffs()[i]
506 );
507 }
508
509 UpperExpr boundaryCoeffs(const label i)
510 {
511 return
512 (
513 elems_.boundaryCoeffs().set(i)
514 ? elems_.boundaryCoeffs()[i]
516 );
517 }
518
519 UpperExpr boundaryCoeffs(const label i) const
520 {
521 return
522 (
523 elems_.boundaryCoeffs().set(i)
524 ? elems_.boundaryCoeffs()[i]
526 );
527 }
528
530 {
531 return *const_cast<this_type&>
532 (
533 elems_
534 ).faceFluxCorrectionPtr().get();
535 }
538 {
539 return *elems_.faceFluxCorrectionPtr().get();
540 }
541};
542
543
544/*---------------------------------------------------------------------------*\
545 Class fvMatrixConstRefWrap Declaration
546\*---------------------------------------------------------------------------*/
547
548//- Expression wrap of const reference to fvMatrix
549template<class Matrix>
551:
552 public fvMatrixExpression
553 <
554 fvMatrixConstRefWrap<Matrix>,
555 ListConstRefWrap<typename Matrix::psiFieldType::value_type>, // diag
556 ListConstRefWrap<typename Matrix::psiFieldType::value_type>, // upper
557 ListConstRefWrap<typename Matrix::psiFieldType::value_type>, // lower
558 //ListConstRefWrap<typename Matrix::psiFieldType::value_type>, // faceflux
559 GeometricFieldConstRefWrap<typename Matrix::faceFluxFieldType>,
560 ListConstRefWrap<typename Matrix::psiFieldType::value_type> // source
561 >
562{
563public:
564
565 static constexpr bool is_leaf = false; //true;
566
567 //- The fvMatrix type
568 typedef Matrix this_type;
570 //- Type to return for internal field
571 typedef typename Matrix::psiFieldType::value_type value_type;
572
573 //- Type to return for containers
577 //typedef ListConstRefWrap<value_type> FaceFluxExpr;
579 <
580 typename Matrix::faceFluxFieldType
581 > FaceFluxExpr;
583
585private:
586
587 const this_type& elems_;
588
590public:
591
592 // Construct from components
593 fvMatrixConstRefWrap(const this_type& elems)
596 <
598 DiagExpr,
603 >
604 (
605 elems.hasDiag(),
606 elems.hasUpper(),
607 elems.hasLower(),
608 elems.hasFaceFluxCorrection(),
609 elems.dimensions()
610 ),
611 elems_(elems)
612 {}
613
614
615 // lduMatrix part
616
617 DiagExpr diag() const
619 return elems_.diag();
620 }
621
622 UpperExpr upper() const
623 {
624 return elems_.upper();
625 }
626
627 LowerExpr lower() const
628 {
629 return elems_.lower();
630 }
631
632
633 // fvMatrix
634
635 SourceExpr source() const
636 {
637 return elems_.source();
638 }
639
640 UpperExpr internalCoeffs(const label i) const
641 {
642 return
643 (
644 elems_.internalCoeffs().set(i)
645 ? elems_.internalCoeffs()[i]
647 );
648 }
649
650 UpperExpr boundaryCoeffs(const label i) const
651 {
652 return
653 (
654 elems_.boundaryCoeffs().set(i)
655 ? elems_.boundaryCoeffs()[i]
657 );
658 }
659
661 {
662 return *const_cast<this_type&>
663 (
664 elems_
665 ).faceFluxCorrectionPtr().get();
666 }
667};
668
669
670// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
671
672// Expressions on fvMatrices
673// ~~~~~~~~~~~~~~~~~~~~~~~~~
674
675// operator+
676template<typename E1, typename E2>
677class fvm_add
678:
679 public fvMatrixExpression
680 <
681 fvm_add<E1, E2>,
682 List_add // DiagExpr
683 <
684 typename E1::DiagExpr,
685 typename E2::DiagExpr
686 >,
687 List_add // UpperExpr
688 <
689 typename E1::UpperExpr,
690 typename E2::UpperExpr
691 >,
692 List_add // LowerExpr
693 <
694 typename E1::LowerExpr,
695 typename E2::LowerExpr
696 >,
697 GF_add // FaceFluxExpr
698 <
699 typename E1::FaceFluxExpr,
700 typename E2::FaceFluxExpr
701 >,
702 List_add // SourceExpr
703 <
704 typename E1::SourceExpr,
705 typename E2::SourceExpr
706 >
707 >
708{
709 // cref if leaf, copy otherwise
710 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
711 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_;
712
713public:
714 static constexpr bool is_leaf = false;
715
716 //- Type to return for internal field
717 typedef typename E1::value_type value_type;
718
719 //- Type to return for containers
720 typedef List_add
721 <
722 typename E1::DiagExpr,
723 typename E2::DiagExpr
724 > DiagExpr;
725 typedef List_add
726 <
727 typename E1::UpperExpr,
728 typename E2::UpperExpr
729 > UpperExpr;
730 typedef List_add
731 <
732 typename E1::LowerExpr,
733 typename E2::LowerExpr
734 > LowerExpr;
735 typedef GF_add
736 <
737 typename E1::FaceFluxExpr,
738 typename E2::FaceFluxExpr
740 typedef List_add
741 <
742 typename E1::SourceExpr,
743 typename E2::SourceExpr
745
746 fvm_add(const E1& u, const E2& v)
747 :
749 <
750 fvm_add<E1, E2>,
751 DiagExpr,
752 UpperExpr,
756 >
757 (
758 u.hasDiag() || v.hasDiag(),
759 u.hasUpper() || v.hasUpper(),
760 u.hasLower() || v.hasLower(),
762 u.dimensions()
763 ),
764 u_(u),
765 v_(v)
766 {
767 //Pout<< "fvm_add :" << nl
768 // << " u_ : " << boost::core::demangle(typeid(u_).name())
769 // << nl
770 // << " v_ : " << boost::core::demangle(typeid(v_).name())
771 // << endl;
772 }
774
775 // lduMatrix part
776
777 DiagExpr diag() const
778 {
779 return u_.diag() + v_.diag();
780 }
781
782 UpperExpr upper() const
783 {
784 return u_.upper() + v_.upper();
785 }
786
787 LowerExpr lower() const
788 {
789 return u_.lower() + v_.lower();
790 }
791
792 // fvMatrix
793
794 SourceExpr source() const
795 {
796 return u_.source() + v_.source();
797 }
798
799 UpperExpr boundaryCoeffs(const label i) const
800 {
801 return u_.boundaryCoeffs(i) + v_.boundaryCoeffs(i);
802 }
803
804 UpperExpr internalCoeffs(const label i) const
805 {
806 return u_.internalCoeffs(i) + v_.internalCoeffs(i);
807 }
808
810 {
811 return u_.faceFluxCorrection() + v_.faceFluxCorrection();
812 }
813};
814template<typename E1, typename E2>
815fvm_add<E1, E2>
816operator+
817(
819 <
820 E1,
821 typename E1::DiagExpr,
822 typename E1::UpperExpr,
823 typename E1::LowerExpr,
824 typename E1::FaceFluxExpr,
825 typename E1::SourceExpr
826 > const& u,
829 E2,
830 typename E2::DiagExpr,
831 typename E2::UpperExpr,
832 typename E2::LowerExpr,
833 typename E2::FaceFluxExpr,
834 typename E2::SourceExpr
835 > const& v
836)
837{
839 (
840 static_cast<const E1&>(u),
841 static_cast<const E2&>(v)
842 );
843}
844
846// operator-, operator==
847template<typename E1, typename E2>
848class fvm_subtract
849:
850 public fvMatrixExpression
851 <
852 fvm_subtract<E1, E2>,
853 List_subtract // diag
854 <
855 typename E1::DiagExpr,
856 typename E2::DiagExpr
857 >,
858 List_subtract // upper
859 <
860 typename E1::UpperExpr,
861 typename E2::UpperExpr
862 >,
863 List_subtract // lower
864 <
865 typename E1::LowerExpr,
866 typename E2::LowerExpr
867 >,
868 GF_subtract // faceflux
869 <
870 typename E1::FaceFluxExpr,
871 typename E2::FaceFluxExpr
872 >,
873 List_subtract // source
874 <
875 typename E1::SourceExpr,
876 typename E2::SourceExpr
878 >
879{
880 // cref if leaf, copy otherwise
881 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
882 typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_;
883
884public:
885 static constexpr bool is_leaf = false;
886
887 //- Type to return for internal field
888 typedef typename E1::value_type value_type;
889
890 //- Type to return for containers
891 typedef List_subtract
892 <
893 typename E1::DiagExpr,
894 typename E2::DiagExpr
895 > DiagExpr;
896 typedef List_subtract
897 <
898 typename E1::UpperExpr,
899 typename E2::UpperExpr
900 > UpperExpr;
901 typedef List_subtract
902 <
903 typename E1::LowerExpr,
904 typename E2::LowerExpr
905 > LowerExpr;
906 typedef GF_subtract
907 <
908 typename E1::FaceFluxExpr,
909 typename E2::FaceFluxExpr
910 > FaceFluxExpr;
911 typedef List_subtract
912 <
913 typename E1::SourceExpr,
914 typename E2::SourceExpr
915 > SourceExpr;
916
917 fvm_subtract(const E1& u, const E2& v)
918 :
920 <
921 fvm_subtract<E1, E2>,
922 DiagExpr,
923 UpperExpr,
924 LowerExpr,
927 >
929 u.hasDiag() || v.hasDiag(),
930 u.hasUpper() || v.hasUpper(),
931 u.hasLower() || v.hasLower(),
934 ),
935 u_(u),
936 v_(v)
937 {}
939
940 // lduMatrix part
941
942 DiagExpr diag() const
944 return u_.diag() - v_.diag();
945 }
946
947 UpperExpr upper() const
949 return u_.upper() - v_.upper();
951
952 LowerExpr lower() const
953 {
954 return u_.lower() - v_.lower();
955 }
956
957
958 // fvMatrix
959
960 SourceExpr source() const
961 {
962 return u_.source() - v_.source();
963 }
964
965 UpperExpr internalCoeffs(const label i) const
966 {
967 return u_.internalCoeffs(i) - v_.internalCoeffs(i);
968 }
969
970 UpperExpr boundaryCoeffs(const label i) const
971 {
972 return u_.boundaryCoeffs(i) - v_.boundaryCoeffs(i);
973 }
974
976 {
977 return u_.faceFluxCorrection() - v_.faceFluxCorrection();
978 }
979};
980template<typename E1, typename E2>
982operator-
983(
986 E1,
987 typename E1::DiagExpr,
988 typename E1::UpperExpr,
989 typename E1::LowerExpr,
990 typename E1::FaceFluxExpr,
991 typename E1::SourceExpr
992 > const& u,
994 <
995 E2,
996 typename E2::DiagExpr,
997 typename E2::UpperExpr,
998 typename E2::LowerExpr,
999 typename E2::FaceFluxExpr,
1000 typename E2::SourceExpr
1001 > const& v
1002)
1005 (
1006 static_cast<const E1&>(u),
1007 static_cast<const E2&>(v)
1009}
1010template<typename E1, typename E2>
1012operator==
1013(
1016 E1,
1017 typename E1::DiagExpr,
1018 typename E1::UpperExpr,
1019 typename E1::LowerExpr,
1020 typename E1::FaceFluxExpr,
1021 typename E1::SourceExpr
1022 > const& u,
1024 <
1025 E2,
1026 typename E2::DiagExpr,
1027 typename E2::UpperExpr,
1028 typename E2::LowerExpr,
1029 typename E2::FaceFluxExpr,
1030 typename E2::SourceExpr
1031 > const& v
1032)
1033{
1035 (
1036 static_cast<const E1&>(u),
1037 static_cast<const E2&>(v)
1038 );
1039}
1040
1041
1042// Negation : operator-
1043template<typename E1>
1044class fvm_negate
1046 public fvMatrixExpression
1047 <
1048 fvm_negate<E1>,
1049 List_negate<typename E1::DiagExpr>,
1050 List_negate<typename E1::UpperExpr>,
1051 List_negate<typename E1::LowerExpr>,
1052 List_negate<typename E1::FaceFluxExpr>,
1053 List_negate<typename E1::SourceExpr>
1054 >
1055{
1056 // cref if leaf, copy otherwise
1057 typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
1058
1059public:
1060 static constexpr bool is_leaf = false;
1061
1062 //- Type to return for internal field
1063 typedef typename E1::value_type value_type;
1064
1065 //- Type to return for containers
1071
1072 fvm_negate(const E1& u)
1073 :
1075 <
1078 UpperExpr,
1079 LowerExpr,
1082 >
1083 (
1084 u.hasDiag(),
1085 u.hasUpper(),
1086 u.hasLower(),
1087 u.hasFaceFluxCorrection(),
1088 u.dimensions()
1089 ),
1090 u_(u)
1091 {}
1092
1094 // lduMatrix part
1095
1096 DiagExpr diag() const
1097 {
1098 return -u_.diag();
1099 }
1100
1101 UpperExpr upper() const
1102 {
1103 return -u_.upper();
1108 return -u_.lower();
1110
1111
1112 // fvMatrix
1113
1114 SourceExpr source() const
1115 {
1116 return -u_.source();
1117 }
1118
1119 UpperExpr internalCoeffs(const label i) const
1120 {
1121 return -u_.internalCoeffs(i);
1122 }
1123
1124 UpperExpr boundaryCoeffs(const label i) const
1125 {
1126 return -u_.boundaryCoeffs(i);
1127 }
1128
1130 {
1131 return -u_.faceFluxCorrection();
1132 }
1134template<typename E1>
1136operator-
1137(
1139 <
1140 E1,
1141 typename E1::DiagExpr,
1142 typename E1::UpperExpr,
1143 typename E1::LowerExpr,
1144 typename E1::FaceFluxExpr,
1145 typename E1::SourceExpr
1146 > const& u
1147)
1148{
1149 return fvm_negate<E1>(static_cast<const E1&>(u));
1150}
1152
1153//- fvMatrix, internal parts and dimensions only. No upper/lower/boundaryCoeffs
1154// etc. Used for source manipulation.
1155template<class E1, class E2> //, class FaceFluxExpr>
1157:
1158 public fvMatrixExpression
1159 <
1160 fvMatrixInternal<E1, E2>,
1161 E1, // Diag
1162 E1, // Upper, Not used
1163 E1, // Lower, Not used
1164 GeometricField<typename E1::value_type, fvPatchField, volMesh>, // FaceFlux, Not used
1165 E2 // Source
1167{
1168public:
1169
1170 static constexpr bool is_leaf = false; //true;
1171
1172 //- Type to return for internal field
1173 typedef typename E1::value_type value_type;
1174
1175 //- Type to return for containers
1176 typedef E1 DiagExpr;
1177 typedef E1 UpperExpr; // not yet used
1178 typedef E1 LowerExpr; // not yet used
1180 FaceFluxExpr; // not yet used
1181 typedef E2 SourceExpr;
1182
1183
1184private:
1185
1186 const E1 diag_;
1187 const SourceExpr source_;
1188
1189
1190public:
1191
1192 // Construct from component expressions
1194 (
1195 const dimensionSet& dimensions,
1197 const SourceExpr& source
1198 )
1199 :
1201 <
1202 fvMatrixInternal<DiagExpr, SourceExpr>, //, FaceFluxExpr>,
1203 DiagExpr,
1204 UpperExpr, // upper not yet used
1205 LowerExpr, // lower not yet used
1206 FaceFluxExpr, // face flux not used
1208 >
1209 (
1210 true, //elems.hasDiag(),
1211 false, //elems.hasUpper(),
1212 false, //elems.hasLower(),
1213 false, //elems.hasFaceFluxCorrection(),
1214 dimensions //elems.dimensions()
1216 diag_(diag),
1217 source_(source)
1218 {
1219 //Pout<< "fvMatrixInternal :" << nl
1220 // << " diag_ : " << boost::core::demangle(typeid(diag_).name())
1221 // << nl
1222 // << " source_: "
1223 // << boost::core::demangle(typeid(source_).name())
1224 // << nl
1225 // << " *this : " << boost::core::demangle(typeid(*this).name())
1226 // << endl;
1227 }
1228
1229 // Construct from component expressions
1231 (
1232 const dimensionSet& dimensions,
1233 const DiagExpr&& diag,
1234 const SourceExpr&& source
1235 )
1236 :
1238 <
1239 fvMatrixInternal<DiagExpr, SourceExpr>, //, FaceFluxExpr>,
1240 DiagExpr,
1241 UpperExpr, // upper not yet used
1242 LowerExpr, // lower not yet used
1243 FaceFluxExpr, // faceflux not yet used
1245 >
1246 (
1247 true, //elems.hasDiag(),
1248 false, //elems.hasUpper(),
1249 false, //elems.hasLower(),
1250 false, //elems.hasFaceFluxCorrection(),
1251 dimensions //elems.dimensions()
1252 ),
1253 diag_(diag),
1254 source_(source)
1255 {}
1256
1257
1258 // lduMatrix part
1259
1260 auto diag() const
1261 {
1262 return diag_;
1263 }
1264
1265 auto upper() const
1266 {
1267 return List<value_type>::null();
1268 }
1269
1270 auto lower() const
1271 {
1272 return List<value_type>::null();
1273 }
1275
1276 // fvMatrix
1277
1278 auto source() const
1279 {
1280 return source_;
1281 }
1282
1283 auto internalCoeffs(const label i) const
1284 {
1285 return List<value_type>::null();
1286 }
1287
1288 auto boundaryCoeffs(const label i) const
1289 {
1290 return List<value_type>::null();
1291 }
1292
1293 auto faceFluxCorrection() const
1294 {
1296 }
1297};
1298template<typename E1>
1299auto SuSp
1300(
1301 const dimensionSet& dimensions, // dimensions of expression
1302 const E1& expression,
1303 const GeometricField<typename E1::value_type, fvPatchField, volMesh>& fld
1305{
1306 //- Wrap of constant as a list expression
1308 //- Wrap of List as an expression
1310
1311 // Wrap zero
1312 const constant constantZero(fld.size(), 0.0);
1313
1314 // Wrap mesh volume
1315 const expr V(fld.mesh().V());
1316
1317 return fvMatrixInternal
1318 (
1319 dimVol*dimensions*fld.dimensions(),
1320 V*max(expression, constantZero),
1321 V*min(expression, constantZero)*expr(fld.internalField())
1323}
1324template<typename E1>
1325auto Sp
1326(
1327 const dimensionSet& dimensions, // dimensions of expression
1328 const E1& expression,
1330)
1331{
1332 //- Wrap of constant as a list expression
1334 //- Wrap of List as an expression
1336
1337 // Wrap zero
1338 const constant constantZero(fld.size(), 0.0);
1339
1340 // Wrap mesh volume
1341 const expr V(fld.mesh().V());
1342
1344 (
1345 dimVol*dimensions*fld.dimensions(),
1346 V*expr(fld.internalField()),
1347 constantZero // Still provides an expression for source. TBD.
1348 );
1349}
1350template<typename E1>
1351auto Su
1352(
1353 const dimensionSet& dimensions, // dimensions of expression
1354 const E1& expression,
1356)
1357{
1358 //- Wrap of constant as a list expression
1360 //- Wrap of List as an expression
1361 typedef ListConstRefWrap<typename E1::value_type> expr;
1362
1363 // Wrap zero
1364 const constant constantZero(fld.size(), 0.0);
1365
1366 // Wrap mesh volume
1367 const expr V(fld.mesh().V());
1368
1369 return fvMatrixInternal
1370 (
1371 dimVol*dimensions*fld.dimensions(),
1372 constantZero // Still provides an expression for diag. TBD.
1373 -V*expression
1374 );
1375}
1376
1377
1378//XXXXXXXX
1379// Alternative in-place fvMatrix sources. Can be removed once ones above
1380// work.
1381template<class Expr>
1382void Su
1383(
1385 const Expr& expression
1386)
1387{
1388 //- Wrap of List as an expression
1389 typedef ListConstRefWrap<typename Expr::value_type> expr;
1390 //- Evaluator of an expression
1391 typedef ListRefWrap<typename Expr::value_type> evaluator;
1392
1393 // Wrap mesh volume
1394 const expr V(m.psi().mesh().V());
1395
1396 // Add expression to source
1397 auto& s = m.source();
1398 evaluator(s, expr(s) + V*expression);
1399}
1400template<class Expr>
1401void rhs
1402(
1404 const Expr& expression
1405)
1406{
1407 Su(m, expression);
1408}
1409template<class Expr, class Expr2>
1410void Sp
1411(
1413 const Expr2& mult,
1414 const Expr& expression
1415)
1416{
1417 //- Wrap of List as an expression
1418 typedef ListConstRefWrap<typename Expr::value_type> expr;
1419 //- Evaluator of an expression
1420 typedef ListRefWrap<typename Expr::value_type> evaluator;
1421
1422 // Wrap mesh volume
1423 const expr V(m.psi().mesh().V());
1424
1425 // Add expression onto diag
1426 auto& d = m.diag();
1427 evaluator(d, expr(d) - mult*V*expression);
1428}
1429template<class Expr, class Expr2>
1430void SuSp
1431(
1432 fvMatrix<typename Expr::value_type>& m,
1433 const Expr2& mult,
1434 const Expr& expression
1435)
1436{
1437 //- Wrap of constant as a list expression
1439 //- Wrap of List as an expression
1441 //- Evaluator of an expression
1443
1444 const constant constantZero(expression.size(), 0.0);
1445
1446 // Wrap mesh volume
1447 const expr V(m.psi().mesh().V());
1448
1449 // Linearise expression
1450 auto& diag = m.diag();
1451 auto& source = m.source();
1452
1453 // diag() += domain*max(susp.field(), scalar(0));
1454 evaluator
1455 (
1456 diag,
1457 expr(diag) - mult*V*max(expression, constantZero)
1458 );
1459 // source() -= domain*min(susp.field(), scalar(0))*fld.primitiveField();
1460 evaluator
1462 source,
1463 expr(source)
1464 + (
1465 mult
1466 *V
1467 *min(expression, constantZero)
1468 *expr(m.psi().internalField())
1469 )
1471}
1472//XXXXXXXX
1473
1474
1475
1476// Some discretisation using expressions
1477// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1478
1479template<typename E1, typename E2>
1480class interpolate
1481:
1482 public GeometricFieldExpression
1483 <
1484 interpolate<E1, E2>,
1485
1486 //- Type to return for internal field
1487 List_interpolate
1488 <
1489 IndirectConstWrap<typename E1::IntExpr>,
1490 IndirectConstWrap<typename E1::IntExpr>,
1491 typename E2::IntExpr
1492 >,
1493
1494 //- Type to return for uncoupled patch field
1495 typename E1::UncoupledPatchExpr,
1496
1497 //- Type to return for coupled patch field
1498 List_interpolate
1499 <
1500 IndirectConstWrap<typename E1::IntExpr>,
1501 typename E1::CoupledPatchExpr,
1502 typename E2::CoupledPatchExpr
1503 >,
1504
1505 //- Type of actual values
1506 typename E1::value_type
1507 >
1508{
1509 //- Internal values
1510 typename std::conditional
1511 <
1512 E1::is_leaf,
1513 const E1&,
1514 const E1
1515 >::type cellVals_;
1516
1517 //- Interpolation weights
1518 typename std::conditional
1519 <
1520 E2::is_leaf,
1521 const E2&,
1522 const E2
1523 >::type faceWeights_;
1524
1525 //- Addressing container
1526 const fvMesh& mesh_;
1527
1528public:
1529
1530 static constexpr bool is_leaf = false;
1531
1532 //- Type to return for internal field
1533 typedef List_interpolate
1534 <
1537 typename E2::IntExpr
1538 > IntExpr;
1539
1540 //- Type to return for uncoupled patch field
1541 typedef typename E1::UncoupledPatchExpr UncoupledPatchExpr;
1542
1543 //- Type to return for coupled patch field
1544 typedef List_interpolate
1545 <
1547 typename E1::CoupledPatchExpr,
1548 typename E2::CoupledPatchExpr
1551 //- Type of actual values
1552 typedef typename E1::value_type value_type;
1553
1554
1555 // Construct from components
1557 (
1558 const E1& cellVals,
1559 const E2& faceWeights,
1560 const fvMesh& mesh
1561 )
1562 :
1564 <
1565 interpolate<E1, E2>,
1566 IntExpr,
1570 >
1571 (
1572 cellVals.dimensions()*faceWeights.dimensions(),
1573 faceWeights.oriented()
1574 ),
1575 cellVals_(cellVals),
1576 faceWeights_(faceWeights),
1577 mesh_(mesh)
1578 {}
1579
1580 value_type operator[](const label i) const
1581 {
1582 const auto ownVal = cellVals_[mesh_.owner()[i]];
1583 const auto neiVal = cellVals_[mesh_.neighbour()[i]];
1584 return faceWeights_[i]*(ownVal-neiVal) + neiVal;
1585 }
1586
1587 label size() const
1588 {
1589 return faceWeights_.size(); // number of internal faces
1590 }
1591
1592 IntExpr internalField() const
1593 {
1594 return IntExpr
1595 (
1596 IndirectConstWrap<typename E1::IntExpr>
1597 (
1598 cellVals_.internalField(),
1599 mesh_.owner()
1600 ),
1601 IndirectConstWrap<typename E1::IntExpr>
1602 (
1603 cellVals_.internalField(),
1604 mesh_.neighbour()
1605 ),
1606 faceWeights_.internalField()
1607 );
1608 }
1609
1610 UncoupledPatchExpr patchField(const label i) const
1611 {
1612 return UncoupledPatchExpr(cellVals_.patchField(i));
1613 }
1615 CoupledPatchExpr coupledPatchField(const label i) const
1616 {
1617 return CoupledPatchExpr
1618 (
1620 (
1621 cellVals_.internalField(),
1622 mesh_.boundaryMesh()[i].faceCells()
1623 ),
1624 cellVals_.access
1625 (
1626 [&](const auto& fld, const label i)
1627 {
1628 return ListConstTmpWrap<Field<value_type>>
1630 fld.boundaryField()[i].patchNeighbourField()
1631 );
1632 },
1633 i
1634 ),
1635 faceWeights_.coupledPatchField(i)
1636 );
1637 }
1638};
1640
1641template<typename E1>
1643:
1645 <
1646 E1,
1647 GeometricFieldConstRefWrap<surfaceScalarField>
1649{
1650public:
1651
1652 // Construct from components
1654 (
1655 const E1& cellVals,
1656 const fvMesh& mesh
1657 )
1658 :
1660 <
1661 E1,
1663 >
1664 (
1665 cellVals,
1666 mesh.surfaceInterpolation::weights().expr(),
1667 mesh
1668 )
1669 {}
1670};
1671
1673template<class Type, class E1, class E2>
1675(
1677 const E1& gammaMagSf,
1678 const E2& deltaCoeffs
1683
1684 const auto& vf = fvm.psi();
1685
1686 // Set dimensions. Or should we just check?
1687 const_cast<dimensionSet&>(fvm.dimensions()).reset
1688 (
1689 deltaCoeffs.dimensions()
1690 * gammaMagSf.dimensions()
1691 * vf.dimensions()
1692 );
1693
1695 (
1696 fvm.upper(),
1697 deltaCoeffs.internalField()*gammaMagSf.internalField()
1698 );
1699 fvm.negSumDiag();
1700
1701 forAll(vf.boundaryField(), patchi)
1703 const auto& pvf = vf.boundaryField()[patchi];
1704 auto& intCoeffs = fvm.internalCoeffs()[patchi];
1705 auto& bouCoeffs = fvm.boundaryCoeffs()[patchi];
1706
1707 if (pvf.coupled())
1708 {
1709 // Evaluate deltaCoeffs
1710 scalarField pDeltaCoeffs;
1711 ListRefWrap<scalar>(pDeltaCoeffs, deltaCoeffs.patchField(patchi));
1712
1713 //intCoeffs = pGamma*pvf.gradientInternalCoeffs(pDeltaCoeffs);
1714 evaluator
1715 (
1716 intCoeffs,
1717 expr(pvf.gradientInternalCoeffs(pDeltaCoeffs)())
1718 *gammaMagSf.patchField(patchi)
1719 );
1720 //bouCoeffs = -pGamma*pvf.gradientBoundaryCoeffs(pDeltaCoeffs);
1721 evaluator
1722 (
1723 bouCoeffs,
1724 -expr(pvf.gradientBoundaryCoeffs(pDeltaCoeffs)())
1725 *gammaMagSf.patchField(patchi)
1726 );
1727 }
1728 else
1729 {
1730 //intCoeffs = pGamma*pvf.gradientInternalCoeffs();
1731 evaluator
1732 (
1733 intCoeffs,
1734 expr(pvf.gradientInternalCoeffs()())
1735 *gammaMagSf.patchField(patchi)
1736 );
1737 //bouCoeffs = -pGamma*pvf.gradientBoundaryCoeffs();
1738 evaluator
1739 (
1740 bouCoeffs,
1741 -expr(pvf.gradientBoundaryCoeffs()())
1742 *gammaMagSf.patchField(patchi)
1743 );
1744 }
1746}
1747
1748
1749// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1750
1751} // End namespace Expression
1752} // End namespace Foam
1753
1754// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1755
1756#endif
1757
1758// ************************************************************************* //
Expression templates for GeometricFields.
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))
const Mesh & mesh() const noexcept
Return const reference to mesh.
Expression wrap of const reference to GeometricField.
Expression wrap of non-const reference to GeometricField.
Expression wrap of indirection.
Expression wrap of const reference to UList.
Expression wrap of non-const reference to List.
Not possible: a *= b has to return a new type so it can never be in-place.
Expression wrap of a List with a uniform value.
Expression wrap of const reference to fvMatrix.
ListConstRefWrap< value_type > LowerExpr
ListConstRefWrap< value_type > UpperExpr
UpperExpr internalCoeffs(const label i) const
GeometricFieldConstRefWrap< typename Matrix::faceFluxFieldType > FaceFluxExpr
ListConstRefWrap< value_type > SourceExpr
UpperExpr boundaryCoeffs(const label i) const
Matrix::psiFieldType::value_type value_type
Type to return for internal field.
ListConstRefWrap< value_type > DiagExpr
Type to return for containers.
Matrix & evaluate(Matrix &m) const
Helper to evaluate (=construct) an fvMatrix.
UpperExpr internalCoeffs(const label i) const
const dimensionSet & dimensions() const noexcept
fvMatrixExpression(const bool hasDiag, const bool hasUpper, const bool hasLower, const bool hasFaceFluxCorrection, const dimensionSet &dimensions)
UpperExpr boundaryCoeffs(const label i) const
fvMatrix, internal parts and dimensions only. No upper/lower/boundaryCoeffs
auto boundaryCoeffs(const label i) const
auto internalCoeffs(const label i) const
E1::value_type value_type
Type to return for internal field.
fvMatrixInternal(const dimensionSet &dimensions, const DiagExpr &diag, const SourceExpr &source)
E1 DiagExpr
Type to return for containers.
fvMatrixInternal(const dimensionSet &dimensions, const DiagExpr &&diag, const SourceExpr &&source)
GeometricField< value_type, fvPatchField, volMesh > FaceFluxExpr
Expression wrap of non-const reference to fvMatrix.
fvMatrixRefWrap(this_type &&elems)
Move construct.
GeometricFieldRefWrap< typename Matrix::faceFluxFieldType > FaceFluxExpr
ListRefWrap< value_type > LowerExpr
ListRefWrap< value_type > UpperExpr
UpperExpr internalCoeffs(const label i)
this_type & evaluate(const fvMatrixExpression< E, typename E::DiagExpr, typename E::UpperExpr, typename E::LowerExpr, typename E::FaceFluxExpr, typename E::SourceExpr > &expr)
Evaluate and return as GeoField. Rename to evaluate to make it clear it takes time?...
fvMatrixRefWrap(this_type &elems, const fvMatrixExpression< E, typename E::DiagExpr, typename E::UpperExpr, typename E::LowerExpr, typename E::FaceFluxExpr, typename E::SourceExpr > &expr)
UpperExpr internalCoeffs(const label i) const
UpperExpr boundaryCoeffs(const label i)
ListRefWrap< value_type > SourceExpr
fvMatrixRefWrap(this_type &elems)
Copy construct.
UpperExpr boundaryCoeffs(const label i) const
ListRefWrap< value_type > DiagExpr
Type to return for containers.
Matrix::psiFieldType::value_type value_type
Type to return for internal field.
fvm_add(const E1 &u, const E2 &v)
static constexpr bool is_leaf
GF_add< typename E1::FaceFluxExpr, typename E2::FaceFluxExpr > FaceFluxExpr
UpperExpr internalCoeffs(const label i) const
List_add< typename E1::LowerExpr, typename E2::LowerExpr > LowerExpr
E1::value_type value_type
Type to return for internal field.
List_add< typename E1::UpperExpr, typename E2::UpperExpr > UpperExpr
FaceFluxExpr faceFluxCorrection() const
List_add< typename E1::DiagExpr, typename E2::DiagExpr > DiagExpr
Type to return for containers.
UpperExpr boundaryCoeffs(const label i) const
List_add< typename E1::SourceExpr, typename E2::SourceExpr > SourceExpr
List_negate< typename E1::SourceExpr > SourceExpr
UpperExpr internalCoeffs(const label i) const
E1::value_type value_type
Type to return for internal field.
FaceFluxExpr faceFluxCorrection() const
List_negate< typename E1::UpperExpr > UpperExpr
List_negate< typename E1::FaceFluxExpr > FaceFluxExpr
List_negate< typename E1::LowerExpr > LowerExpr
UpperExpr boundaryCoeffs(const label i) const
List_negate< typename E1::DiagExpr > DiagExpr
Type to return for containers.
GF_subtract< typename E1::FaceFluxExpr, typename E2::FaceFluxExpr > FaceFluxExpr
List_subtract< typename E1::DiagExpr, typename E2::DiagExpr > DiagExpr
Type to return for containers.
UpperExpr internalCoeffs(const label i) const
E1::value_type value_type
Type to return for internal field.
List_subtract< typename E1::SourceExpr, typename E2::SourceExpr > SourceExpr
FaceFluxExpr faceFluxCorrection() const
List_subtract< typename E1::UpperExpr, typename E2::UpperExpr > UpperExpr
fvm_subtract(const E1 &u, const E2 &v)
UpperExpr boundaryCoeffs(const label i) const
List_subtract< typename E1::LowerExpr, typename E2::LowerExpr > LowerExpr
E1::UncoupledPatchExpr UncoupledPatchExpr
Type to return for uncoupled patch field.
List_interpolate< IndirectConstWrap< typename E1::IntExpr >, typename E1::CoupledPatchExpr, typename E2::CoupledPatchExpr > CoupledPatchExpr
Type to return for coupled patch field.
E1::value_type value_type
Type of actual values.
UncoupledPatchExpr patchField(const label i) const
interpolate(const E1 &cellVals, const E2 &faceWeights, const fvMesh &mesh)
List_interpolate< IndirectConstWrap< typename E1::IntExpr >, IndirectConstWrap< typename E1::IntExpr >, typename E2::IntExpr > IntExpr
Type to return for internal field.
value_type operator[](const label i) const
CoupledPatchExpr coupledPatchField(const label i) const
linearInterpolate(const E1 &cellVals, const fvMesh &mesh)
Generic GeometricField class.
static const this_type & null() noexcept
Return a null GeometricField (reference to a nullObject).
const Internal & internalField() const noexcept
Return a const-reference to the dimensioned internal field.
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
Definition List.H:138
A templated (m x n) matrix of objects of <T>. The layout is (mRows x nCols) - row-major order:
Definition Matrix.H:77
List< Type > diag() const
Extract the diagonal elements. Method may change in the future.
Definition Matrix.C:416
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
void reset(const dimensionSet &ds)
Copy assign the exponents from the dimensionSet.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition fvMatrix.H:118
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Definition fvMatrix.H:487
Field< Type > & source() noexcept
Definition fvMatrix.H:535
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
const labelUList & owner() const
Internal face owner. Note bypassing virtual mechanism so.
Definition fvMesh.H:572
const labelUList & neighbour() const
Internal face neighbour.
Definition fvMesh.H:580
const scalarField & diag() const
Definition lduMatrix.C:195
Cell to surface interpolation scheme. Included in fvMesh.
dynamicFvMesh & mesh
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.
ListRefWrap< typename Expr::value_type > evaluator
Evaluator of an expression.
ListConstRefWrap< typename Expr::value_type > expr
Fully self-contained constant field wrapper. Not needed?
void fvmLaplacianUncorrected(fvMatrix< Type > &fvm, const E1 &gammaMagSf, const E2 &deltaCoeffs)
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)
const expr V(m.psi().mesh().V())
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)
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
auto SuSp(const dimensionSet &dimensions, const E1 &expression, const GeometricField< typename E1::value_type, fvPatchField, volMesh > &fld)
Different types of constants.
Namespace of functions to calculate implicit derivatives returning a matrix.
Namespace for OpenFOAM.
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const direction noexcept
Definition scalarImpl.H:265
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
const dimensionSet dimVol(dimVolume)
Older spelling for dimVolume.
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299