TensorI.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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include <type_traits>
30
31#include "SymmTensor.H"
32
33// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34
35template<class Cmpt>
37:
38 Tensor::msType(Zero)
39{}
40
41
42template<class Cmpt>
43template<class Cmpt2>
45(
46 const MatrixSpace<Tensor<Cmpt2>, Cmpt2, 3, 3>& vs
47)
48:
49 Tensor::msType(vs)
50{}
51
52
53template<class Cmpt>
54template<class Cmpt2>
56(
57 const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
58)
59:
60 Tensor::msType(vs)
61{}
62
63
64template<class Cmpt>
66{
67 this->v_[XX] = st.ii(); this->v_[XY] = Zero; this->v_[XZ] = Zero;
68 this->v_[YX] = Zero; this->v_[YY] = st.ii(); this->v_[YZ] = Zero;
69 this->v_[ZX] = Zero; this->v_[ZY] = Zero; this->v_[ZZ] = st.ii();
70}
71
72
73template<class Cmpt>
75{
76 this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
77 this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
78 this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
79}
80
81
82template<class Cmpt>
84(
85 const Vector<Vector<Cmpt>>& vecs,
86 const bool transposed
87)
88:
89 Tensor<Cmpt>(vecs.x(), vecs.y(), vecs.z(), transposed)
90{}
91
92
93template<class Cmpt>
95(
96 const Vector<Cmpt>& x,
97 const Vector<Cmpt>& y,
98 const Vector<Cmpt>& z,
99 const bool transposed
100)
101{
102 if (transposed)
104 this->cols(x, y, z);
105 }
106 else
108 this->rows(x, y, z);
109 }
110}
112
113template<class Cmpt>
115(
116 const Cmpt txx, const Cmpt txy, const Cmpt txz,
117 const Cmpt tyx, const Cmpt tyy, const Cmpt tyz,
118 const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
119)
120{
121 this->v_[XX] = txx; this->v_[XY] = txy; this->v_[XZ] = txz;
122 this->v_[YX] = tyx; this->v_[YY] = tyy; this->v_[YZ] = tyz;
123 this->v_[ZX] = tzx; this->v_[ZY] = tzy; this->v_[ZZ] = tzz;
124}
125
126
127template<class Cmpt>
128template
130 template<class, Foam::direction, Foam::direction> class Block2,
131 Foam::direction BRowStart,
132 Foam::direction BColStart
133>
135(
136 const Block2<Tensor<Cmpt>, BRowStart, BColStart>& block
137)
140{}
141
142
143template<class Cmpt>
145:
146 Tensor::msType(is)
147{}
148
149
150// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
151
152template<class Cmpt>
153inline const Cmpt& Foam::Tensor<Cmpt>::xx() const
154{
155 return this->v_[XX];
156}
157
159template<class Cmpt>
160inline const Cmpt& Foam::Tensor<Cmpt>::xy() const
161{
162 return this->v_[XY];
163}
164
166template<class Cmpt>
167inline const Cmpt& Foam::Tensor<Cmpt>::xz() const
169 return this->v_[XZ];
173template<class Cmpt>
174inline const Cmpt& Foam::Tensor<Cmpt>::yx() const
176 return this->v_[YX];
180template<class Cmpt>
181inline const Cmpt& Foam::Tensor<Cmpt>::yy() const
183 return this->v_[YY];
184}
185
186
187template<class Cmpt>
188inline const Cmpt& Foam::Tensor<Cmpt>::yz() const
190 return this->v_[YZ];
191}
193
194template<class Cmpt>
195inline const Cmpt& Foam::Tensor<Cmpt>::zx() const
196{
197 return this->v_[ZX];
198}
199
200
201template<class Cmpt>
202inline const Cmpt& Foam::Tensor<Cmpt>::zy() const
203{
204 return this->v_[ZY];
205}
207
208template<class Cmpt>
209inline const Cmpt& Foam::Tensor<Cmpt>::zz() const
210{
211 return this->v_[ZZ];
213
214
215template<class Cmpt>
217{
218 return this->v_[XX];
219}
220
221
222template<class Cmpt>
224{
225 return this->v_[XY];
227
228
229template<class Cmpt>
231{
232 return this->v_[XZ];
233}
234
235
236template<class Cmpt>
238{
239 return this->v_[YX];
241
242
243template<class Cmpt>
245{
246 return this->v_[YY];
247}
248
249
250template<class Cmpt>
252{
253 return this->v_[YZ];
254}
255
256
257template<class Cmpt>
259{
260 return this->v_[ZX];
261}
262
263
264template<class Cmpt>
267 return this->v_[ZY];
268}
269
270
271template<class Cmpt>
273{
274 return this->v_[ZZ];
276
277
278template<class Cmpt>
280{
281 return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
282}
283
284
285template<class Cmpt>
288 return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
289}
290
291
292template<class Cmpt>
295 return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
296}
298
299template<class Cmpt>
301{
302 return Vector<Cmpt>(this->v_[XX], this->v_[YX], this->v_[ZX]);
304
305
306template<class Cmpt>
308{
309 return Vector<Cmpt>(this->v_[XY], this->v_[YY], this->v_[ZY]);
310}
311
312
313template<class Cmpt>
315{
316 return Vector<Cmpt>(this->v_[XZ], this->v_[YZ], this->v_[ZZ]);
317}
318
319
320template<class Cmpt>
321template<Foam::direction Idx>
323{
324 if (Idx == 0) return cx();
325 else if (Idx == 1) return cy();
326 else if (Idx == 2) return cz();
327
328 static_assert(Idx < 3, "Invalid column access");
329 return Zero;
330}
331
332
333template<class Cmpt>
335{
336 switch (c)
337 {
338 case 0: return cx(); break;
339 case 1: return cy(); break;
340 case 2: return cz(); break;
341 default:
343 << "Invalid column access " << c << abort(FatalError);
344 }
345
346 return Zero;
347}
348
349
350template<class Cmpt>
351template<Foam::direction Idx>
353{
354 if (Idx == 0) return x();
355 else if (Idx == 1) return y();
356 else if (Idx == 2) return z();
357
358 static_assert(Idx < 3, "Invalid row access");
359 return Zero;
360}
361
362
363template<class Cmpt>
365{
366 switch (r)
367 {
368 case 0: return x(); break;
369 case 1: return y(); break;
370 case 2: return z(); break;
371 default:
373 << "Invalid row access " << r << abort(FatalError);
374 }
375
376 return Zero;
377}
378
379
380template<class Cmpt>
381template<Foam::direction Idx>
383{
384 if (Idx == 0)
385 {
386 this->v_[XX] = v.x();
387 this->v_[YX] = v.y();
388 this->v_[ZX] = v.z();
389 }
390 else if (Idx == 1)
391 {
392 this->v_[XY] = v.x();
393 this->v_[YY] = v.y();
394 this->v_[ZY] = v.z();
395 }
396 else if (Idx == 2)
397 {
398 this->v_[XZ] = v.x();
399 this->v_[YZ] = v.y();
400 this->v_[ZZ] = v.z();
401 }
402
403 static_assert(Idx < 3, "Invalid column access");
404}
405
406
407template<class Cmpt>
408template<Foam::direction Idx>
410{
411 if (Idx == 0)
412 {
413 this->v_[XX] = v.x(); this->v_[XY] = v.y(); this->v_[XZ] = v.z();
414 }
415 else if (Idx == 1)
416 {
417 this->v_[YX] = v.x(); this->v_[YY] = v.y(); this->v_[YZ] = v.z();
418 }
419 else if (Idx == 2)
420 {
421 this->v_[ZX] = v.x(); this->v_[ZY] = v.y(); this->v_[ZZ] = v.z();
422 }
423
424 static_assert(Idx < 3, "Invalid row access");
425}
426
427
428template<class Cmpt>
430(
431 const Vector<Cmpt>& x,
432 const Vector<Cmpt>& y,
433 const Vector<Cmpt>& z
434)
435{
436 this->v_[XX] = x.x(); this->v_[XY] = y.x(); this->v_[XZ] = z.x();
437 this->v_[YX] = x.y(); this->v_[YY] = y.y(); this->v_[YZ] = z.y();
438 this->v_[ZX] = x.z(); this->v_[ZY] = y.z(); this->v_[ZZ] = z.z();
439}
440
441
442template<class Cmpt>
444(
445 const Vector<Cmpt>& x,
446 const Vector<Cmpt>& y,
447 const Vector<Cmpt>& z
448)
449{
450 this->v_[XX] = x.x(); this->v_[XY] = x.y(); this->v_[XZ] = x.z();
451 this->v_[YX] = y.x(); this->v_[YY] = y.y(); this->v_[YZ] = y.z();
452 this->v_[ZX] = z.x(); this->v_[ZY] = z.y(); this->v_[ZZ] = z.z();
453}
454
455
456template<class Cmpt>
458(
459 const direction c,
460 const Vector<Cmpt>& v
461)
462{
463 switch (c)
464 {
465 case 0: col<0>(v); break;
466 case 1: col<1>(v); break;
467 case 2: col<2>(v); break;
468 default:
470 << "Invalid column access " << c << abort(FatalError);
471 }
472}
473
474
475template<class Cmpt>
477(
478 const direction r,
479 const Vector<Cmpt>& v
480)
481{
482 switch (r)
483 {
484 case 0: row<0>(v); break;
485 case 1: row<1>(v); break;
486 case 2: row<2>(v); break;
487 default:
489 << "Invalid row access " << r << abort(FatalError);
490 }
491}
492
493
494template<class Cmpt>
496{
497 return Vector<Cmpt>(this->v_[XX], this->v_[YY], this->v_[ZZ]);
498}
499
500
501template<class Cmpt>
503{
504 this->v_[XX] = v.x(); this->v_[YY] = v.y(); this->v_[ZZ] = v.z();
505}
506
507
508template<class Cmpt>
509inline bool Foam::Tensor<Cmpt>::is_identity(const scalar tol) const
510{
511 return
512 (
513 mag(xx() - pTraits<Cmpt>::one) < tol
514 && mag(yy() - pTraits<Cmpt>::one) < tol
515 && mag(zz() - pTraits<Cmpt>::one) < tol
516 && mag(xy()) < tol && mag(xz()) < tol
517 && mag(yx()) < tol && mag(yz()) < tol
518 && mag(zx()) < tol && mag(zy()) < tol
519 );
520}
521
522
523// * * * * * * * * * * * * * * * Member Operations * * * * * * * * * * * * * //
524
525template<class Cmpt>
527{
528 return Tensor<Cmpt>
529 (
530 xx(), yx(), zx(),
531 xy(), yy(), zy(),
532 xz(), yz(), zz()
533 );
534}
535
536
537template<class Cmpt>
540{
541 const Tensor<Cmpt>& t1 = *this;
542
543 return Tensor<Cmpt>
544 (
545 t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
546 t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
547 t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
548
549 t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
550 t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
551 t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
552
553 t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
554 t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
555 t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
556 );
557}
558
559
560template<class Cmpt>
563{
564 const Tensor<Cmpt>& t1 = *this;
565
566 return Tensor<Cmpt>
567 (
568 t1.xx()*t2.xx(), t1.xy()*t2.xy(), t1.xz()*t2.xz(),
569 t1.yx()*t2.yx(), t1.yy()*t2.yy(), t1.yz()*t2.yz(),
570 t1.zx()*t2.zx(), t1.zy()*t2.zy(), t1.zz()*t2.zz()
571 );
572}
573
574
575// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
576
577template<class Cmpt>
579{
580 *this = this->inner(t);
581}
582
583
584template<class Cmpt>
585template<class Cmpt2>
587(
588 const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
589)
590{
591 VectorSpace<Tensor<Cmpt>, Cmpt, 9>::operator=(vs);
592}
593
594
595template<class Cmpt>
597{
598 this->v_[XX] = st.ii(); this->v_[XY] = Zero; this->v_[XZ] = Zero;
599 this->v_[YX] = Zero; this->v_[YY] = st.ii(); this->v_[YZ] = Zero;
600 this->v_[ZX] = Zero; this->v_[ZY] = Zero; this->v_[ZZ] = st.ii();
601}
602
603
604template<class Cmpt>
606{
607 this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
608 this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
609 this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
610}
611
612
613template<class Cmpt>
615{
616 this->v_[XX] = tr.x().x();
617 this->v_[XY] = tr.x().y();
618 this->v_[XZ] = tr.x().z();
619
620 this->v_[YX] = tr.y().x();
621 this->v_[YY] = tr.y().y();
622 this->v_[YZ] = tr.y().z();
623
624 this->v_[ZX] = tr.z().x();
625 this->v_[ZY] = tr.z().y();
626 this->v_[ZZ] = tr.z().z();
627}
628
629
630// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
631
632namespace Foam
633{
634
635// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
636
637//- Return the trace of a Tensor
638template<class Cmpt>
639inline Cmpt tr(const Tensor<Cmpt>& t)
640{
641 return t.xx() + t.yy() + t.zz();
642}
643
644
645//- Return the spherical part of a Tensor
646template<class Cmpt>
648{
650 (
651 (1.0/3.0)*tr(t)
652 );
653}
654
655
656//- Return the symmetric part of a Tensor
657template<class Cmpt>
659{
660 return SymmTensor<Cmpt>
661 (
662 t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
663 t.yy(), 0.5*(t.yz() + t.zy()),
664 t.zz()
665 );
666}
667
668
669//- Return twice the symmetric part of a Tensor
670template<class Cmpt>
672{
673 return SymmTensor<Cmpt>
674 (
675 2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
676 2*t.yy(), (t.yz() + t.zy()),
677 2*t.zz()
678 );
679}
680
681
682//- Return the skew-symmetric part of a Tensor
683template<class Cmpt>
685{
686 return Tensor<Cmpt>
687 (
688 Zero, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
689 0.5*(t.yx() - t.xy()), Zero, 0.5*(t.yz() - t.zy()),
690 0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), Zero
691 );
692}
693
694
695//- Return the skew-symmetric part of a SymmTensor as a Tensor
696template<class Cmpt>
697inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
698{
699 return Tensor<Cmpt>::zero;
700}
701
702
703//- Return the deviatoric part of a Tensor
704template<class Cmpt>
706{
707 return t - sph(t);
708}
709
710
711//- Return the two-third deviatoric part of a Tensor
712template<class Cmpt>
714{
715 return t - 2*sph(t);
716}
717
718
719//- Return the determinant of a Tensor
720template<class Cmpt>
721inline Cmpt det(const Tensor<Cmpt>& t)
722{
723 return
724 (
725 t.xx()*t.yy()*t.zz() + t.xy()*t.yz()*t.zx()
726 + t.xz()*t.yx()*t.zy() - t.xx()*t.yz()*t.zy()
727 - t.xy()*t.yx()*t.zz() - t.xz()*t.yy()*t.zx()
728 );
729}
730
731
732//- Return the cofactor Tensor of a Tensor
733template<class Cmpt>
735{
736 return Tensor<Cmpt>
737 (
738 t.yy()*t.zz() - t.zy()*t.yz(),
739 t.zx()*t.yz() - t.yx()*t.zz(),
740 t.yx()*t.zy() - t.yy()*t.zx(),
741
742 t.xz()*t.zy() - t.xy()*t.zz(),
743 t.xx()*t.zz() - t.xz()*t.zx(),
744 t.xy()*t.zx() - t.xx()*t.zy(),
745
746 t.xy()*t.yz() - t.xz()*t.yy(),
747 t.yx()*t.xz() - t.xx()*t.yz(),
748 t.xx()*t.yy() - t.yx()*t.xy()
749 );
750}
751
752
753//- Return the inverse of a Tensor by using the given determinant
754template<class Cmpt>
755inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt dett)
756{
757 #ifdef FULLDEBUG
758 if (mag(dett) < VSMALL)
759 {
761 << "Tensor is not invertible due to the (almost) zero determinant:"
762 << " Tensor = " << t << nl
763 << " det(Tensor) = " << dett
764 << abort(FatalError);
765 }
766 #endif
767
768 return cof(t).T()/dett;
769}
770
771
772//- Return the inverse of a Tensor
773template<class Cmpt>
775{
776 return inv(t, det(t));
777}
778
779
780//- Return the inverse of this Tensor
781template<class Cmpt>
783{
784 return Foam::inv(*this);
785}
786
787
788//- Return the 1st invariant of a Tensor
789template<class Cmpt>
790inline Cmpt invariantI(const Tensor<Cmpt>& t)
791{
792 return tr(t);
793}
794
795
796//- Return the 2nd invariant of a Tensor
797template<class Cmpt>
798inline Cmpt invariantII(const Tensor<Cmpt>& t)
799{
800 return
801 (
802 t.xx()*t.yy() + t.yy()*t.zz() + t.xx()*t.zz()
803 - t.xy()*t.yx() - t.yz()*t.zy() - t.xz()*t.zx()
804 );
805}
806
807
808//- Return the 3rd invariant of a Tensor
809template<class Cmpt>
810inline Cmpt invariantIII(const Tensor<Cmpt>& t)
811{
812 return det(t);
813}
814
815
816// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
817
818//- Sum of a SphericalTensor and a Tensor
819template<class Cmpt>
820inline Tensor<Cmpt>
822{
823 return Tensor<Cmpt>
824 (
825 st1.ii() + t2.xx(), t2.xy(), t2.xz(),
826 t2.yx(), st1.ii() + t2.yy(), t2.yz(),
827 t2.zx(), t2.zy(), st1.ii() + t2.zz()
828 );
829}
830
831
832//- Sum of a Tensor and a SphericalTensor
833template<class Cmpt>
834inline Tensor<Cmpt>
836{
837 return Tensor<Cmpt>
838 (
839 t1.xx() + st2.ii(), t1.xy(), t1.xz(),
840 t1.yx(), t1.yy() + st2.ii(), t1.yz(),
841 t1.zx(), t1.zy(), t1.zz() + st2.ii()
842 );
843}
844
845
846//- Sum of a SymmTensor and a Tensor
847template<class Cmpt>
848inline Tensor<Cmpt>
850{
851 return Tensor<Cmpt>
852 (
853 st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
854 st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
855 st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
856 );
857}
858
859
860//- Sum of a Tensor and a SymmTensor
861template<class Cmpt>
862inline Tensor<Cmpt>
864{
865 return Tensor<Cmpt>
866 (
867 t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
868 t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
869 t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
870 );
871}
872
873
874//- Subtract a Tensor from a SphericalTensor
875template<class Cmpt>
876inline Tensor<Cmpt>
878{
879 return Tensor<Cmpt>
880 (
881 st1.ii() - t2.xx(), -t2.xy(), -t2.xz(),
882 -t2.yx(), st1.ii() - t2.yy(), -t2.yz(),
883 -t2.zx(), -t2.zy(), st1.ii() - t2.zz()
884 );
885}
886
887
888//- Subtract a SphericalTensor from a Tensor
889template<class Cmpt>
890inline Tensor<Cmpt>
892{
893 return Tensor<Cmpt>
894 (
895 t1.xx() - st2.ii(), t1.xy(), t1.xz(),
896 t1.yx(), t1.yy() - st2.ii(), t1.yz(),
897 t1.zx(), t1.zy(), t1.zz() - st2.ii()
898 );
899}
900
901
902//- Subtract a Tensor from a SymmTensor
903template<class Cmpt>
904inline Tensor<Cmpt>
906{
907 return Tensor<Cmpt>
908 (
909 st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
910 st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
911 st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
912 );
913}
914
915
916//- Subtract a SymmTensor from a Tensor
917template<class Cmpt>
918inline Tensor<Cmpt>
920{
921 return Tensor<Cmpt>
922 (
923 t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
924 t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
925 t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
926 );
927}
928
929
930//- Return the Hodge dual of a Tensor as a Vector
931template<class Cmpt>
933{
934 return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
935}
936
937
938//- Return the Hodge dual of a Vector as a Tensor
939template<class Cmpt>
941{
942 return Tensor<Cmpt>
943 (
944 Zero, -v.z(), v.y(),
945 v.z(), Zero, -v.x(),
946 -v.y(), v.x(), Zero
947 );
948}
949
950
951//- Division of a Vector by a Tensor
952template<class Cmpt>
953inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt>>::type
955{
956 return inv(t) & v;
957}
958
959
960//- Division of a Tensor by a Cmpt
961template<class Cmpt>
962inline Tensor<Cmpt>
963operator/(const Tensor<Cmpt>& t, const Cmpt s)
964{
965 #ifdef FULLDEBUG
966 if (mag(s) < VSMALL)
967 {
969 << "Tensor = " << t
970 << " is not divisible due to a zero value in Cmpt:"
971 << "Cmpt = " << s
972 << abort(FatalError);
973 }
974 #endif
975
976 return Tensor<Cmpt>
977 (
978 t.xx()/s, t.xy()/s, t.xz()/s,
979 t.yx()/s, t.yy()/s, t.yz()/s,
980 t.zx()/s, t.zy()/s, t.zz()/s
981 );
982}
983
984
985//- Inner-product of a Tensor and a Tensor
986template<class Cmpt>
987inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt>>::type
989{
990 return t1.inner(t2);
991}
992
993
994//- Inner-product of a SphericalTensor and a Tensor
995template<class Cmpt>
996inline Tensor<Cmpt>
998{
999 return Tensor<Cmpt>
1000 (
1001 st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
1002 st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
1003 st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
1004 );
1005}
1006
1007
1008//- Inner-product of a Tensor and a SphericalTensor
1009template<class Cmpt>
1010inline Tensor<Cmpt>
1012{
1013 return Tensor<Cmpt>
1014 (
1015 t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
1016 t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
1017 t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
1018 );
1019}
1020
1021
1022//- Inner-product of a SymmTensor and a Tensor
1023template<class Cmpt>
1024inline Tensor<Cmpt>
1026{
1027 return Tensor<Cmpt>
1028 (
1029 st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
1030 st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
1031 st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
1032
1033 st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
1034 st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
1035 st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
1036
1037 st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
1038 st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
1039 st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
1040 );
1041}
1042
1043
1044//- Inner-product of a Tensor and a SymmTensor
1045template<class Cmpt>
1046inline Tensor<Cmpt>
1048{
1049 return Tensor<Cmpt>
1050 (
1051 t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
1052 t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
1053 t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
1054
1055 t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
1056 t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
1057 t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
1058
1059 t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
1060 t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
1061 t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
1062 );
1063}
1064
1065
1066//- Inner-product of a Tensor and a Vector
1067template<class Cmpt>
1068#if defined(__GNUC__) && !defined(__clang__)
1069// Workaround for gcc (11+) that fails to handle tensor dot vector
1070__attribute__((optimize("no-tree-vectorize")))
1071#endif
1072inline typename innerProduct<Tensor<Cmpt>, Vector<Cmpt>>::type
1074{
1075 return Vector<Cmpt>
1076 (
1077 t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
1078 t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
1079 t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
1080 );
1081}
1082
1083
1084//- Inner-product of a Vector and a Tensor
1085template<class Cmpt>
1086inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt>>::type
1088{
1089 return Vector<Cmpt>
1090 (
1091 v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
1092 v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
1093 v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
1094 );
1095}
1096
1097
1098//- Double-inner-product of a SphericalTensor and a Tensor
1099template<class Cmpt>
1100inline Cmpt
1102{
1103 return (st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
1104}
1105
1106
1107//- Double-inner-product of a Tensor and a SphericalTensor
1108template<class Cmpt>
1109inline Cmpt
1111{
1112 return (t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
1113}
1114
1115
1116//- Double-inner-product of a SymmTensor and a Tensor
1117template<class Cmpt>
1118inline Cmpt
1120{
1121 return
1122 (
1123 st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
1124 st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
1125 st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
1126 );
1127}
1128
1129
1130//- Double-inner-product of a Tensor and a SymmTensor
1131template<class Cmpt>
1132inline Cmpt
1134{
1135 return
1136 (
1137 t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
1138 t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
1139 t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
1140 );
1141}
1142
1143
1144//- Outer-product of a Vector and a Vector
1145template<class Cmpt>
1146inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt>>::type
1148{
1149 return Tensor<Cmpt>
1150 (
1151 v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
1152 v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
1153 v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
1154 );
1155}
1156
1157
1158// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1159
1160template<class Cmpt>
1162{
1163public:
1164
1166};
1167
1168
1169template<class Cmpt>
1171{
1172public:
1173
1175};
1176
1177
1178template<class Cmpt>
1180{
1181public:
1182
1184};
1185
1186
1187template<class Cmpt>
1189{
1190public:
1191
1193};
1194
1195
1196template<class Cmpt>
1197class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt>>
1198{
1199public:
1200
1202};
1203
1204
1205template<class Cmpt>
1206class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt>>
1207{
1208public:
1209
1211};
1212
1213
1214template<class Cmpt>
1215class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt>>
1216{
1217public:
1218
1220};
1221
1222
1223template<class Cmpt>
1224class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt>>
1225{
1226public:
1227
1229};
1230
1231
1232// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1233
1234} // End namespace Foam
1235
1236// ************************************************************************* //
scalar y
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
Templated matrix space.
Definition: MatrixSpace.H:61
A templated (3 x 3) diagonal tensor of objects of <T>, effectively containing 1 element,...
const Cmpt & ii() const
A templated (3 x 3) symmetric tensor of objects of <T>, effectively containing 6 elements,...
Definition: SymmTensor.H:57
const Cmpt & xx() const
Definition: SymmTensorI.H:97
const Cmpt & yz() const
Definition: SymmTensorI.H:127
const Cmpt & xz() const
Definition: SymmTensorI.H:109
const Cmpt & zz() const
Definition: SymmTensorI.H:145
const Cmpt & xy() const
Definition: SymmTensorI.H:103
const Cmpt & yy() const
Definition: SymmTensorI.H:121
A templated (3 x 3) tensor of objects of <T> derived from MatrixSpace.
Definition: Tensor.H:64
bool is_identity(const scalar tol=ROOTVSMALL) const
Is identity tensor?
Definition: TensorI.H:509
Tensor< Cmpt > T() const
Return non-Hermitian transpose.
Definition: TensorI.H:526
const Cmpt & xx() const
Definition: TensorI.H:153
const Cmpt & yx() const
Definition: TensorI.H:174
void rows(const Vector< Cmpt > &x, const Vector< Cmpt > &y, const Vector< Cmpt > &z)
Set row values.
Definition: TensorI.H:444
void operator&=(const Tensor< Cmpt > &t)
Assign inner-product of this with another Tensor.
Definition: TensorI.H:578
Tensor & operator=(const Tensor &)=default
Copy assignment.
const Cmpt & yz() const
Definition: TensorI.H:188
Vector< Cmpt > row() const
Extract vector for given row: compile-time check of index.
Vector< Cmpt > z() const
Extract vector for row 2.
Definition: TensorI.H:293
const Cmpt & xz() const
Definition: TensorI.H:167
Vector< Cmpt > cz() const
Extract vector for column 2.
Definition: TensorI.H:314
Tensor< Cmpt > inner(const Tensor< Cmpt > &t2) const
Inner-product of this with another Tensor.
Definition: TensorI.H:539
const Cmpt & zz() const
Definition: TensorI.H:209
Tensor< Cmpt > inv() const
Return inverse.
Definition: TensorI.H:782
const Cmpt & xy() const
Definition: TensorI.H:160
Vector< Cmpt > cx() const
Extract vector for column 0.
Definition: TensorI.H:300
Vector< Cmpt > cy() const
Extract vector for column 1.
Definition: TensorI.H:307
const Cmpt & zx() const
Definition: TensorI.H:195
const Cmpt & zy() const
Definition: TensorI.H:202
const Cmpt & yy() const
Definition: TensorI.H:181
void cols(const Vector< Cmpt > &x, const Vector< Cmpt > &y, const Vector< Cmpt > &z)
Set column values.
Definition: TensorI.H:430
Vector< Cmpt > y() const
Extract vector for row 1.
Definition: TensorI.H:286
Vector< Cmpt > col() const
Extract vector for given column: compile-time check of index.
Tensor()=default
Default construct.
Tensor< Cmpt > schur(const Tensor< Cmpt > &t2) const
Schur-product of this with another Tensor.
Definition: TensorI.H:562
Vector< Cmpt > diag() const
Extract the diagonal as a vector.
Definition: TensorI.H:495
Vector< Cmpt > x() const
Extract vector for row 0.
Definition: TensorI.H:279
Templated vector space.
Definition: VectorSpace.H:79
Templated 3D Vector derived from VectorSpace adding construction from 3 components,...
Definition: Vector.H:65
const Cmpt & z() const
Access to the vector z component.
Definition: VectorI.H:85
const Cmpt & y() const
Access to the vector y component.
Definition: VectorI.H:79
const Cmpt & x() const
Access to the vector x component.
Definition: VectorI.H:73
Creates a single block of cells from point coordinates, numbers of cells in each direction and an exp...
Definition: block.H:61
dimensioned< Type > T() const
Return transpose.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:62
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:63
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
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))
Namespace for OpenFOAM.
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
dimensionedSymmTensor dev2(const dimensionedSymmTensor &dt)
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)
dimensionedScalar det(const dimensionedSphericalTensor &dt)
dimensionedSymmTensor symm(const dimensionedSymmTensor &dt)
dimensionedScalar tr(const dimensionedSphericalTensor &dt)
tmp< faMatrix< Type > > operator+(const faMatrix< Type > &, const faMatrix< Type > &)
Cmpt invariantII(const SymmTensor< Cmpt > &st)
Return the 2nd invariant of a SymmTensor.
Definition: SymmTensorI.H:468
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
Cmpt invariantIII(const SymmTensor< Cmpt > &st)
Return the 3rd invariant of a SymmTensor.
Definition: SymmTensorI.H:480
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
tmp< GeometricField< Type, fvPatchField, volMesh > > operator&(const fvMatrix< Type > &, const DimensionedField< Type, volMesh > &)
dimensionedScalar operator/(const scalar s1, const dimensionedScalar &ds2)
dimensionedSymmTensor cof(const dimensionedSymmTensor &dt)
Cmpt invariantI(const SymmTensor< Cmpt > &st)
Return the 1st invariant of a SymmTensor.
Definition: SymmTensorI.H:460
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
SphericalTensor< Cmpt > sph(const DiagTensor< Cmpt > &dt)
Return the spherical part of a DiagTensor as a SphericalTensor.
Definition: DiagTensorI.H:130
uint8_t direction
Definition: direction.H:56
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
dimensioned< typename scalarProduct< Type1, Type2 >::type > operator&&(const dimensioned< Type1 > &, const dimensioned< Type2 > &)
dimensionedTensor skew(const dimensionedTensor &dt)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
A non-counting (dummy) refCount.
Definition: refCount.H:59