GranOO  3.0
A robust and versatile workbench to build 3D dynamic simulations based on the Discrete Element Method
Tensor.hpp
Go to the documentation of this file.
1 // This file is part of GranOO, a workbench for DEM simulation.
2 //
3 // Author(s) : - Damien Andre IRCER/UNILIM, Limoges France
4 // <damien.andre@unilim.fr>
5 // - Jean-luc Charles Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
6 // <jean-luc.charles@ensam.eu>
7 // - Jeremie Girardot Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
8 // <jeremie.girardot@ensam.eu>
9 // - Cedric Hubert LAMIH/UPHF, Valenciennes France
10 // <cedric.hubert@uphf.fr>
11 // - Ivan Iordanoff Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
12 // <ivan.iordanoff@ensam.eu>
13 //
14 // Copyright (C) 2008-2019 D. Andre, JL. Charles, J. Girardot, C. Hubert, I. Iordanoff
15 //
16 // This program is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 // This program is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 
29 
30 #ifndef _GranOO_Geom_Tensor_hpp_
31 #define _GranOO_Geom_Tensor_hpp_
32 
33 #include <cmath>
34 #include <iostream>
35 #include "GranOO3/3rdParty/Eigen/Dense"
36 
37 #include <boost/archive/text_oarchive.hpp>
38 #include <boost/archive/text_iarchive.hpp>
39 
40 #include "GranOO3/Geom/Vector.hpp"
41 
42 
43 namespace GranOO3
44 {
45  namespace Geom
46  {
47 
48  class Frame;
49 
50  std::ostream& operator<< (std::ostream& o, const Tensor& m);
51  Vector operator* (const Tensor &m, const Vector &v);
52  Tensor operator* (const double &d, const Tensor &m);
53  Tensor operator* (const Tensor &m, const double &d);
54  Tensor operator* (const Tensor &m1, const Tensor &m2);
55  Tensor operator/ (const Tensor &m, const double &d);
56  Tensor operator- (const Tensor &m1, const Tensor &m2);
57  Tensor operator+ (const Tensor &m1, const Tensor &m2);
58  bool operator== (const Tensor &m1, const Tensor &m2);
59 
60 
61  class Tensor
62  {
63  public:
64  // Usefull for internal use only, NOT DOCUMENTED !
65  static std::string class_ID() {return "Tensor";}
66  static const int N = 9;
67 
68  public:
69  // Constructors and destructor
70  Tensor();
71  Tensor(const Tensor& m);
72  Tensor(const Tensor& m, const Frame& from, const Frame& to);
73 
74  Tensor(double, double, double,
75  double, double, double,
76  double, double, double);
77 
78  // Internal operators
79  Tensor& operator=(const Tensor& m);
80  void operator+= (const Tensor& m);
81  void operator/= (double d);
82 
83  // Usefull methods
84  void clear();
85  void eigen_value(Vector& v, Quaternion& q) const;
86  double determinant() const;
87  Tensor transpose() const;
88  Tensor inverse() const;
89  bool is_null() const;
90  bool is_nan() const;
91 
92  // Component
93  double & xx();
94  double & xy();
95  double & xz();
96 
97  double & yx();
98  double & yy();
99  double & yz();
100 
101  double & zx();
102  double & zy();
103  double & zz();
104 
105  const double & xx() const;
106  const double & xy() const;
107  const double & xz() const;
108 
109  const double & yx() const;
110  const double & yy() const;
111  const double & yz() const;
112 
113  const double & zx() const;
114  const double & zy() const;
115  const double & zz() const;
116 
117 
118  // Component (for python wrapper)
119  void set_xx(const double&);
120  void set_xy(const double&);
121  void set_xz(const double&);
122  void set_yx(const double&);
123  void set_yy(const double&);
124  void set_yz(const double&);
125  void set_zx(const double&);
126  void set_zy(const double&);
127  void set_zz(const double&);
128 
129  // Component (for python wrapper)
130  double get_xx() const;
131  double get_xy() const;
132  double get_xz() const;
133  double get_yx() const;
134  double get_yy() const;
135  double get_yz() const;
136  double get_zx() const;
137  double get_zy() const;
138  double get_zz() const;
139 
140  template <typename Axis> double& val();
141  template <typename Axis> const double& val() const;
142 
143  const double & operator() (unsigned int i, unsigned int j) const;
144  double& operator() (unsigned int i, unsigned int j);
145 
146  double trace() const;
147 
148 
149  private:
150  //BOOST SERIALIZATION
152  template<class Archive>
153  void serialize(Archive & ar, const unsigned int);
154 
155  public:
156  Eigen::Matrix<double, 3, 3> coord;
157  };
158 
159 #ifndef DOXYGEN_SHOULD_SKIP_THIS
160 
161  template<class Archive>
162  void Tensor::serialize(Archive & ar, const unsigned int ) {
163  ar & xx(); ar & yx(); ar & zx();
164  ar & xy(); ar & yy(); ar & zy();
165  ar & xz(); ar & yz(); ar & zz();
166  }
167 
168  inline
169  Tensor::Tensor(const Tensor& M)
170  : coord(M.coord) {
171  }
172 
173  inline
174  Tensor::Tensor(double XX, double XY, double XZ,
175  double YX, double YY, double YZ,
176  double ZX, double ZY, double ZZ)
177  : coord(){
178  xx() = XX; xy() = XY; xz() = XZ;
179  yx() = YX; yy() = YY; yz() = YZ;
180  zx() = ZX; zy() = ZY; zz() = ZZ;
181  }
182 
183  inline
185  : coord() {
186  }
187 
188  // Operator
189  inline Tensor
190  operator/(const Tensor &m, const double &d) {
191  return Tensor(m.xx()/d, m.xy()/d, m.xz()/d,
192  m.yx()/d, m.yy()/d, m.yz()/d,
193  m.zx()/d, m.zy()/d, m.zz()/d);
194  }
195 
196  inline Tensor &
197  Tensor::operator=(const Tensor& M) {
198  coord = M.coord;
199  return *this;
200  }
201 
202  inline double
203  Tensor::determinant() const {
204  return (xx()*(yy()*zz()-yz()*zy()) - xy()*(yx()*zz()-yz()*zx()) + xz()*(yx()*zy()-yy()*zx()));
205  }
206 
207  inline Tensor
208  Tensor::transpose() const {
209  return Tensor(xx(), yx(), zx(), xy(), yy(), zy(), xz(), yz(), zz());
210  }
211 
212  inline Tensor
213  Tensor::inverse() const {
214  const double det = determinant();
215  return Tensor(yy()*zz() - zy()*yz(),
216  zx()*yz() - yx()*zz(),
217  yx()*zy() - zx()*yy(),
218  zy()*xz() - xy()*zz(),
219  xx()*zz() - zx()*xz(),
220  zx()*xy() - xx()*zy(),
221  xy()*yz() - yy()*xz(),
222  yx()*xz() - xx()*yz(),
223  xx()*yy() - yx()*xy()
224  ).transpose()/det;
225  }
226 
227  inline void
228  Tensor::clear() {
229  xx() = xy() = xz() = 0.;
230  yx() = yy() = yz() = 0.;
231  zx() = zy() = zz() = 0.;
232  }
233 
234  inline bool
235  Tensor::is_null() const {
236  return (xy() == 0. && xz() == 0. && xz() == 0. &&
237  yy() == 0. && yz() == 0. && yz() == 0. &&
238  zy() == 0. && zz() == 0. && zz() == 0);
239  }
240 
241  inline bool
242  Tensor::is_nan() const {
243  if (xx()!=xx())
244  return true;
245  if (xy()!=xy())
246  return true;
247  if (xz()!=xz())
248  return true;
249 
250  if (yx()!=yx())
251  return true;
252  if (yy()!=yy())
253  return true;
254  if (yz()!=yz())
255  return true;
256 
257  if (zx()!=zx())
258  return true;
259  if (zy()!=zy())
260  return true;
261  if (zz()!=zz())
262  return true;
263 
264  return false;
265  }
266 
267  inline double & Tensor::xx() {
268  return coord(0,0);
269  }
270 
271  inline double & Tensor::xy() {
272  return coord(0,1);
273  }
274 
275  inline double & Tensor::xz() {
276  return coord(0,2);
277  }
278 
279  inline double & Tensor::yx() {
280  return coord(1,0);
281  }
282 
283  inline double & Tensor::yy() {
284  return coord(1,1);
285  }
286 
287  inline double & Tensor::yz() {
288  return coord(1,2);
289  }
290 
291  inline double & Tensor::zx() {
292  return coord(2,0);
293  }
294 
295  inline double & Tensor::zy() {
296  return coord(2,1);
297  }
298 
299  inline double & Tensor::zz() {
300  return coord(2,2);
301  }
302 
303  inline const double & Tensor::xx() const {
304  return coord(0,0);
305  }
306 
307  inline const double & Tensor::xy() const {
308  return coord(0,1);
309  }
310 
311  inline const double & Tensor::xz() const {
312  return coord(0,2);
313  }
314 
315  inline const double & Tensor::yx() const {
316  return coord(1,0);
317  }
318 
319  inline const double & Tensor::yy() const {
320  return coord(1,1);
321  }
322 
323  inline const double & Tensor::yz() const {
324  return coord(1,2);
325  }
326 
327  inline const double & Tensor::zx() const {
328  return coord(2,0);
329  }
330 
331  inline const double & Tensor::zy() const {
332  return coord(2,1);
333  }
334 
335  inline const double & Tensor::zz() const {
336  return coord(2,2);
337  }
338 
339  template<> inline double& Tensor::val<XX>() {
340  return xx();
341  }
342 
343  template<> inline double& Tensor::val<XY>() {
344  return xy();
345  }
346 
347  template<> inline double& Tensor::val<XZ>() {
348  return xz();
349  }
350 
351  template<> inline double& Tensor::val<YX>() {
352  return yx();
353  }
354 
355  template<> inline double& Tensor::val<YY>() {
356  return yy();
357  }
358 
359  template<> inline double& Tensor::val<YZ>() {
360  return yz();
361  }
362 
363  template<> inline double& Tensor::val<ZX>() {
364  return zx();
365  }
366 
367  template<> inline double& Tensor::val<ZY>() {
368  return zy();
369  }
370 
371  template<> inline double& Tensor::val<ZZ>() {
372  return zz();
373  }
374 
375  template<> inline const double& Tensor::val<XX>() const {
376  return xx();
377  }
378 
379  template<> inline const double& Tensor::val<XY>() const {
380  return xy();
381  }
382 
383  template<> inline const double& Tensor::val<XZ>() const {
384  return xz();
385  }
386 
387  template<> inline const double& Tensor::val<YX>() const {
388  return yx();
389  }
390 
391  template<> inline const double& Tensor::val<YY>() const {
392  return yy();
393  }
394 
395  template<> inline const double& Tensor::val<YZ>() const {
396  return yz();
397  }
398 
399  template<> inline const double& Tensor::val<ZX>() const {
400  return zx();
401  }
402 
403  template<> inline const double& Tensor::val<ZY>() const {
404  return zy();
405  }
406 
407  template<> inline const double& Tensor::val<ZZ>() const {
408  return zz();
409  }
410 
411  inline void Tensor::set_xx(const double& val) {
412  xx() = val;
413  }
414 
415  inline void Tensor::set_xy(const double& val) {
416  xy() = val;
417  }
418 
419  inline void Tensor::set_xz(const double& val) {
420  xz() = val;
421  }
422 
423  inline void Tensor::set_yx(const double& val) {
424  yx() = val;
425  }
426 
427  inline void Tensor::set_yy(const double& val) {
428  yy() = val;
429  }
430 
431  inline void Tensor::set_yz(const double& val) {
432  yz() = val;
433  }
434 
435  inline void Tensor::set_zx(const double& val) {
436  zx() = val;
437  }
438 
439  inline void Tensor::set_zy(const double& val) {
440  zy() = val;
441  }
442 
443  inline void Tensor::set_zz(const double& val) {
444  zz() = val;
445  }
446 
447  inline double Tensor::get_xx() const {
448  return xx();
449  }
450 
451  inline double Tensor::get_xy() const {
452  return xy();
453  }
454 
455  inline double Tensor::get_xz() const {
456  return xz();
457  }
458 
459  inline double Tensor::get_yx() const {
460  return yx();
461  }
462 
463  inline double Tensor::get_yy() const {
464  return yy();
465  }
466 
467  inline double Tensor::get_yz() const {
468  return yz();
469  }
470 
471  inline double Tensor::get_zx() const {
472  return zx();
473  }
474 
475  inline double Tensor::get_zy() const {
476  return zy();
477  }
478 
479  inline double Tensor::get_zz() const {
480  return zz();
481  }
482 
483  inline const double&
484  Tensor::operator() (unsigned int i, unsigned int j) const {
485  SafeModeAssert(i < 3, "The component must be in [0, 2] range");
486  SafeModeAssert(j < 3, "The component must be in [0, 2] range");
487  return coord(i,j);
488  }
489 
490  inline double&
491  Tensor::operator() (unsigned int i, unsigned int j) {
492  SafeModeAssert(i < 3, "The component must be in [0, 2] range");
493  SafeModeAssert(j < 3, "The component must be in [0, 2] range");
494  return coord(i,j);
495  }
496 
497  inline double Tensor::trace() const {
498  return xx() + yy() + zz();
499  }
500 
501 
502  //
503  //EXTERNALS OPERATORS
504  //
505  inline
506  std::ostream&
507  operator<< (std::ostream& o, const Tensor& M) {
508  return o << M.xx() << '\t' << M.xy() << '\t' << M.xz() << '\n'
509  << M.yx() << '\t' << M.yy() << '\t' << M.yz() << '\n'
510  << M.zx() << '\t' << M.zy() << '\t' << M.zz() << '\n';
511  }
512 
513  inline Vector
514  operator*(const Tensor &m, const Vector &v) {
515  return Vector(m.xx()*v.x() + m.xy()*v.y() + m.xz()*v.z(),
516  m.yx()*v.x() + m.yy()*v.y() + m.yz()*v.z(),
517  m.zx()*v.x() + m.zy()*v.y() + m.zz()*v.z());
518 
519  }
520 
521  inline Tensor
522  operator*(const double &d, const Tensor &m) {
523  return Tensor(m.xx()*d, m.xy()*d, m.xz()*d,
524  m.yx()*d, m.yy()*d, m.yz()*d,
525  m.zx()*d, m.zy()*d, m.zz()*d);
526  }
527 
528  inline Tensor
529  operator*(const Tensor &m, const double &d) {
530  return d*m;
531  }
532 
533  inline Tensor
534  operator* (const Tensor &m1, const Tensor &m2) {
535  return Tensor(m1.xx()*m2.xx() + m1.xy()*m2.yx() + m1.xz()*m2.zx(),
536  m1.xx()*m2.xy() + m1.xy()*m2.yy() + m1.xz()*m2.zy(),
537  m1.xx()*m2.xz() + m1.xy()*m2.yz() + m1.xz()*m2.zz(),
538 
539  m1.yx()*m2.xx() + m1.yy()*m2.yx() + m1.yz()*m2.zx(),
540  m1.yx()*m2.xy() + m1.yy()*m2.yy() + m1.yz()*m2.zy(),
541  m1.yx()*m2.xz() + m1.yy()*m2.yz() + m1.yz()*m2.zz(),
542 
543  m1.zx()*m2.xx() + m1.zy()*m2.yx() + m1.zz()*m2.zx(),
544  m1.zx()*m2.xy() + m1.zy()*m2.yy() + m1.zz()*m2.zy(),
545  m1.zx()*m2.xz() + m1.zy()*m2.yz() + m1.zz()*m2.zz());
546  }
547 
548  inline Tensor
549  operator+ (const Tensor &m1, const Tensor &m2) {
550  return Tensor(m1.xx()+m2.xx(), m1.xy()+m2.xy(), m1.xz()+m2.xz(),
551  m1.yx()+m2.yx(), m1.yy()+m2.yy(), m1.yz()+m2.yz(),
552  m1.zx()+m2.zx(), m1.zy()+m2.zy(), m1.zz()+m2.zz());
553  }
554 
555  inline Tensor
556  operator- (const Tensor &m1, const Tensor &m2) {
557  return Tensor(m1.xx()-m2.xx(), m1.xy()-m2.xy(), m1.xz()-m2.xz(),
558  m1.yx()-m2.yx(), m1.yy()-m2.yy(), m1.yz()-m2.yz(),
559  m1.zx()-m2.zx(), m1.zy()-m2.zy(), m1.zz()-m2.zz());
560  }
561 
562  inline bool
563  operator== (const Tensor &m1, const Tensor &m2) {
564  Tensor t(m1.xx()-m2.xx(), m1.xy()-m2.xy(), m1.xz()-m2.xz(),
565  m1.yx()-m2.yx(), m1.yy()-m2.yy(), m1.yz()-m2.yz(),
566  m1.zx()-m2.zx(), m1.zy()-m2.zy(), m1.zz()-m2.zz());
567  return t.is_null();
568  }
569 
570  inline void
571  Tensor::operator+= (const Tensor &m1) {
572  Tensor& m = *this;
573  m.xx() += m1.xx();
574  m.yy() += m1.yy();
575  m.zz() += m1.zz();
576  m.xy() += m1.xy();
577  m.yx() += m1.yx();
578  m.xz() += m1.xz();
579  m.zx() += m1.zx();
580  m.yz() += m1.yz();
581  m.zy() += m1.zy();
582  }
583 
584  inline void
585  Tensor::operator/= (double d) {
586  Tensor& m = *this;
587  m.xx() /= d;
588  m.yy() /= d;
589  m.zz() /= d;
590  m.xy() /= d;
591  m.yx() /= d;
592  m.xz() /= d;
593  m.zx() /= d;
594  m.yz() /= d;
595  m.zy() /= d;
596  }
597 
598 #endif
599  }
600 }
601 
602 
603 
604 #endif
605 
#define SafeModeAssert(condition, message)
Definition: Macro.hpp:47
Definition: Frame.hpp:68
Definition: Quaternion.hpp:54
Definition: Tensor.hpp:62
static const int N
Definition: Tensor.hpp:66
void set_xz(const double &)
double get_yy() const
const double & zz() const
const double & operator()(unsigned int i, unsigned int j) const
double get_xy() const
double trace() const
void operator+=(const Tensor &m)
const double & yz() const
Tensor & operator=(const Tensor &m)
void set_xy(const double &)
void set_xx(const double &)
void serialize(Archive &ar, const unsigned int)
const double & zy() const
Tensor transpose() const
const double & xy() const
const double & zx() const
Eigen::Matrix< double, 3, 3 > coord
Definition: Tensor.hpp:156
static std::string class_ID()
Definition: Tensor.hpp:65
double get_zx() const
double get_xz() const
const double & yx() const
double get_yz() const
void set_yy(const double &)
const double & xz() const
double get_yx() const
Tensor inverse() const
const double & val() const
void operator/=(double d)
void set_yz(const double &)
void set_zy(const double &)
friend class boost::serialization::access
Definition: Tensor.hpp:151
double get_zz() const
Tensor(const Tensor &m)
double determinant() const
void eigen_value(Vector &v, Quaternion &q) const
Definition: Tensor.cpp:57
void set_zz(const double &)
double get_xx() const
Tensor(double, double, double, double, double, double, double, double, double)
void set_zx(const double &)
double get_zy() const
bool is_null() const
void set_yx(const double &)
const double & xx() const
const double & yy() const
Definition: Vector.hpp:75
SymTensor operator+(const SymTensor &m1, const SymTensor &m2)
SymTensor operator-(const SymTensor &m1, const SymTensor &m2)
std::ostream & operator<<(std::ostream &, const EulerAngle &)
SymTensor operator/(const SymTensor &m, const double &d)
Vector operator*(const SymTensor &m, const Vector &v)
bool operator==(const EulerAngle &, const EulerAngle &)
Definition: Common.hpp:198
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t t(t+t)") define_sfop3(16