GranOO  3.0
A robust and versatile workbench to build 3D dynamic simulations based on the Discrete Element Method
SymTensor.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_SymTensor_hpp_
31 #define _GranOO_Geom_SymTensor_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 #include "GranOO3/Geom/Tensor.hpp"
42 
43 
44 namespace GranOO3
45 {
46  namespace Geom
47  {
48 
49  class Frame;
50  class SymTensor;
51 
52  std::ostream& operator<< (std::ostream& o, const SymTensor& m);
53  Vector operator* (const SymTensor &m, const Vector &v);
54  SymTensor operator* (const double &d, const SymTensor &m);
55  SymTensor operator* (const SymTensor &m, const double &d);
56  double operator* (const SymTensor &m1, const SymTensor &m2); // dot product
57  Tensor operator* (const SymTensor &m1, const Tensor &m2);
58  Tensor operator* (const Tensor &m1, const SymTensor &m2);
59  SymTensor operator/ (const SymTensor &m, const double &d);
60  SymTensor operator- (const SymTensor &m1, const SymTensor &m2);
61  SymTensor operator+ (const SymTensor &m1, const SymTensor &m2);
62  bool operator==(const SymTensor &m1, const SymTensor &m2);
63 
64  // A tensor that uses the Voigt's notation for symetric tensor //
65  // The tensor is stored as a 6 components vector in the following //
66  // order : xx, yy, zz, xy, xz, yz //
67  class SymTensor
68  {
69  public:
70  // Usefull for internal use only, NOT DOCUMENTED !
71  static std::string class_ID() {return "SymTensor";}
72  static const int N = 6;
73  static const SymTensor id;
74 
75  public:
76  // Constructors and destructor
78  SymTensor(const SymTensor& m);
79  SymTensor(const SymTensor& m, const Frame& from, const Frame& to);
80 
81  SymTensor(double, double, double,
82  double, double, double);
83 
84  // Internal operators
87  void operator+= (const SymTensor& m);
88  void operator/= (double d);
89 
90  // Usefull methods
91  void clear();
92  void eigen_value(Vector& v, Quaternion& q) const;
93  bool is_null() const;
94  bool is_nan() const;
95 
96  // Invariants
97  double trace() const;
98  double invariant1() const;
99  double invariant2() const;
100  double invariant3() const;
101 
102 
103  // Component
104  double & xx();
105  double & xy();
106  double & xz();
107 
108  double & yx();
109  double & yy();
110  double & yz();
111 
112  double & zx();
113  double & zy();
114  double & zz();
115 
116  const double & xx() const;
117  const double & xy() const;
118  const double & xz() const;
119 
120  const double & yx() const;
121  const double & yy() const;
122  const double & yz() const;
123 
124  const double & zx() const;
125  const double & zy() const;
126  const double & zz() const;
127 
128 
129  // Component (for python wrapper)
130  void set_xx(const double&);
131  void set_xy(const double&);
132  void set_xz(const double&);
133  void set_yx(const double&);
134  void set_yy(const double&);
135  void set_yz(const double&);
136  void set_zx(const double&);
137  void set_zy(const double&);
138  void set_zz(const double&);
139 
140  // Component (for python wrapper)
141  double get_xx() const;
142  double get_xy() const;
143  double get_xz() const;
144  double get_yx() const;
145  double get_yy() const;
146  double get_yz() const;
147  double get_zx() const;
148  double get_zy() const;
149  double get_zz() const;
150 
151  template <typename Axis> double& val();
152  template <typename Axis> const double& val() const;
153 
154  const double & operator() (unsigned int i, unsigned int j) const;
155  double& operator() (unsigned int i, unsigned int j);
156 
157  const double & operator() (unsigned int i) const;
158  double& operator() (unsigned int i);
159 
160  private:
161  //BOOST SERIALIZATION
163  template<class Archive>
164  void serialize(Archive & ar, const unsigned int);
165 
166  public:
167  Eigen::Matrix<double, 6, 1> coord;
168  };
169 
170 #ifndef DOXYGEN_SHOULD_SKIP_THIS
171 
172  template<class Archive>
173  void SymTensor::serialize(Archive & ar, const unsigned int ) {
174  ar & xx(); ar & yy(); ar & zz();
175  ar & xy(); ar & xz(); ar & yz();
176  }
177 
178  inline
179  SymTensor::SymTensor(const SymTensor& M)
180  : coord(M.coord) {
181  }
182 
183  inline
184  SymTensor::SymTensor(double XX, double YY, double ZZ,
185  double XY, double XZ, double YZ)
186  : coord(){
187  coord(0) = XX;
188  coord(1) = YY;
189  coord(2) = ZZ;
190  coord(3) = XY;
191  coord(4) = XZ;
192  coord(5) = YZ;
193  }
194 
195  inline
197  : coord() {
198  }
199 
200  // Operator
201  inline SymTensor
202  operator/(const SymTensor &m, const double &d) {
203  return SymTensor(m.xx()/d, m.yy()/d, m.zz()/d,
204  m.xy()/d, m.xz()/d, m.yz()/d);
205  }
206 
207  inline SymTensor &
208  SymTensor::operator=(const SymTensor& M) {
209  coord = M.coord;
210  return *this;
211  }
212 
213 
214  inline SymTensor &
215  SymTensor::operator=(const Tensor& M) {
216  xx() = M.xx();
217  yy() = M.yy();
218  zz() = M.zz();
219 
220  xy() = M.xy();
221  xz() = M.xz();
222  yz() = M.yz();
223 
224  return *this;
225  }
226 
227 
228  inline void
229  SymTensor::clear() {
230  xx() = xy() = xz() = 0.;
231  yx() = yy() = yz() = 0.;
232  zx() = zy() = zz() = 0.;
233  }
234 
235  inline bool
236  SymTensor::is_null() const {
237  return (xy() == 0. && xz() == 0. && xz() == 0. &&
238  yy() == 0. && yz() == 0. && yz() == 0. &&
239  zy() == 0. && zz() == 0. && zz() == 0);
240  }
241 
242  inline bool
243  SymTensor::is_nan() const {
244  if (xx()!=xx())
245  return true;
246  if (yy()!=yy())
247  return true;
248  if (zz()!=zz())
249  return true;
250 
251  if (xy()!=xy())
252  return true;
253  if (xz()!=xz())
254  return true;
255  if (yz()!=yz())
256  return true;
257 
258  return false;
259  }
260 
261  inline double & SymTensor::xx() {
262  return coord(0);
263  }
264 
265  inline double & SymTensor::xy() {
266  return coord(3);
267  }
268 
269  inline double & SymTensor::xz() {
270  return coord(4);
271  }
272 
273  inline double & SymTensor::yx() {
274  return coord(3);
275  }
276 
277  inline double & SymTensor::yy() {
278  return coord(1);
279  }
280 
281  inline double & SymTensor::yz() {
282  return coord(5);
283  }
284 
285  inline double & SymTensor::zx() {
286  return coord(4);
287  }
288 
289  inline double & SymTensor::zy() {
290  return coord(5);
291  }
292 
293  inline double & SymTensor::zz() {
294  return coord(2);
295  }
296 
297  inline const double & SymTensor::xx() const {
298  return coord(0);
299  }
300 
301  inline const double & SymTensor::xy() const {
302  return coord(3);
303  }
304 
305  inline const double & SymTensor::xz() const {
306  return coord(4);
307  }
308 
309  inline const double & SymTensor::yx() const {
310  return coord(3);
311  }
312 
313  inline const double & SymTensor::yy() const {
314  return coord(1);
315  }
316 
317  inline const double & SymTensor::yz() const {
318  return coord(5);
319  }
320 
321  inline const double & SymTensor::zx() const {
322  return coord(4);
323  }
324 
325  inline const double & SymTensor::zy() const {
326  return coord(5);
327  }
328 
329  inline const double & SymTensor::zz() const {
330  return coord(2);
331  }
332 
333  template<> inline double& SymTensor::val<XX>() {
334  return xx();
335  }
336 
337  template<> inline double& SymTensor::val<XY>() {
338  return xy();
339  }
340 
341  template<> inline double& SymTensor::val<XZ>() {
342  return xz();
343  }
344 
345  template<> inline double& SymTensor::val<YX>() {
346  return yx();
347  }
348 
349  template<> inline double& SymTensor::val<YY>() {
350  return yy();
351  }
352 
353  template<> inline double& SymTensor::val<YZ>() {
354  return yz();
355  }
356 
357  template<> inline double& SymTensor::val<ZX>() {
358  return zx();
359  }
360 
361  template<> inline double& SymTensor::val<ZY>() {
362  return zy();
363  }
364 
365  template<> inline double& SymTensor::val<ZZ>() {
366  return zz();
367  }
368 
369  template<> inline const double& SymTensor::val<XX>() const {
370  return xx();
371  }
372 
373  template<> inline const double& SymTensor::val<XY>() const {
374  return xy();
375  }
376 
377  template<> inline const double& SymTensor::val<XZ>() const {
378  return xz();
379  }
380 
381  template<> inline const double& SymTensor::val<YX>() const {
382  return yx();
383  }
384 
385  template<> inline const double& SymTensor::val<YY>() const {
386  return yy();
387  }
388 
389  template<> inline const double& SymTensor::val<YZ>() const {
390  return yz();
391  }
392 
393  template<> inline const double& SymTensor::val<ZX>() const {
394  return zx();
395  }
396 
397  template<> inline const double& SymTensor::val<ZY>() const {
398  return zy();
399  }
400 
401  template<> inline const double& SymTensor::val<ZZ>() const {
402  return zz();
403  }
404 
405  inline void SymTensor::set_xx(const double& val) {
406  xx() = val;
407  }
408 
409  inline void SymTensor::set_xy(const double& val) {
410  xy() = val;
411  }
412 
413  inline void SymTensor::set_xz(const double& val) {
414  xz() = val;
415  }
416 
417  inline void SymTensor::set_yx(const double& val) {
418  yx() = val;
419  }
420 
421  inline void SymTensor::set_yy(const double& val) {
422  yy() = val;
423  }
424 
425  inline void SymTensor::set_yz(const double& val) {
426  yz() = val;
427  }
428 
429  inline void SymTensor::set_zx(const double& val) {
430  zx() = val;
431  }
432 
433  inline void SymTensor::set_zy(const double& val) {
434  zy() = val;
435  }
436 
437  inline void SymTensor::set_zz(const double& val) {
438  zz() = val;
439  }
440 
441  inline double SymTensor::get_xx() const {
442  return xx();
443  }
444 
445  inline double SymTensor::get_xy() const {
446  return xy();
447  }
448 
449  inline double SymTensor::get_xz() const {
450  return xz();
451  }
452 
453  inline double SymTensor::get_yx() const {
454  return yx();
455  }
456 
457  inline double SymTensor::get_yy() const {
458  return yy();
459  }
460 
461  inline double SymTensor::get_yz() const {
462  return yz();
463  }
464 
465  inline double SymTensor::get_zx() const {
466  return zx();
467  }
468 
469  inline double SymTensor::get_zy() const {
470  return zy();
471  }
472 
473  inline double SymTensor::get_zz() const {
474  return zz();
475  }
476 
477  inline const double&
478  SymTensor::operator() (unsigned int i, unsigned int j) const {
479  SafeModeAssert(i < 3, "The component must be in [0, 2] range");
480  SafeModeAssert(j < 3, "The component must be in [0, 2] range");
481  return coord(i,j);
482  }
483 
484  inline double&
485  SymTensor::operator() (unsigned int i, unsigned int j) {
486  SafeModeAssert(i < 3, "The component must be in [0, 2] range");
487  SafeModeAssert(j < 3, "The component must be in [0, 2] range");
488  return coord(i,j);
489  }
490 
491 
492  inline const double&
493  SymTensor::operator() (unsigned int i) const {
494  SafeModeAssert(i < 5, "The component must be in [0, 5] range");
495  return coord(i);
496  }
497 
498  inline double&
499  SymTensor::operator() (unsigned int i) {
500  SafeModeAssert(i < 5, "The component must be in [0, 2] range");
501  return coord(i);
502  }
503 
504 
505  inline double SymTensor::trace() const {
506  return xx() + yy() + zz();
507  }
508 
509 
510  inline double SymTensor::invariant1() const {
511  return xx() + yy() + zz();
512  }
513 
514  inline double SymTensor::invariant2() const {
515  return xx()*yy() + yy()*zz() + xx()*zz() - xy()*xy() - yz()*yz() - xz()*xz();
516  }
517 
518  inline double SymTensor::invariant3() const {
519  return xx()*yy()*zz() + 2*xy()*yz()*xz() - xy()*xy()*zz() - yz()*yz()*xx() - xz()*xz()*yy();
520  }
521 
522 
523  //
524  //EXTERNALS OPERATORS
525  //
526  inline
527  std::ostream&
528  operator<< (std::ostream& o, const SymTensor& M) {
529  return o << M.xx() << '\t' << M.yy() << '\t' << M.zz() << '\n'
530  << M.xy() << '\t' << M.xz() << '\t' << M.yz() << '\n';
531  }
532 
533  inline Vector
534  operator*(const SymTensor &m, const Vector &v) {
535  return Vector(m.xx()*v.x() + m.xy()*v.y() + m.xz()*v.z(),
536  m.yx()*v.x() + m.yy()*v.y() + m.yz()*v.z(),
537  m.zx()*v.x() + m.zy()*v.y() + m.zz()*v.z());
538 
539  }
540 
541  inline SymTensor
542  operator*(const double &d, const SymTensor &m) {
543  return SymTensor(m.xx()*d, m.yy()*d, m.zz()*d,
544  m.xy()*d, m.xz()*d, m.yz()*d);
545  }
546 
547  inline SymTensor
548  operator*(const SymTensor &m, const double &d) {
549  return d*m;
550  }
551 
552  inline double
553  operator* (const SymTensor &m1, const SymTensor &m2) {
554  return (m1.xx()*m2.xx() + m1.yy()*m2.yy() + m1.zz()*m2.zz() +
555  m1.xy()*m2.xy() + m1.xz()*m2.xz() + m1.yz()*m2.yz());
556  }
557 
558  inline Tensor
559  operator* (const SymTensor &m1, const Tensor &m2) {
560  return Tensor(m1.xx()*m2.xx() + m1.xy()*m2.yx() + m1.xz()*m2.zx(),
561  m1.xx()*m2.xy() + m1.xy()*m2.yy() + m1.xz()*m2.zy(),
562  m1.xx()*m2.xz() + m1.xy()*m2.yz() + m1.xz()*m2.zz(),
563 
564  m1.yx()*m2.xx() + m1.yy()*m2.yx() + m1.yz()*m2.zx(),
565  m1.yx()*m2.xy() + m1.yy()*m2.yy() + m1.yz()*m2.zy(),
566  m1.yx()*m2.xz() + m1.yy()*m2.yz() + m1.yz()*m2.zz(),
567 
568  m1.zx()*m2.xx() + m1.zy()*m2.yx() + m1.zz()*m2.zx(),
569  m1.zx()*m2.xy() + m1.zy()*m2.yy() + m1.zz()*m2.zy(),
570  m1.zx()*m2.xz() + m1.zy()*m2.yz() + m1.zz()*m2.zz());
571  }
572 
573  inline Tensor
574  operator* (const Tensor &m1, const SymTensor &m2) {
575  return Tensor(m1.xx()*m2.xx() + m1.xy()*m2.yx() + m1.xz()*m2.zx(),
576  m1.xx()*m2.xy() + m1.xy()*m2.yy() + m1.xz()*m2.zy(),
577  m1.xx()*m2.xz() + m1.xy()*m2.yz() + m1.xz()*m2.zz(),
578 
579  m1.yx()*m2.xx() + m1.yy()*m2.yx() + m1.yz()*m2.zx(),
580  m1.yx()*m2.xy() + m1.yy()*m2.yy() + m1.yz()*m2.zy(),
581  m1.yx()*m2.xz() + m1.yy()*m2.yz() + m1.yz()*m2.zz(),
582 
583  m1.zx()*m2.xx() + m1.zy()*m2.yx() + m1.zz()*m2.zx(),
584  m1.zx()*m2.xy() + m1.zy()*m2.yy() + m1.zz()*m2.zy(),
585  m1.zx()*m2.xz() + m1.zy()*m2.yz() + m1.zz()*m2.zz());
586  }
587 
588 
589 
590 
591  inline SymTensor
592  operator+ (const SymTensor &m1, const SymTensor &m2) {
593  return SymTensor(m1.xx()+m2.xx(), m1.yy()+m2.yy(), m1.zz()+m2.zz(),
594  m1.xy()+m2.xy(), m1.xz()+m2.xz(), m1.yz()+m2.yz());
595  }
596 
597  inline SymTensor
598  operator- (const SymTensor &m1, const SymTensor &m2) {
599  return SymTensor(m1.xx()-m2.xx(), m1.yy()-m2.yy(), m1.zz()-m2.zz(),
600  m1.xy()-m2.xy(), m1.xz()-m2.xz(), m1.yz()-m2.yz());
601  }
602 
603  inline bool
604  operator== (const SymTensor &m1, const SymTensor &m2) {
605  SymTensor t(m1.xx()-m2.xx(), m1.yy()-m2.yy(), m1.zz()-m2.zz(),
606  m1.xy()-m2.xy(), m1.xz()-m2.xz(), m1.yz()-m2.yz());
607  return t.is_null();
608  }
609 
610  inline void
611  SymTensor::operator+= (const SymTensor &m1) {
612  SymTensor& m = *this;
613  m.xx() += m1.xx();
614  m.yy() += m1.yy();
615  m.zz() += m1.zz();
616  m.xy() += m1.xy();
617  m.xz() += m1.xz();
618  m.yz() += m1.yz();
619  }
620 
621  inline void
622  SymTensor::operator/= (double d) {
623  SymTensor& m = *this;
624  m.xx() /= d;
625  m.yy() /= d;
626  m.zz() /= d;
627  m.xy() /= d;
628  m.xz() /= d;
629  m.yz() /= d;
630  }
631 
632 #endif
633  }
634 }
635 
636 
637 
638 #endif
639 
#define SafeModeAssert(condition, message)
Definition: Macro.hpp:47
Definition: Frame.hpp:68
Definition: Quaternion.hpp:54
Definition: SymTensor.hpp:68
void set_yz(const double &)
void set_yy(const double &)
const double & yz() const
const double & operator()(unsigned int i, unsigned int j) const
void operator+=(const SymTensor &m)
const double & zz() const
void eigen_value(Vector &v, Quaternion &q) const
Definition: SymTensor.cpp:59
void serialize(Archive &ar, const unsigned int)
SymTensor(double, double, double, double, double, double)
double invariant2() const
const double & xz() const
void set_zy(const double &)
static const int N
Definition: SymTensor.hpp:72
void set_zz(const double &)
void set_yx(const double &)
SymTensor & operator=(const SymTensor &m)
const double & xy() const
void operator/=(double d)
static const SymTensor id
Definition: SymTensor.hpp:73
SymTensor(const SymTensor &m)
const double & xx() const
const double & yx() const
const double & zy() const
const double & zx() const
const double & yy() const
void set_xx(const double &)
void set_zx(const double &)
void set_xz(const double &)
const double & val() const
double invariant1() const
friend class boost::serialization::access
Definition: SymTensor.hpp:162
void set_xy(const double &)
static std::string class_ID()
Definition: SymTensor.hpp:71
double invariant3() const
SymTensor & operator=(const Tensor &m)
Eigen::Matrix< double, 6, 1 > coord
Definition: SymTensor.hpp:167
Definition: Tensor.hpp:62
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