NeoPZ
TPZTensor.h
Go to the documentation of this file.
1 // $Id: TPZTensor.h,v 1.28 2010-12-04 20:41:28 diogo Exp $
2 
3 #ifndef TPZTENSOR_H
4 #define TPZTENSOR_H
5 
6 #include "pzmanvector.h"
7 #include "pzfmatrix.h"
8 #include "pzextractval.h"
9 #include <iostream>
10 #include <algorithm>
11 #include "fadType.h"
12 #include <math.h>
13 #include <array>
14 #include <algorithm>
15 #include <functional>
16 #include <pzvec_extras.h>
17 
18 #include "pzlog.h"
19 #include "TPZAssert.h"
20 #ifndef WIN32
21 #include <fenv.h>//NAN DETECTOR
22 #ifndef MACOSX
23 #pragma STDC FENV_ACCESS ON
24 #endif
25 #endif
26 
27 #define _XX_ 0
28 #define _XY_ 1
29 #define _XZ_ 2
30 #define _YY_ 3
31 #define _YZ_ 4
32 #define _ZZ_ 5
33 
34 #ifdef LOG4CXX
35 static LoggerPtr loggerr(Logger::getLogger("logtensor"));
36 #endif
37 
41 template <class T>
42 class TPZTensor : public TPZSavable {
43 public:
44 
45  struct TPZDecomposed {
46  unsigned int fDistinctEigenvalues;
50  TPZManVector<TPZTensor<T>, 3> fEigentensors; // Tensors of the spectral decomposition. If there is a repeated eigenvalue, all its occurrences are filled with the same tensor.
51 
52  TPZDecomposed() : fDistinctEigenvalues(0), fGeometricMultiplicity(3, 0), fEigenvalues(3, 0.), fEigenvectors(3), fEigentensors(3) {
53  }
54 
55  TPZDecomposed(const TPZDecomposed &copy) : fDistinctEigenvalues(copy.fDistinctEigenvalues), fGeometricMultiplicity(copy.fGeometricMultiplicity), fEigenvalues(copy.fEigenvalues), fEigenvectors(copy.fEigenvectors), fEigentensors(copy.fEigentensors) {
56  }
57 
59  fDistinctEigenvalues = copy.fDistinctEigenvalues;
60  fGeometricMultiplicity = copy.fGeometricMultiplicity;
61  fEigenvalues = copy.fEigenvalues;
62  fEigenvectors = copy.fEigenvectors;
63  fEigentensors = copy.fEigentensors;
64  return *this;
65  }
66 
67  TPZDecomposed(const TPZTensor<T> &source) : fDistinctEigenvalues(0), fGeometricMultiplicity(3, 0), fEigenvalues(3, 0.), fEigenvectors(3), fEigentensors(3) {
68  source.EigenSystem(*this);
69  }
70 
71  void Print(std::ostream &out) const {
72 #ifdef PZDEBUG
73  if (fDistinctEigenvalues == 0 || fDistinctEigenvalues > 3) {
74  std::stringstream str;
75  str << "TPZTensor::Decomposed::Print Invalid number of distinct eigenvalues: " << fDistinctEigenvalues << std::endl;
76  LOGPZ_DEBUG(loggerr, str.str());
77  }
78 #endif
79  out << "TPZTensor::Decomposed Eigenvalues (" << fDistinctEigenvalues << " distinct):" << std::endl;
80  unsigned int vIndex = 0;
81  unsigned int lambda = 0;
82  do {
83  const unsigned int geoMult(fGeometricMultiplicity[lambda]);
84 #ifdef PZDEBUG
85  if (geoMult == 0 || geoMult > 3) {
86  std::stringstream str;
87  str << "TPZTensor::Decomposed::Print Invalid geometric multiplicity (" << geoMult << ") for eigenvalue " << fEigenvalues[lambda] << std::endl;
88  LOGPZ_DEBUG(loggerr, str.str());
89  }
90 #endif
91  out << "Eigenvalue: " << fEigenvalues[lambda] << " (" << geoMult << " time" << (geoMult > 1 ? "s" : "") << ")" << std::endl;
92  out << "Eigenvector" << (geoMult > 1 ? "s" : "") << ":" << std::endl;
93  if (fEigenvectors.size() == 0 || fEigenvectors[0].size() == 0) {
94  out << " Not computed." << std::endl;
95  } else {
96  for (unsigned int v = 0; v < geoMult; ++v) {
97  out << fEigenvectors[vIndex][0] << " ";
98  out << fEigenvectors[vIndex][1] << " ";
99  out << fEigenvectors[vIndex][2] << std::endl;
100  ++vIndex;
101  }
102  }
103  out << "Eigentensor:" << std::endl;
104  fEigentensors[lambda].Print(out);
105  out << std::endl;
106  lambda += geoMult; // Go to next distinct eigenvalue
107 #ifdef PZDEBUG
108  if (lambda > 3) {
109  std::stringstream str;
110  str << "TPZTensor::Decomposed::Print Total geometric multiplicity greater than expected!" << std::endl;
111  LOGPZ_ERROR(loggerr, str.str());
112  }
113 #endif
114  } while (lambda < 3);
115  }
119 
121  static int NumCasesCheckConv() {
122  return 3;
123  }
124 
125  static STATE gEigval[3];
127 
128  static void TangentCheckConv(TPZFMatrix<STATE> &state, TPZFMatrix<STATE> &tangent, int icase) {
130  for (int i = 0; i < 6; i++) {
131  obj[i] = state(i);
132  }
134  switch (icase) {
135  case 0:
136  case 1:
137  case 2:
138  {
139  tangent.Resize(1, 9);
140  for (int i = 0; i < 3; i++) {
141  gEigval[i] = objdec.fEigenvalues[i];
142  }
143  for (int j = 0; j < 6; j++) {
144  tangent(0, j) = objdec.fEigentensors[icase][j];
145  tangent(0, 6) = objdec.fEigentensors[icase].XY();
146  tangent(0, 7) = objdec.fEigentensors[icase].XZ();
147  tangent(0, 8) = objdec.fEigentensors[icase].YZ();
148  }
149  STATE sum = 0., sum2 = 0.;
150  for (int i = 0; i < 9; i++) {
151  sum += tangent(0, i) * tangent(0, i);
152  }
153  sum2 = tangent(0, _XX_) + tangent(0, _YY_) + tangent(0, _ZZ_);
154  tangent.Print("tangent");
155  std::cout << "sum2 = " << sum2 << std::endl;
156  std::cout << "sum = " << sum << std::endl;
157  }
158  break;
159  default:
160  break;
161  }
162  }
164 
165  static void ResidualCheckConv(TPZFMatrix<STATE> &state, TPZFMatrix<STATE> &residual, int icase) {
167  for (int i = 0; i < 6; i++) {
168  obj[i] = state(i);
169  }
170  obj[_XY_] = obj[_XY_]*0.5 + 0.5 * state(6);
171  obj[_XZ_] = (obj[_XZ_] + state(7))*0.5;
172  obj[_YZ_] = (obj[_YZ_] + state(8))*0.5;
174  residual.Resize(1, 1);
175  switch (icase) {
176  case 0:
177  case 1:
178  case 2:
179  {
180  residual(0, 0) = objdec.fEigenvalues[icase];
181  int numequal = 1;
182  for (int i = 0; i < 3; i++) {
183  if (i == icase) {
184  continue;
185  }
186  if (gEigval[i] == gEigval[icase]) {
187  numequal++;
188  residual(0) += objdec.fEigenvalues[i];
189  }
190  }
191  residual(0) /= numequal;
192  }
193  break;
194 
195  default:
196  break;
197  }
198  }
199 
200  void ComputeJ2(T & J2) {
201  T sig1, sig2, sig3;
202  sig1 = this->fEigenvalues[0];
203  sig2 = this->fEigenvalues[1];
204  sig3 = this->fEigenvalues[2];
205  J2 = (pow(sig1 + (-sig1 - sig2 - sig3) / 3., 2) + pow(sig2 + (-sig1 - sig2 - sig3) / 3., 2) + pow((-sig1 - sig2 - sig3) / 3. + sig3, 2)) / 2.;
206  }
207 
208  void ComputeJ3(T & J3) {
209  T sig1, sig2, sig3, s1, s2, s3, temp;
210  sig1 = this->fEigenvalues[0];
211  sig2 = this->fEigenvalues[1];
212  sig3 = this->fEigenvalues[2];
213  s1 = sig1 - (1. / 3.)*(sig1 + sig2 + sig3);
214  s2 = sig2 - (1. / 3.)*(sig1 + sig2 + sig3);
215  s3 = sig3 - (1. / 3.)*(sig1 + sig2 + sig3);
216  temp = (1. / 3.)*(s1 * s1 * s1 + s2 * s2 * s2 + s3 * s3 * s3);
217  J3 = temp;
218  }
219 
220  void ComputeI1(T &I1) {
221  I1 = this->fEigenvalues[0] + this->fEigenvalues[1] + this->fEigenvalues[2];
222  }
223 
224  void ApplyStrainComputeElasticStress(TPZTensor<T> &Stress, REAL &K, REAL & G) {
225  const T sig1 = this->fEigenvalues[0];
226  const T sig2 = this->fEigenvalues[1];
227  const T sig3 = this->fEigenvalues[2];
228  const T trace = sig1 + sig2 + sig3;
229  const T trace_3 = trace / 3.;
230 
231  TPZTensor<T> SigVol;
232  SigVol.XX() = SigVol.YY() = SigVol.ZZ() = K * trace;
233 
234  Stress.XX() = sig1 - trace_3;
235  Stress.YY() = sig2 - trace_3;
236  Stress.ZZ() = sig3 - trace_3;
237  Stress *= (2 * G);
238  Stress += SigVol;
239  }
240  };
241 
245  TPZTensor() : fData(6, T(0.)) {
246  }
247 
251  TPZTensor(const T & Init) : fData(6, Init) {
252  }
253 
257  TPZTensor(const TPZTensor<T> & source) : fData(source.fData) {
258  }
259 
263  TPZTensor(const TPZDecomposed &eigensystem) : fData(6, T(0.)) {
264  unsigned int i;
265  for (i = 0; i < 3; i += eigensystem.fGeometricMultiplicity[i]) {
266  Add(eigensystem.fEigentensors[i], eigensystem.fEigenvalues[i]);
267  }
268 #ifdef PZDEBUG
269  if (i != 3) {
270  DebugStop();
271  }
272 #endif
273  }
274 
275  int ClassId() const override {
276  return Hash("TPZTensor") ^ ClassIdOrHash<T>() << 1;
277  }
278 
280  void Write(TPZStream &buf, int withclassid) const override;
281 
283  void Read(TPZStream &buf, void *context) override;
284 
285  operator TPZFMatrix<T>() const {
286  TPZFMatrix<T> result(3, 3);
287  result(0, 0) = XX();
288  result(0, 1) = result(1, 0) = XY();
289  result(0, 2) = result(2, 0) = XZ();
290  result(1, 1) = YY();
291  result(1, 2) = result(2, 1) = YZ();
292  result(2, 2) = ZZ();
293  return result;
294  }
295 
296  TPZTensor(const TPZFMatrix<T> &input) : fData(6, 0.) {
297 #ifdef PZDEBUG
298  if (input.Rows() != 3 || input.Cols() != 3) {
299  DebugStop();
300  }
301  T tol;
302  ZeroTolerance(tol);
303  for (int i = 0; i < 3; i++) {
304  for (int j = 0; j < 3; j++) {
305  if (fabs(TPZExtractVal::val(input.GetVal(i, j) - input.GetVal(j, i))) > tol) {
306  std::cout << "diff = " << input.GetVal(i, j) - input.GetVal(j, i) << std::endl;
307  DebugStop();
308  }
309  }
310  }
311 #endif
312  fData[_XX_] = input.GetVal(0, 0);
313  fData[_XY_] = input.GetVal(0, 1);
314  fData[_XZ_] = input.GetVal(0, 2);
315  fData[_YY_] = input.GetVal(1, 1);
316  fData[_YZ_] = input.GetVal(1, 2);
317  fData[_ZZ_] = input.GetVal(2, 2);
318  }
322  void Print(std::ostream &out) const;
323 
327  const TPZTensor<T> & operator=(const TPZTensor<T> &source);
328 
332  const TPZTensor<T> & operator+=(const TPZTensor<T> &source);
333 
337  const TPZTensor<T> & operator-=(const TPZTensor<T> &source);
338 
342  const TPZTensor<T> & operator*=(const T &multipl);
343 
347  TPZTensor<T> operator+(const TPZTensor<T> &source) const;
348 
352  TPZTensor<T> operator-(const TPZTensor<T> &source) const;
353 
357  TPZTensor<T> operator*(const T &multipl) const;
358 
359  T &operator()(const int64_t row, const int64_t col) {
360  if (row <= col) {
361  return fData[row * (5 - row) / 2 + col];
362  } else {
363  return fData[col * (5 - col) / 2 + row];
364  }
365  }
366 
367  T &operator()(const int64_t row, const int64_t col) const {
368  if (row <= col) {
369  return fData[row * (5 - row) / 2 + col];
370  } else {
371  return fData[col * (5 - col) / 2 + row];
372  }
373  }
374 
379  template <class TBASE>
380  void Identity_T(TBASE &);
381 
382  //Specialization for TBASE = REAL
383  void Identity();
384 
390  template < class T1, class T2 >
391  void Add(const TPZTensor< T1 > & tensor, const T2 & constant);
392 
398  template < class T1, class T2>
399  void Multiply(const T1 & multipl, const T2 & constant);
400 
406  void Multiply(const TPZTensor<T> tensor, TPZTensor<T> & resp)const;
407 
412  template < class T2>
413  void Scale(const T2 & constant);
414 
418  void Zero();
419 
424  void EigenVector(TPZVec<TPZVec<T> > & eigVec) const;
425 
430  // void EigenValue(TPZVec<T> & eigVal) const;
431 
437  T J2() const;
438 
442  void dJ2(TPZTensor<T> & Tangent) const;
443 
447  T Det() const;
448 
452  void dDet(TPZTensor<T> &grad) const;
453 
457  T I1() const;
458 
462  T I2() const;
463 
467  T I3() const;
468 
469  T Norm() const;
470 
475  void S(TPZTensor<T> &s) const;
476 
480  T J3() const;
481 
485  void dJ3(TPZTensor<T> &deriv) const;
486 
490  void Adjust(TPZVec<T> &sigIJ, TPZTensor<T> &result) const {
491  TPZTensor<T> S;
492  this->S(S);
493  TPZTensor<T> Diag;
494  Diag.Identity();
495  Diag *= sigIJ[0] / T(3.);
496  T J2 = this->J2();
497  T sqj2 = sqrt(J2);
498  REAL sqj2val = TPZExtractVal::val(sqj2);
499  T ratio;
500  if (fabs(sqj2val) > 1.e-6) {
501  ratio = sigIJ[1] / sqj2;
502  } else {
503  ratio = T(1.);
504  }
505  S *= ratio;
506  S += Diag;
507  result = S;
508 
509  }
510 
514  void HaighWestergaard(T &LodeAngle, T &qsi, T &rho) const;
515 
519  void HaighWestergaard(T &LodeAngle, T &qsi, T &rho, TPZTensor<T> & dLodeAngle, TPZTensor<T> & dQsi, TPZTensor<T> & dRho) const;
520 
521  void ComputeEigenvalues(TPZDecomposed &eigensystem, const bool compute_eigenvectors = false) const;
522 
523 
527  void Eigenvalue(TPZTensor<T> &eigenval, TPZTensor<T> &dSigma1, TPZTensor<T> &dSigma2, TPZTensor<T> &dSigma3)const;
528 
532  void Lodeangle(TPZTensor<T> &GradLode, T &Lode)const;
533 
534  bool IsZeroTensor(T tol = 1.e-9) const {
535  REAL realTol = TPZExtractVal::val(tol);
536  for (unsigned int i = 0; i < 6; ++i) {
537  if (fabs(this->fData[i]) > realTol) {
538  return false;
539  }
540  }
541  return true;
542  }
543 
544  bool IsDiagonal(T tol = 1.e-9) const {
545  REAL realTol = TPZExtractVal::val(tol);
546  if ((fabs(this->XY()) > realTol) || (fabs(this->XZ()) > realTol) || (fabs(this->YZ()) > realTol)) {
547  return false;
548  }
549  return true;
550  }
551 
556  void EigenSystem(TPZDecomposed &eigensystem) const;
557 
561  void EigenSystemJacobi(TPZDecomposed &eigensystem) const;
562 
566  inline T & XX() const {
567  return fData[_XX_];
568  }
569 
570  inline T & XY() const {
571  return fData[_XY_];
572  }
573 
574  inline T & XZ() const {
575  return fData[_XZ_];
576  }
577 
578  inline T & YY() const {
579  return fData[_YY_];
580  }
581 
582  inline T & YZ() const {
583  return fData[_YZ_];
584  }
585 
586  inline T & ZZ() const {
587  return fData[_ZZ_];
588  }
589 
590  inline T &operator[](int i) const {
591  return fData[i];
592  }
593 
594 private:
599  template <class TBASE>
600  void DeviatoricDiagonal_T(TPZVec<T> & vec) const;
601 
602  // Specialization for TBASE = REAL
603  void DeviatoricDiagonal(TPZVec<T> & vec) const;
604 
605 public:
611  template < class T1 >
612  void CopyTo(TPZTensor<T1> & target) const;
613 
619  void CopyTo(TPZFMatrix<REAL> & target) const;
620 
626  void CopyFrom(const TPZFMatrix<T> & source);
627 
631  void CopyToTensor(TPZFMatrix<T> & Tensor) const;
632 
636  void SetUp(const TPZVec<REAL> & Solution);
637 
645  void ComputeEigenvectors(TPZDecomposed &eigensystem) const;
646 
647 
648 public:
653 
654 protected:
655 
656  static inline bool IsZeroVal(const T & val, T tol = 1.e-9) {
657  return (fabs(TPZExtractVal::val(val)) <= tol);
658  }
659 
660  bool AreEqual(const T &val1, const T &val2, const T tol = T(1.e-9)) const {
661  return (std::fabs(TPZExtractVal::val(val1) - TPZExtractVal::val(val2)) <= tol);
662  }
663 
667  void DirectEigenValues(TPZDecomposed &eigensystem, bool compute_eigenvectors) const;
668 
669  void Precondition(REAL &conditionFactor, TPZTensor<T>& A, TPZDecomposed &decomposition) const;
670 
671  void ComputeEigenvector0(const T &eigenvalue, TPZManVector<T, 3> &eigenvector) const;
672  void ComputeEigenvector1(const TPZManVector<T, 3> &eigenvector0, const T &eigenvalue1, TPZManVector<T, 3> &eigenvector1) const;
673  void ComputeEigenvectorsInternal(TPZDecomposed &eigensystem) const;
674 
679  void EigenProjection(const TPZVec<T> &EigenVals, int index, const TPZVec<int> &DistinctEigenvalues, TPZTensor<T> &Ei) const;
680 };
681 
682 template <class T>
683 void TPZTensor<T>::Read(TPZStream& buf, void* context) {
684  buf.Read(fData);
685 }
686 
687 template <class T>
688 void TPZTensor<T>::Write(TPZStream& buf, int withclassid) const {
689  buf.Write(fData);
690 }
691 
692 template <class T>
693 template <class TBASE>
694 inline void TPZTensor<T>::Identity_T(TBASE &) {
695  fData[_XX_] = TBASE(1.);
696  fData[_YY_] = TBASE(1.);
697  fData[_ZZ_] = TBASE(1.);
698 
699  fData[_XY_] = TBASE(0.);
700  fData[_XZ_] = TBASE(0.);
701  fData[_YZ_] = TBASE(0.);
702 }
703 
704 template <class T>
705 inline void TPZTensor<T>::Identity() {
706  REAL TBase;
707  Identity_T(TBase);
708 }
709 
710 template < class T >
712  fData = source.fData;
713  return *this;
714 }
715 
716 template < class T >
718  int i;
719  for (i = 0; i < 6; i++)fData[i] += source.fData[i];
720  return *this;
721 }
722 
723 template < class T >
725  int i;
726  for (i = 0; i < 6; i++)fData[i] -= source.fData[i];
727  return *this;
728 }
729 
730 template < class T >
731 const TPZTensor<T> & TPZTensor<T>::operator*=(const T &multipl) {
732  int i;
733  for (i = 0; i < 6; i++)fData[i] *= multipl;
734  return *this;
735 }
736 
737 template < class T >
739  TPZTensor<T> temp(*this);
740  return temp += source;
741 }
742 
743 template < class T >
745  TPZTensor<T> temp(*this);
746  return temp -= source;
747 }
748 
749 template < class T >
750 TPZTensor<T> TPZTensor<T>::operator*(const T &multipl) const {
751  TPZTensor<T> temp(*this);
752  return temp *= multipl;
753 }
754 
755 template < class T >
756 template < class T1, class T2 >
757 void TPZTensor<T>::Add(const TPZTensor< T1 > & tensor, const T2 & constant) {
758  int i, size = 6;
759  for (i = 0; i < size; i++) {
760  fData[i] += tensor.fData[i] * T1(constant);
761  }
762 }
763 
764 template < class T >
765 template < class T1, class T2 >
766 void TPZTensor<T>::Multiply(const T1 & multipl, const T2 & constant) {
767  int i, size = 6;
768  for (i = 0; i < size; i++) {
769  fData[i] *= multipl;
770  fData[i] *= constant;
771  }
772 }
773 
774 template < class T >
775 void TPZTensor<T>::Multiply(const TPZTensor<T> tensor, TPZTensor<T> & resp) const {
776  const T XX = this->fData[_XX_];
777  const T YY = this->fData[_YY_];
778  const T ZZ = this->fData[_ZZ_];
779  const T XY = this->fData[_XY_];
780  const T XZ = this->fData[_XZ_];
781  const T YZ = this->fData[_YZ_];
782  resp.fData[_XX_] = XX * tensor.XX() + XY * tensor.XY() + XZ * tensor.XZ();
783  resp.fData[_YY_] = XY * tensor.XY() + YY * tensor.YY() + YZ * tensor.YZ();
784  resp.fData[_ZZ_] = XZ * tensor.XZ() + YZ * tensor.YZ() + ZZ * tensor.ZZ();
785  resp.fData[_XY_] = XX * tensor.XY() + XY * tensor.YY() + XZ * tensor.YZ();
786  resp.fData[_XZ_] = XX * tensor.XZ() + XY * tensor.YZ() + XZ * tensor.ZZ();
787  resp.fData[_YZ_] = XY * tensor.XZ() + YY * tensor.YZ() + YZ * tensor.ZZ();
788 }
789 
790 template < class T >
791 template < class T2 >
792 void TPZTensor<T>::Scale(const T2 & constant) {
793  int i, size = 6;
794  const T Tconst = T(constant);
795  for (i = 0; i < size; i++) {
796  fData[i] *= Tconst;
797  }
798 }
799 
800 template < class T >
802  int i, size = 6;
803  const T Tzero = T(0.);
804  for (i = 0; i < size; i++) {
805  fData[i] = Tzero;
806  }
807 }
808 
809 template < class T >
810 void TPZTensor<T>::SetUp(const TPZVec<REAL> & Solution) {
811  int i, size = 6;
812  for (i = 0; i < size; i++) {
813  fData[i] = Solution[i];
814  }
815 }
816 
817 template < class T >
818 template < class T1 >
819 void TPZTensor<T>::CopyTo(TPZTensor<T1> & target) const {
820  for (unsigned int i = 0; i < 6; i++) {
821  target[i] = TPZExtractVal::val(fData[i]);
822  }
823 }
824 
825 template < class T >
827  for (unsigned int i = 0; i < 6; i++) {
828  target(i, 0) = TPZExtractVal::val(fData[i]);
829  }
830 }
831 
832 template < class T >
833 void TPZTensor<T>::CopyFrom(const TPZFMatrix<T> & source) {
834  for (unsigned int i = 0; i < 6; i++) {
835  fData[i] = source.Get(i, 0);
836  }
837 }
838 
839 template < class T >
840 template < class TBASE >
842  T p = I1() / T(TBASE(3.));
843  vec[0] = fData[_XX_] - p;
844  vec[1] = fData[_YY_] - p;
845  vec[2] = fData[_ZZ_] - p;
846 }
847 
848 template < class T >
850  DeviatoricDiagonal_T<REAL>(vec);
851 }
852 
853 template < class T>
855  T norm = T(0.);
856  for (unsigned int i = 0; i < 6; i++) {
857  norm += fData[i] * fData[i];
858  }
859  norm += fData[_XY_] * fData[_XY_];
860  norm += fData[_XZ_] * fData[_XZ_];
861  norm += fData[_YZ_] * fData[_YZ_];
862  return sqrt(norm);
863 }
864 
865 template <class T>
866 std::ostream &operator<<(std::ostream &out, const TPZTensor<T> &tens) {
867  tens.Print(out);
868  return out;
869 }
870 
874 template <class T>
875 T TPZTensor<T>::Det() const {
876  return fData[_XX_] * fData[_YY_] * fData[_ZZ_] + fData[_XY_] * fData[_XZ_] * fData[_YZ_]*2. - fData[_XZ_] * fData[_YY_] * fData[_XZ_] -
877  fData[_XY_] * fData[_XY_] * fData[_ZZ_] - fData[_YZ_] * fData[_YZ_] * fData[_XX_];
878 }
879 
883 template <class T>
884 void TPZTensor<T>::dDet(TPZTensor<T> &grad) const {
885  grad.fData[_XX_] = fData[_YY_] * fData[_ZZ_] - fData[_YZ_] * fData[_YZ_];
886  grad.fData[_XY_] = fData[_XZ_] * fData[_YZ_] - fData[_XY_] * fData[_ZZ_];
887  grad.fData[_XZ_] = fData[_XY_] * fData[_YZ_] - fData[_XZ_] * fData[_YY_];
888  grad.fData[_YY_] = fData[_XX_] * fData[_ZZ_] - fData[_XZ_] * fData[_XZ_];
889  grad.fData[_YZ_] = fData[_XY_] * fData[_XZ_] - fData[_YZ_] * fData[_XX_];
890  grad.fData[_ZZ_] = fData[_XX_] * fData[_YY_] - fData[_XY_] * fData[_XY_];
891 }
892 
893 template <class T>
895  s = *this;
896  T mult = -I1() / T(3);
897  s.fData[_XX_] += mult;
898  s.fData[_YY_] += mult;
899  s.fData[_ZZ_] += mult;
900 }
901 
902 template < class T >
903 T TPZTensor<T>::I1() const {
904  return fData[_XX_] + fData[_YY_] + fData[_ZZ_];
905 }
906 
907 template < class T >
908 T TPZTensor<T>::I2() const {
909  return -(fData[_XY_] * fData[_XY_] +
910  fData[_XZ_] * fData[_XZ_] +
911  fData[_YZ_] * fData[_YZ_])
912  + (fData[_XX_] * fData[_YY_] +
913  fData[_YY_] * fData[_ZZ_] +
914  fData[_XX_] * fData[_ZZ_]);
915 }
916 
917 template < class T >
918 T TPZTensor<T>::I3() const {
919  return fData[_XX_] * fData[_YY_] * fData[_ZZ_]
920  +(fData[_XY_] * fData[_XZ_] * fData[_YZ_]) * 2.
921  - (fData[_XX_] * fData[_YZ_] * fData[_YZ_] +
922  fData[_YY_] * fData[_XZ_] * fData[_XZ_] +
923  fData[_ZZ_] * fData[_XY_] * fData[_XY_]);
924 }
925 
926 template < class T >
927 T TPZTensor<T>::J2() const {
928  TPZVec<T> s(3);
929  DeviatoricDiagonal_T<T>(s);
930  T value = -s[0] * s[1] - s[0] * s[2] - s[1] * s[2] + fData[_XY_] * fData[_XY_] + fData[_XZ_] * fData[_XZ_] + fData[_YZ_] * fData[_YZ_];
931  return TPZAssert::NonNegative(value);
932 }
933 
934 template < class T >
935 void TPZTensor<T>::dJ2(TPZTensor<T> & Tangent) const {
936  T p = I1() / T(3.);
937  Tangent.fData[_XX_] = fData[_XX_] - p;
938  Tangent.fData[_YY_] = fData[_YY_] - p;
939  Tangent.fData[_ZZ_] = fData[_ZZ_] - p;
940  Tangent.fData[_XY_] = fData[_XY_] * T(2.);
941  Tangent.fData[_XZ_] = fData[_XZ_] * T(2.);
942  Tangent.fData[_YZ_] = fData[_YZ_] * T(2.);
943 }
944 
945 template <class T>
946 T TPZTensor<T>::J3() const {
947  TPZTensor<T> s;
948  S(s);
949  return s.Det();
950 }
951 
955 template<class T>
956 void TPZTensor<T>::dJ3(TPZTensor<T> &deriv) const {
957  T state0(fData[_XX_]), state1(fData[_XY_]), statex1(fData[_XY_]),
958  state2(fData[_XZ_]), statex2(fData[_XZ_]), state3(fData[_YY_]),
959  state4(fData[_YZ_]), statex4(fData[_YZ_]), state5(fData[_ZZ_]);
960  deriv.fData[_XX_] = (fData[_XX_] * fData[_XX_]*2.) / 9. + fData[_XY_] * fData[_XY_] / 3. +
961  fData[_XZ_] * fData[_XZ_] / 3. - (fData[_XX_] * fData[_YY_]*2.) / 9. -
962  fData[_YY_] * fData[_YY_] / 9. - (fData[_YZ_] * fData[_YZ_]*2.) / 3. - (fData[_XX_] * fData[_ZZ_]*2.) /
963  9. + (fData[_YY_] * fData[_ZZ_]*4.) / 9. - fData[_ZZ_] * fData[_ZZ_] / 9.;
964  deriv.fData[_XY_] = (state0 * state1) / 3. + (state1 * state3) / 3. -
965  (state1 * state5 * 2.) / 3. + (state0 * statex1) / 3. +
966  (state3 * statex1) / 3. - (state5 * statex1 * 2.) / 3. +
967  state4 * statex2 + state2*statex4;
968  deriv.fData[_XZ_] = (state0 * state2) / 3. - (state2 * state3 * 2.) / 3. +
969  state1 * state4 + (state2 * state5) / 3. +
970  (state0 * statex2) / 3. - (state3 * statex2 * 2.) / 3. +
971  (state5 * statex2) / 3. + statex1*statex4;
972  deriv.fData[_YY_] = -(fData[_XX_] * fData[_XX_]) / 9. +
973  (fData[_XY_] * fData[_XY_]) / 3. - ((fData[_XZ_] * fData[_XZ_])*2.) / 3. - (fData[_XX_] * fData[_YY_]*2.) / 9. + ((fData[_YY_] * fData[_YY_])*2.) / 9. +
974  (fData[_YZ_] * fData[_YZ_]) / 3. + (fData[_XX_] * fData[_ZZ_]*4.) / 9. - (fData[_YY_] * fData[_ZZ_]*2.) / 9. -
975  (fData[_ZZ_] * fData[_ZZ_]) / 9.;
976  deriv.fData[_YZ_] = (state0 * state4 * (-2.)) / 3. + (state3 * state4) / 3. +
977  (state4 * state5) / 3. + state2 * statex1 +
978  state1 * statex2 - (state0 * statex4 * 2.) / 3. +
979  (state3 * statex4) / 3. + (state5 * statex4) / 3.;
980  deriv.fData[_ZZ_] = -(fData[_XX_] * fData[_XX_]) / 9. - (2. * (fData[_XY_] * fData[_XY_])) / 3. +
981  (fData[_XZ_] * fData[_XZ_]) / 3. + (fData[_XX_] * fData[_YY_]*4.) / 9. - (fData[_YY_] * fData[_YY_]) / 9. +
982  (fData[_YZ_] * fData[_YZ_]) / 3. - (fData[_XX_] * fData[_ZZ_]*2.) / 9. - (fData[_YY_] * fData[_ZZ_]*2.) /
983  9. + ((fData[_ZZ_] * fData[_ZZ_])*2.) / 9.;
984 
985 }
986 
987 template <class T>
989  Tensor.Resize(3, 3);
990  Tensor(0, 0) = XX();
991  Tensor(0, 1) = Tensor(1, 0) = XY();
992  Tensor(0, 2) = Tensor(2, 0) = XZ();
993  Tensor(1, 1) = YY();
994  Tensor(1, 2) = Tensor(2, 1) = YZ();
995  Tensor(2, 2) = ZZ();
996 }
997 
998 template<class T>
999 static T Polynom(const T &x, const T &I1, const T &I2, const T &I3) {
1000  T result = x * x * x - I1 * x * x + I2 * x - I3;
1001  return result;
1002 }
1003 
1004 template<class T>
1005 static T DerivPolynom(const T &x, const T &I1, const T &I2, const T &I3) {
1006  T result = T(3.) * x * x - T(2.) * I1 * x + I2;
1007  return result;
1008 }
1009 
1010 template<class T>
1011 static T UpdateNewton(const T &x, const T &I1, const T &I2, const T &I3) {
1012  T residue = Polynom(x, I1, I2, I3);
1013  T dres = DerivPolynom(x, I1, I2, I3);
1014  return x - residue / dres;
1015 }
1016 
1017 template <class T>
1019  TPZFNMatrix<9, T> TensorMat(*this);
1020 
1021  int64_t numiterations = 1000;
1022  T tol;
1023  ZeroTolerance(tol);
1024 
1025  eigensystem.fEigenvectors[0] = TPZManVector<T, 3>(3, 0.);
1026  eigensystem.fEigenvectors[1] = TPZManVector<T, 3>(3, 0.);
1027  eigensystem.fEigenvectors[2] = TPZManVector<T, 3>(3, 0.);
1028 
1029  TPZManVector<T, 3> Eigenvalues(3, 0.);
1030  TPZFNMatrix<9, T> Eigenvectors(3, 3, 0.);
1031  TensorMat.SolveEigensystemJacobi(numiterations, TPZExtractVal::ref(tol), Eigenvalues, Eigenvectors);
1032 
1033  TPZManVector<TPZTensor<T>, 3> &Eigentensors = eigensystem.fEigentensors;
1034  eigensystem.fEigenvalues = Eigenvalues;
1035 
1036  //tres autovalores iguais
1037  if (AreEqual(Eigenvalues[0], Eigenvalues[1]) && AreEqual(Eigenvalues[0], Eigenvalues[2])) {
1038  eigensystem.fDistinctEigenvalues = 1;
1039  for (unsigned int i = 0; i < 3; ++i) {
1040  eigensystem.fGeometricMultiplicity[i] = 3;
1041  eigensystem.fEigenvectors[i][i] = 1.;
1042  Eigentensors[i].Identity();
1043  }
1044  } else {
1045  for (unsigned int i = 0; i < 3; ++i) {
1046  for (unsigned int j = 0; j < 3; ++j) {
1047  eigensystem.fEigenvectors[i][j] = Eigenvectors(i, j);
1048  }
1049  }
1050 
1051  if (AreEqual(Eigenvalues[0], Eigenvalues[1]) || AreEqual(Eigenvalues[1], Eigenvalues[2]) || AreEqual(Eigenvalues[0], Eigenvalues[2])) { //dois autovalores iguais
1052  eigensystem.fDistinctEigenvalues = 2;
1053 
1054  int different = -1;
1055  int equals[2] = {-1, -1};
1056  if (AreEqual(Eigenvalues[0], Eigenvalues[1])) {
1057  different = 2;
1058  equals[0] = 0;
1059  equals[1] = 1;
1060  } else if (AreEqual(Eigenvalues[0], Eigenvalues[2])) {
1061  different = 1;
1062  equals[0] = 0;
1063  equals[1] = 2;
1064  } else if (AreEqual(Eigenvalues[1], Eigenvalues[2])) {
1065  different = 0;
1066  equals[0] = 1;
1067  equals[1] = 2;
1068  }
1069  eigensystem.fGeometricMultiplicity[different] = 1;
1070  eigensystem.fGeometricMultiplicity[equals[0]] = 2;
1071  eigensystem.fGeometricMultiplicity[equals[1]] = 2;
1072 
1073  Eigentensors[different].XX() = Eigenvectors(different, 0) * Eigenvectors(different, 0);
1074  Eigentensors[different].XY() = Eigenvectors(different, 0) * Eigenvectors(different, 1);
1075  Eigentensors[different].XZ() = Eigenvectors(different, 0) * Eigenvectors(different, 2);
1076  Eigentensors[different].YY() = Eigenvectors(different, 1) * Eigenvectors(different, 1);
1077  Eigentensors[different].YZ() = Eigenvectors(different, 1) * Eigenvectors(different, 2);
1078  Eigentensors[different].ZZ() = Eigenvectors(different, 2) * Eigenvectors(different, 2);
1079 
1080  Eigentensors[equals[0]].Identity();
1081  Eigentensors[equals[0]] -= Eigentensors[different];
1082  Eigentensors[equals[1]] = Eigentensors[equals[0]];
1083  } else {
1084  //nenhum autovalor igual
1085  eigensystem.fDistinctEigenvalues = 3;
1086  for (int i = 0; i < 3; i++) {
1087  eigensystem.fGeometricMultiplicity[i] = 1;
1088  Eigentensors[i].XX() = Eigenvectors(i, 0) * Eigenvectors(i, 0);
1089  Eigentensors[i].XY() = Eigenvectors(i, 0) * Eigenvectors(i, 1);
1090  Eigentensors[i].XZ() = Eigenvectors(i, 0) * Eigenvectors(i, 2);
1091  Eigentensors[i].YY() = Eigenvectors(i, 1) * Eigenvectors(i, 1);
1092  Eigentensors[i].YZ() = Eigenvectors(i, 1) * Eigenvectors(i, 2);
1093  Eigentensors[i].ZZ() = Eigenvectors(i, 2) * Eigenvectors(i, 2);
1094  }
1095  }//3 autovalores diferentes
1096  }
1097 
1098 #ifdef PZDEBUG
1099 #ifdef LOG4CXX
1100  if (loggerr->isDebugEnabled()) {
1101  std::stringstream str;
1102  str << "\n-------------AUTOVETORES JACOBI--------------" << std::endl;
1103  str << "Tensor:" << std::endl;
1104  this->Print(str);
1105  str << "Eigenvalues = " << Eigenvalues << std::endl;
1106  str << "Eigenvectors:" << std::endl;
1107  Eigenvectors.Print("Eigenvec:", str);
1108  str << "Eigenprojections:" << std::endl;
1109  for (int k = 0; k < 3; k++) {
1110  str << "EigenProjection " << k << ":" << std::endl;
1111  Eigentensors[k].Print(str);
1112  }
1113 
1114  str << "\n-------------FIM AUTOVETORES JACOBI--------------" << std::endl;
1115  LOGPZ_DEBUG(loggerr, str.str())
1116  }
1117 #endif
1118 #endif
1119 }
1120 
1121 template <class T>
1122 void TPZTensor<T>::ComputeEigenvalues(TPZDecomposed &eigensystem, const bool compute_eigenvectors) const {
1123  TPZManVector<T, 3> &eigenvalues = eigensystem.fEigenvalues;
1124  TPZManVector<TPZManVector<T, 3>, 3> &eigenvectors = eigensystem.fEigenvectors;
1125 
1126  T tol = Norm()*1.e-12;
1127 
1128  if (this->IsZeroTensor(tol)) {
1129  eigensystem.fDistinctEigenvalues = 1;
1130  eigenvalues[0] = eigenvalues[1] = eigenvalues[2] = 0.;
1131  eigensystem.fGeometricMultiplicity[0] = 3;
1132  eigensystem.fGeometricMultiplicity[1] = 3;
1133  eigensystem.fGeometricMultiplicity[2] = 3;
1134  if (compute_eigenvectors) {
1135  eigenvectors[0] = TPZManVector<T, 3>(3, 0.);
1136  eigenvectors[0][0] = 1.0;
1137  eigenvectors[1] = TPZManVector<T, 3>(3, 0.);
1138  eigenvectors[1][1] = 1.0;
1139  eigenvectors[2] = TPZManVector<T, 3>(3, 0.);
1140  eigenvectors[2][2] = 1.0;
1141  }
1142  } else if (this->IsDiagonal(tol)) {
1143  eigenvalues[0] = this->XX();
1144  eigenvalues[1] = this->YY();
1145  eigenvalues[2] = this->ZZ();
1146 
1147  if (compute_eigenvectors) {
1148  eigenvectors.resize(3);
1149  eigenvectors[0] = TPZManVector<T, 3>(3, 0.);
1150  eigenvectors[0][0] = 1.0;
1151  eigenvectors[1] = TPZManVector<T, 3>(3, 0.);
1152  eigenvectors[1][1] = 1.0;
1153  eigenvectors[2] = TPZManVector<T, 3>(3, 0.);
1154  eigenvectors[2][2] = 1.0;
1155  }
1156 
1157  bool ev0eqev1 = AreEqual(eigenvalues[0], eigenvalues[1], tol);
1158  bool ev1eqev2 = AreEqual(eigenvalues[1], eigenvalues[2], tol);
1159 
1160  if (ev0eqev1 && ev1eqev2) {
1161  //tres autovalores iguais
1162  eigensystem.fDistinctEigenvalues = 1;
1163  eigensystem.fGeometricMultiplicity[0] = 3;
1164  eigensystem.fGeometricMultiplicity[1] = 3;
1165  eigensystem.fGeometricMultiplicity[2] = 3;
1166  return;
1167  } else if (ev0eqev1 || ev1eqev2 || AreEqual(eigenvalues[0], eigenvalues[2], tol)) {
1168  eigensystem.fDistinctEigenvalues = 2;
1169  int different = -1;
1170  int equals[2] = {-1, -1};
1171  if (ev0eqev1) {
1172  different = 2;
1173  equals[0] = 0;
1174  equals[1] = 1;
1175  } else if (ev1eqev2) {
1176  different = 0;
1177  equals[0] = 1;
1178  equals[1] = 2;
1179  } else {
1180  different = 1;
1181  equals[0] = 0;
1182  equals[1] = 2;
1183  }
1184  eigensystem.fGeometricMultiplicity[different] = 1;
1185  eigensystem.fGeometricMultiplicity[equals[0]] = 2;
1186  eigensystem.fGeometricMultiplicity[equals[1]] = 2;
1187  } else {
1188  eigensystem.fDistinctEigenvalues = 3;
1189  eigensystem.fGeometricMultiplicity[0] = 1;
1190  eigensystem.fGeometricMultiplicity[1] = 1;
1191  eigensystem.fGeometricMultiplicity[2] = 1;
1192  }
1193 
1194  if (eigenvalues[0] < eigenvalues[1]) {
1195  T eigenvalueTemp = eigenvalues[0];
1196  eigenvalues[0] = eigenvalues[1];
1197  eigenvalues[1] = eigenvalueTemp;
1198  std::swap(eigensystem.fGeometricMultiplicity[0], eigensystem.fGeometricMultiplicity[1]);
1199  if (compute_eigenvectors) {
1200  auto temp = eigenvectors[0];
1201  eigenvectors[0] = eigenvectors[1];
1202  eigenvectors[1] = temp;
1203  }
1204  }
1205  if (eigenvalues[1] < eigenvalues[2]) {
1206  T eigenvalueTemp = eigenvalues[1];
1207  eigenvalues[1] = eigenvalues[2];
1208  eigenvalues[2] = eigenvalueTemp;
1209  std::swap(eigensystem.fGeometricMultiplicity[1], eigensystem.fGeometricMultiplicity[2]);
1210  if (compute_eigenvectors) {
1211  auto temp = eigenvectors[1];
1212  eigenvectors[1] = eigenvectors[2];
1213  eigenvectors[2] = temp;
1214  }
1215  }
1216  if (eigenvalues[0] < eigenvalues[1]) {
1217  T eigenvalueTemp = eigenvalues[0];
1218  eigenvalues[0] = eigenvalues[1];
1219  eigenvalues[1] = eigenvalueTemp;
1220  std::swap(eigensystem.fGeometricMultiplicity[0], eigensystem.fGeometricMultiplicity[1]);
1221  if (compute_eigenvectors) {
1222  auto temp = eigenvectors[0];
1223  eigenvectors[0] = eigenvectors[1];
1224  eigenvectors[1] = temp;
1225  }
1226  }
1227  } else {
1228  this->DirectEigenValues(eigensystem, compute_eigenvectors);
1229 
1230  bool ev0eqev1 = AreEqual(eigenvalues[0], eigenvalues[1], tol);
1231  bool ev1eqev2 = AreEqual(eigenvalues[1], eigenvalues[2], tol);
1232  //tres autovalores iguais
1233  if (ev0eqev1 && ev1eqev2) {
1234  eigensystem.fDistinctEigenvalues = 1;
1235  eigensystem.fGeometricMultiplicity[0] = 3;
1236  eigensystem.fGeometricMultiplicity[1] = 3;
1237  eigensystem.fGeometricMultiplicity[2] = 3;
1238  } else if (ev0eqev1 || ev1eqev2) {
1239  //dois autovalores iguais
1240  eigensystem.fDistinctEigenvalues = 2;
1241 
1242  int different = -1;
1243  int equals = -1;
1244  if (ev0eqev1) {
1245  different = 2;
1246  equals = 0;
1247  } else {
1248  different = 0;
1249  equals = 2;
1250  }
1251  eigensystem.fGeometricMultiplicity[1] = 2;
1252  eigensystem.fGeometricMultiplicity[equals] = 2;
1253  eigensystem.fGeometricMultiplicity[different] = 1;
1254  } else {
1255  //3 autovalores diferentes
1256  eigensystem.fDistinctEigenvalues = 3;
1257  eigensystem.fGeometricMultiplicity[0] = 1;
1258  eigensystem.fGeometricMultiplicity[1] = 1;
1259  eigensystem.fGeometricMultiplicity[2] = 1;
1260  }
1261  }
1262 }
1263 
1264 template <class T>
1265 void TPZTensor<T>::EigenSystem(TPZDecomposed &eigensystem)const {
1266  TPZManVector<T, 3> &eigenvalues = eigensystem.fEigenvalues;
1267  TPZManVector<TPZTensor<T>, 3> &eigentensors = eigensystem.fEigentensors;
1268 
1269  T tol = Norm()*1.e-8;
1270 
1271  ComputeEigenvectors(eigensystem);
1272 
1273  TPZStack<int, 3> indices_to_add;
1274  for (unsigned int i = 0; i < 3; ++i) {
1275  if (eigensystem.fGeometricMultiplicity[i] != 1) {
1276  indices_to_add.push_back(i);
1277  }
1278  for (unsigned int j = 0; j < 3; ++j) {
1279  for (unsigned int k = j; k < 3; ++k) {
1280  eigentensors[i](j, k) = eigensystem.fEigenvectors[i][j] * eigensystem.fEigenvectors[i][k];
1281  }
1282  }
1283  }
1284  if (indices_to_add.size() > 0) {
1285  TPZTensor<T> sum;
1286  for (auto i : indices_to_add) {
1287  sum += eigentensors[i];
1288  }
1289  for (auto i : indices_to_add) {
1290  eigentensors[i] = sum;
1291  }
1292  }
1293 #ifdef PZDEBUG
1294  TPZTensor<T> total;
1295  unsigned int i;
1296  for (i = 0; i < 3; i += eigensystem.fGeometricMultiplicity[i]) {
1297  total.Add(eigentensors[i], eigenvalues[i]);
1298  }
1299  if (i != 3) {
1300  std::cout << "Tensor decomposition error: " << std::endl;
1301  std::cout << "Incorrect total geometric multiplicity: " << i << std::endl;
1302  DebugStop();
1303  }
1304  for (unsigned int i = 0; i < 6; ++i) {
1305  if (!AreEqual(total[i], this->operator[](i), tol)) {
1306  std::cout << std::setprecision(15);
1307  std::cout << "Tensor decomposition error: " << std::endl;
1308  std::cout << "Original Tensor: ";
1309  this->Print(std::cout);
1310  std::cout << "Reconstruction from decomposition: ";
1311  total.Print(std::cout);
1312  std::cout << "Decomposition: " << std::endl;
1313  eigensystem.Print(std::cout);
1314  DebugStop();
1315  }
1316  }
1317 #endif
1318 }
1319 
1320 template <class T>
1322  // Eigenvalues not computed yet. Let's do it.
1323  if (eigensystem.fDistinctEigenvalues == 0) {
1324  ComputeEigenvalues(eigensystem, true);
1325  } else {
1326  eigensystem.fEigenvectors[0] = TPZManVector<T, 3>(3, 0.);
1327  eigensystem.fEigenvectors[1] = TPZManVector<T, 3>(3, 0.);
1328  eigensystem.fEigenvectors[2] = TPZManVector<T, 3>(3, 0.);
1329  switch (eigensystem.fDistinctEigenvalues) {
1330  case 1:
1331  eigensystem.fEigenvectors[0][0] = 1.;
1332  eigensystem.fEigenvectors[1][1] = 1.;
1333  eigensystem.fEigenvectors[2][2] = 1.;
1334  return;
1335  case 2:
1336  case 3:
1337  {
1338  T tol = Norm()*1.e-12;
1339  if (IsDiagonal(tol)) {
1340  for (unsigned int i = 0; i < 3; ++i) {
1341  unsigned int j;
1342  for (j = 0; j < 3; ++j) {
1343  if (AreEqual(eigensystem.fEigenvalues[i], this->operator()(j, j), tol)) {
1344  eigensystem.fEigenvectors[i][j] = 1;
1345  break;
1346  }
1347  }
1348  if (j == 3) {
1349  DebugStop();
1350  }
1351  }
1352  } else {
1353  REAL conditionFactor;
1354  TPZDecomposed eigensystemTemp = eigensystem;
1355  TPZTensor<T> A;
1356  Precondition(conditionFactor, A, eigensystemTemp);
1357  A.ComputeEigenvectorsInternal(eigensystemTemp);
1358  eigensystem.fEigenvectors = eigensystemTemp.fEigenvectors;
1359  }
1360  break;
1361  }
1362  default:
1363  DebugStop();
1364  }
1365  }
1366 
1367 
1368  for (unsigned int lambda = 0; lambda < 3; ++lambda) {
1369  REAL Norm = 0.;
1370  for (unsigned int i = 0; i < 3; ++i) {
1371  Norm += pow(TPZExtractVal::val(eigensystem.fEigenvectors[lambda][i]), 2);
1372  }
1373  Norm = sqrt(Norm);
1374  for (unsigned int i = 0; i < 3; ++i) {
1375  eigensystem.fEigenvectors[lambda][i] /= Norm;
1376  }
1377  }
1378 }
1379 
1380 template <class T>
1381 void TPZTensor<T>::EigenProjection(const TPZVec<T> &EigenVals, int index, const TPZVec<int> &DistinctEigenvalues, TPZTensor<T> &Ei) const {
1382  const int p = DistinctEigenvalues.NElements();
1383  TPZFNMatrix<9, T> local(3, 3), aux(3, 3), resultingTensor(3, 3);
1384  Ei.Identity();
1385  for (int count = 0; count < p; ++count) {
1386  const int j = DistinctEigenvalues[count];
1387  if (j == index) continue;
1388  local.Identity();
1389  local *= -1. * EigenVals[j];
1390 
1391  this->CopyToTensor(aux);
1392  local += aux;
1393 
1394 #ifdef PZDEBUG
1395  if (AreEqual(EigenVals[index], EigenVals[j])) DebugStop();
1396 #endif
1397  local *= 1. / (EigenVals[index] - EigenVals[j]);
1398  Ei.CopyToTensor(aux);
1399  aux.Multiply(local, resultingTensor);
1400  Ei[_XX_] = resultingTensor(0, 0);
1401  Ei[_XY_] = resultingTensor(0, 1);
1402  Ei[_XZ_] = resultingTensor(0, 2);
1403  Ei[_YY_] = resultingTensor(1, 1);
1404  Ei[_YZ_] = resultingTensor(1, 2);
1405  Ei[_ZZ_] = resultingTensor(2, 2);
1406  }//for j
1407 }
1408 
1409 template <class T>
1410 void TPZTensor<T>::ComputeEigenvector0(const T &eigenvalue, TPZManVector<T, 3> &eigenvector) const {
1411  // Compute a unit-length eigenvector for eigenvalue[i0]. The matrix is
1412  // rank 2, so two of the rows are linearly independent. For a robust
1413  // computation of the eigenvector, select the two rows whose cross product
1414  // has largest length of all pairs of rows.
1415  TPZManVector<T, 3> row0(3);
1416  row0[0] = XX() - eigenvalue;
1417  row0[1] = XY();
1418  row0[2] = XZ();
1419  TPZManVector<T, 3> row1(3);
1420  row1[0] = XY();
1421  row1[1] = YY() - eigenvalue;
1422  row1[2] = YZ();
1423  TPZManVector<T, 3> row2(3);
1424  row2[0] = XZ();
1425  row2[1] = YZ();
1426  row2[2] = ZZ() - eigenvalue;
1427  TPZManVector<T, 3> r0xr1(3);
1428  Cross(row0, row1, r0xr1);
1429  TPZManVector<T, 3> r0xr2(3);
1430  Cross(row0, row2, r0xr2);
1431  TPZManVector<T, 3> r1xr2(3);
1432  Cross(row1, row2, r1xr2);
1433  T d0 = Dot(r0xr1, r0xr1);
1434  T d1 = Dot(r0xr2, r0xr2);
1435  T d2 = Dot(r1xr2, r1xr2);
1436 
1437  REAL dmax = TPZExtractVal::val(d0);
1438  int imax = 0;
1439  if (TPZExtractVal::val(d1) > dmax) {
1440  dmax = TPZExtractVal::val(d1);
1441  imax = 1;
1442  }
1443  if (TPZExtractVal::val(d2) > dmax) {
1444  imax = 2;
1445  }
1446 
1447  if (imax == 0) {
1448  T inv_sqrt_val = 1. / sqrt(d0);
1449  eigenvector[0] = r0xr1[0] * inv_sqrt_val;
1450  eigenvector[1] = r0xr1[1] * inv_sqrt_val;
1451  eigenvector[2] = r0xr1[2] * inv_sqrt_val;
1452  } else if (imax == 1) {
1453  T inv_sqrt_val = 1. / sqrt(d1);
1454  eigenvector[0] = r0xr2[0] * inv_sqrt_val;
1455  eigenvector[1] = r0xr2[1] * inv_sqrt_val;
1456  eigenvector[2] = r0xr2[2] * inv_sqrt_val;
1457  } else {
1458  T inv_sqrt_val = 1. / sqrt(d2);
1459  eigenvector[0] = r1xr2[0] * inv_sqrt_val;
1460  eigenvector[1] = r1xr2[1] * inv_sqrt_val;
1461  eigenvector[2] = r1xr2[2] * inv_sqrt_val;
1462  }
1463 }
1464 
1465 template <class T>
1466 void TPZTensor<T>::ComputeEigenvector1(const TPZManVector<T, 3> &eigenvector0, const T &eigenvalue1, TPZManVector<T, 3> &eigenvector1) const {
1467  // Robustly compute a right-handed orthonormal set { U, V, evec0 }.
1468  TPZManVector<T, 3> U(3), V(3);
1469 
1470  // The vector eigenvector0 is guaranteed to be unit-length, in which case there is no
1471  // need to worry about a division by zero when computing invLength.
1472  T invLength;
1473  if (fabs(eigenvector0[0]) > fabs(eigenvector0[1])) {
1474  // The component of maximum absolute value is either eigenvector0[0] or eigenvector0[2].
1475  invLength = (T) 1 / sqrt(eigenvector0[0] * eigenvector0[0] + eigenvector0[2] * eigenvector0[2]);
1476  U[0] = -eigenvector0[2] * invLength;
1477  U[1] = T(0.);
1478  U[2] = +eigenvector0[0] * invLength;
1479  } else {
1480  // The component of maximum absolute value is either eigenvector0[1] or eigenvector0[2].
1481  invLength = (T) 1 / sqrt(eigenvector0[1] * eigenvector0[1] + eigenvector0[2] * eigenvector0[2]);
1482  U[0] = T(0.);
1483  U[1] = +eigenvector0[2] * invLength;
1484  U[2] = -eigenvector0[1] * invLength;
1485  }
1486  Cross(eigenvector0, U, V);
1487 
1488  // Let e be eigenvalue1 and let v1 be a corresponding eigenvector which is a
1489  // solution to the linear system (A - e*I)*v1 = 0. The matrix (A - e*I)
1490  // is 3x3, not invertible (so infinitely many solutions), and has rank 2
1491  // when eigenvalue1 and eigenvalue2 are different. It has rank 1 when eigenvalue1 and eigenvalue2
1492  // are equal. Numerically, it is difficult to compute robustly the rank
1493  // of a matrix. Instead, the 3x3 linear system is reduced to a 2x2 system
1494  // as follows. Define the 3x2 matrix J = [U V] whose columns are the U
1495  // and V computed previously. Define the 2x1 vector X = J*v1. The 2x2
1496  // system is 0 = M * X = (J^T * (A - e*I) * J) * X where J^T is the
1497  // transpose of J and M = J^T * (A - e*I) * J is a 2x2 matrix. The system
1498  // may be written as
1499  // +- -++- -+ +- -+
1500  // | U^T*A*U - e U^T*A*V || x0 | = e * | x0 |
1501  // | V^T*A*U V^T*A*V - e || x1 | | x1 |
1502  // +- -++ -+ +- -+
1503  // where X has row entries x0 and x1.
1504  TPZManVector<T, 3> AU(3);
1505  AU[0] = XX() * U[0] + XY() * U[1] + XZ() * U[2];
1506  AU[1] = XY() * U[0] + YY() * U[1] + YZ() * U[2];
1507  AU[2] = XZ() * U[0] + YZ() * U[1] + ZZ() * U[2];
1508 
1509  TPZManVector<T, 3> AV(3);
1510  AV[0] = XX() * V[0] + XY() * V[1] + XZ() * V[2];
1511  AV[1] = XY() * V[0] + YY() * V[1] + YZ() * V[2];
1512  AV[2] = XZ() * V[0] + YZ() * V[1] + ZZ() * V[2];
1513 
1514  T m00 = U[0] * AU[0] + U[1] * AU[1] + U[2] * AU[2] - eigenvalue1;
1515  T m01 = U[0] * AV[0] + U[1] * AV[1] + U[2] * AV[2];
1516  T m11 = V[0] * AV[0] + V[1] * AV[1] + V[2] * AV[2] - eigenvalue1;
1517 
1518  // For robustness, choose the largest-length row of M to compute the
1519  // eigenvector. The 2-tuple of coefficients of U and V in the
1520  // assignments to eigenvector[1] lies on a circle, and U and V are
1521  // unit length and perpendicular, so eigenvector[1] is unit length
1522  // (within numerical tolerance).
1523  REAL absM00 = fabs(TPZExtractVal::val(m00));
1524  REAL absM01 = fabs(TPZExtractVal::val(m01));
1525  REAL absM11 = fabs(TPZExtractVal::val(m11));
1526  REAL maxAbsComp;
1527  if (absM00 >= absM11) {
1528  maxAbsComp = max(absM00, absM01);
1529  if (IsZeroVal(maxAbsComp)) {
1530  eigenvector1 = U;
1531  } else {
1532  if (absM00 >= absM01) {
1533  m01 /= m00;
1534  m00 = T(1.) / sqrt(T(1.) + m01 * m01);
1535  m01 *= m00;
1536  } else {
1537  m00 /= m01;
1538  m01 = T(1.) / sqrt(T(1.) + m00 * m00);
1539  m00 *= m01;
1540  }
1541  //eigenvector1 = m01*U - m00*V
1542  sscal(U, m01);
1543  eigenvector1 = U;
1544  saxpy(eigenvector1, V, -m00);
1545  }
1546  } else {
1547  maxAbsComp = std::max(absM11, absM01);
1548  if (IsZeroVal(maxAbsComp)) {
1549  eigenvector1 = U;
1550  } else {
1551  if (absM11 >= absM01) {
1552  m01 /= m11;
1553  m11 = T(1.) / sqrt(T(1.) + m01 * m01);
1554  m01 *= m11;
1555  } else {
1556  m11 /= m01;
1557  m01 = T(1.) / sqrt(T(1.) + m11 * m11);
1558  m11 *= m01;
1559  }
1560  //eigenvector1 = m11*U - m01*V
1561  sscal(U, m11);
1562  eigenvector1 = U;
1563  saxpy(eigenvector1, V, -m01);
1564  }
1565  }
1566 }
1567 
1568 template <class T>
1570  TPZManVector<T, 3> &eigenval = eigensystem.fEigenvalues;
1571  TPZManVector<TPZManVector<T, 3>, 3> &eigenvec = eigensystem.fEigenvectors;
1572 
1573  eigenvec.resize(3);
1574  eigenvec[0].resize(3);
1575  eigenvec[1].resize(3);
1576  eigenvec[2].resize(3);
1577  // Compute the eigenvectors so that the set {evec[0], evec[1], evec[2]}
1578  // is right handed and orthonormal.
1579  if (eigensystem.fGeometricMultiplicity[0] == 1) {
1580  ComputeEigenvector0(eigenval[0], eigenvec[0]);
1581  ComputeEigenvector1(eigenvec[0], eigenval[1], eigenvec[1]);
1582  Cross(eigenvec[0], eigenvec[1], eigenvec[2]);
1583  } else {
1584  ComputeEigenvector0(eigenval[2], eigenvec[2]);
1585  ComputeEigenvector1(eigenvec[2], eigenval[1], eigenvec[1]);
1586  Cross(eigenvec[1], eigenvec[2], eigenvec[0]);
1587  }
1588 }
1589 
1590 template <class T>
1591 void TPZTensor<T>::Precondition(REAL &conditionFactor, TPZTensor<T>& A, TPZDecomposed &decomposition) const {
1592  // Precondition the matrix by factoring out the maximum absolute value
1593  // of the components. This guards against floating-point overflow when
1594  // computing the eigenvalues.
1595  REAL max0 = max(fabs(TPZExtractVal::val(XX())), fabs(TPZExtractVal::val(XY())));
1596  REAL max1 = max(fabs(TPZExtractVal::val(XZ())), fabs(TPZExtractVal::val(YY())));
1597  REAL max2 = max(fabs(TPZExtractVal::val(YZ())), fabs(TPZExtractVal::val(ZZ())));
1598  conditionFactor = max(max(max0, max1), max2);
1599 
1600  REAL invMaxAbsElement = 1. / conditionFactor;
1601  for (unsigned int i = 0; i < 6; ++i) {
1602  A.fData[i] = this->fData[i] * invMaxAbsElement;
1603  }
1604  if (decomposition.fDistinctEigenvalues != 0) {
1605  decomposition.fEigenvalues[0] *= invMaxAbsElement;
1606  decomposition.fEigenvalues[1] *= invMaxAbsElement;
1607  decomposition.fEigenvalues[2] *= invMaxAbsElement;
1608  }
1609 }
1610 
1611 template <class T>
1612 void TPZTensor<T>::DirectEigenValues(TPZDecomposed &eigensystem, bool compute_eigenvectors) const {
1613  TPZManVector<T, 3> &eigenval = eigensystem.fEigenvalues;
1614 
1615  REAL conditionFactor;
1616  TPZTensor<T> A;
1617  Precondition(conditionFactor, A, eigensystem);
1618 
1619  T norm = pow(A.XY(), 2.) + pow(A.XZ(), 2.) + pow(A.YZ(), 2.);
1620  // Compute the eigenvalues. The acos(z) function requires |z| <= 1,
1621  // but will fail silently and return NaN if the input is larger than 1 in
1622  // magnitude. To avoid this condition due to rounding errors, the halfDet
1623  // value is clamped to [-1,1].
1624  T traceDiv3 = A.I1() / 3.;
1625  T b00 = A.XX() - traceDiv3;
1626  T b11 = A.YY() - traceDiv3;
1627  T b22 = A.ZZ() - traceDiv3;
1628  T denom = sqrt((pow(b00, 2.) + pow(b11, 2.) + pow(b22, 2.) + norm * T(2.)) / T(6.));
1629  T c00 = b11 * b22 - A.YZ() * A.YZ();
1630  T c01 = A.XY() * b22 - A.YZ() * A.XZ();
1631  T c02 = A.XY() * A.YZ() - b11 * A.XZ();
1632  T det = (b00 * c00 - A.XY() * c01 + A.XZ() * c02) / (denom * denom * denom);
1633  T halfDet = det * T(0.5);
1634  halfDet = min(max(TPZExtractVal::val(halfDet), -1.), 1.);
1635 
1636  // The eigenvalues of B are ordered as beta0 <= beta1 <= beta2. The
1637  // number of digits in twoThirdsPi is chosen so that, whether float or
1638  // double, the floating-point number is the closest to theoretical 2*pi/3.
1639  T angle = acos(halfDet) / T(3.);
1640  const T twoThirdsPi = T(2.09439510239319549);
1641  T beta2 = cos(angle) * T(2.);
1642  T beta0 = cos(angle + twoThirdsPi) * T(2.);
1643  T beta1 = -(beta0 + beta2);
1644 
1645  // The eigenvalues are ordered as alpha0 >= alpha1 >= alpha2.
1646  eigenval[0] = traceDiv3 + denom * beta2;
1647  eigenval[1] = traceDiv3 + denom * beta1;
1648  eigenval[2] = traceDiv3 + denom * beta0;
1649 
1650  if (eigenval[0] < eigenval[1]) {
1651  DebugStop();
1652  }
1653 
1654  if (eigenval[1] < eigenval[2]) {
1655  DebugStop();
1656  }
1657 
1658  if (halfDet > 0. || IsZeroVal(halfDet)) { // greatest eigenvalue has multiplicity 1
1659  eigensystem.fGeometricMultiplicity[0] = 1;
1660  } else { // lowest eigenvalue has multiplicity 1
1661  eigensystem.fGeometricMultiplicity[2] = 1;
1662  }
1663 
1664  if (compute_eigenvectors) {
1665  A.ComputeEigenvectorsInternal(eigensystem);
1666  }
1667  // The preconditioning scaled the tensor, which scales the eigenvalues.
1668  // Revert the scaling.
1669  eigenval[0] *= conditionFactor;
1670  eigenval[1] *= conditionFactor;
1671  eigenval[2] *= conditionFactor;
1672 }
1673 
1674 template <class T>
1675 void TPZTensor<T>::Lodeangle(TPZTensor<T> &GradLode, T &Lode)const {
1676  T J2t(this->J2());
1677  T J3t(this->J3());
1678 
1679  if (fabs(TPZExtractVal::val(J2t)) < 1.e-6)J2t = T(1.e-6);
1680  T sqrtJ2t = sqrt(J2t);
1681  if (fabs(TPZExtractVal::val(sqrtJ2t)) < 1.e-6)sqrtJ2t = T(1.e-6);
1682 
1683  TPZTensor<T> dJ2t, dJ3t;
1684 
1685  this->dJ2(dJ2t);
1686  this->dJ3(dJ3t);
1687  // Derivatives with respect to I1, J2 and J3
1688 
1689  TPZTensor<T> dLodeAngle, TempTensor;
1690 
1691  //QUAL DOS DOIS?
1692  //T theta =-asin( ( T( 3.) * sqrt( T( 3.) ) * J3t ) /( T( 2.) * sqrt(J2t*J2t*J2t) ) )/T( 3.);
1693  //O GRADIENTE DO LODE ESTA EM FUNCAO DO LODE DE 0 a Pi/3
1694 
1695 
1696  T lodetemp = (T(3.) * sqrt(T(3.)) * J3t) / (T(2.) * sqrt(J2t * J2t * J2t));
1697  if (TPZExtractVal::val(lodetemp) <= -1.) {
1698  lodetemp *= T(0.999); // DebugStop();
1699  // TPZExtractVal::val(lodetemp) *= T(0.999); // DebugStop();
1700  //lodetemp = T(-1.);
1701 
1702  }
1703 
1704 
1705  //cout << "\n lodetemp "<<lodetemp<<endl;
1706  //cout << "\n TPZExtractVal::val(lodetemp);"<<TPZExtractVal::val(lodetemp)<<endl;
1707 
1708  if (TPZExtractVal::val(lodetemp) >= 1.) {
1709  lodetemp *= T(0.999);
1710  // TPZExtractVal::val(lodetemp)*= 0.999;
1711  // lodetemp = T(1.);
1712  //DebugStop();
1713  }
1714 
1715  //DLODE = (-2*Dj3*j2 + 3*Dj2*J3t)/(2.*pow(J2t,2.5)*sqrt(1.3333333333333333 - (9*pow(J3t,2))/pow(J2t,3)))
1716  //1
1717  T j33 = T(3.) * J3t;
1718  dJ2t.Multiply(j33, 1);
1719  //2
1720  T j22 = T(2.) * J2t;
1721  dJ3t.Multiply(j22, 1);
1722  //3
1723  dJ2t.Add(dJ3t, -1);
1724  //4
1725  //if(TPZExtractVal::val(J2t)<1.e-6)J2t=1.e-6;
1726  T checknegativeroot = ((T(9.) * J3t * J3t) / (J2t * J2t * J2t));
1727  if (TPZExtractVal::val(checknegativeroot) >= 4 / 3.)checknegativeroot *= T(0.999);
1728  T denom = T(2.) * sqrt(J2t * J2t * J2t * J2t * J2t) * sqrt((T(4 / 3.)) - checknegativeroot);
1729  //T denom2 = (T(2.)*pow(J2t,2.5)*sqrt(T(1.3333333333333333) - (T(9.)*pow(J3t,2.))/pow(J2t,3)));
1730  T oneoverden = T(1.) / denom;
1731  dJ2t.Multiply(oneoverden, 1);
1732  dJ2t *= oneoverden;
1733  // GradLode = dJ2t;
1734 
1735  T acoslodetemp = acos(lodetemp);
1736  Lode = acoslodetemp / T(3.);
1737 
1738  if (TPZExtractVal::val(Lode) >= (M_PI / 3.) - 0.0001) {
1739  Lode *= T(0.999);
1740  }
1741 }
1742 
1743 template <class T>
1744 void TPZTensor<T>::Eigenvalue(TPZTensor<T> &eigenval, TPZTensor<T> &dSigma1, TPZTensor<T> &dSigma2, TPZTensor<T> &dSigma3)const {
1745  T I1(this->I1()), J2(this->J2());
1746  // T J3(this->J3());
1747 
1748  if (fabs(TPZExtractVal::val(J2)) < 1.e-6)J2 = 1.e-6;
1749  // if(fabs( TPZExtractVal::val(J2) ) < 1.e-6)return;
1750 
1751  T sqrtJ2 = sqrt(J2);
1752  if (fabs(TPZExtractVal::val(sqrtJ2)) < 1.e-6)sqrtJ2 = 1.e-6;
1753 
1754  TPZTensor<T> dJ2, dJ3, dLode;
1755  T Lode;
1756 
1757  this->dJ2(dJ2);
1758  this->dJ3(dJ3);
1759  this->Lodeangle(dLode, Lode);
1760 
1761  T pi23 = T(2. * M_PI / 3.);
1762  T TwoOverSqrThree = T(2. / sqrt(3.));
1763  T TwoOverSqrThreeJ2 = TwoOverSqrThree * sqrtJ2;
1764  T I13 = I1 / T(3.);
1765 
1766  T tempCosLode = cos(Lode) * TwoOverSqrThreeJ2;
1767  T tempCosMinusLode = cos(Lode - pi23) * TwoOverSqrThreeJ2;
1768  T tempCosPlusLode = cos(Lode + pi23) * TwoOverSqrThreeJ2;
1769 
1770  if (TPZExtractVal::val(Lode) < 0.) {
1771  cout << "Lode angle é Menor que ZERO. Valido somente para sig1 > sig2 > sig3 -> 0 < theta < Pi/3 " << endl;
1772  DebugStop();
1773  }
1774  if (TPZExtractVal::val(Lode) > M_PI / 3.) {
1775  cout << "Lode angle é Maior que Pi/3. Valido somente para sig1 > sig2 > sig3 -> 0 < theta < Pi/3 " << endl;
1776  DebugStop();
1777  }
1778 
1779  /*ORIGINAL*/
1780  //Valido somente para sig1 > sig2 > sig3 -> 0 < theta < Pi/3
1781 
1782  eigenval.XX() = I13 + tempCosLode;
1783  eigenval.YY() = I13 + tempCosMinusLode;
1784  eigenval.ZZ() = I13 + tempCosPlusLode;
1785  eigenval.XY() *= T(0.);
1786  eigenval.XZ() *= T(0.);
1787  eigenval.YZ() *= T(0.);
1788 
1789 
1790 
1791 
1792 #ifdef LOG4CXX
1793  {
1794  std::stringstream sout;
1795  sout << "\n TPZTENSOR \n" << endl;
1796  sout << "\n LodeAngle = \n" << Lode << endl;
1797  sout << "\n dLodeAngle= " << dLode << endl;
1798  sout << "\n\n";
1799  LOGPZ_INFO(loggerr, sout.str());
1800  }
1801 #endif
1802 
1803 
1804 
1805  T OneOverTwoJ2 = T(0.5) / J2;
1806  TPZTensor<T> dI13;
1807  dI13.Identity();
1808  dI13 *= T(1. / 3.);
1809 
1810  tempCosLode *= OneOverTwoJ2;
1811  tempCosMinusLode *= OneOverTwoJ2;
1812  tempCosPlusLode *= OneOverTwoJ2;
1813 
1814  dSigma1 = dJ2;
1815  dSigma1 *= tempCosLode;
1816  dSigma1 += dI13;
1817  TPZTensor<T> dLodeAngleTemp(dLode);
1818  dLodeAngleTemp *= sin(Lode) * TwoOverSqrThreeJ2;
1819  dSigma1 -= dLodeAngleTemp;
1820 
1821  dSigma2 = dJ2;
1822  dSigma2 *= tempCosMinusLode;
1823  dSigma2 += dI13;
1824  dLodeAngleTemp = dLode;
1825  dLodeAngleTemp *= sin(pi23 - Lode) * TwoOverSqrThreeJ2;
1826  dSigma2 += dLodeAngleTemp;
1827 
1828  dSigma3 = dJ2;
1829  dSigma3 *= tempCosPlusLode;
1830  dSigma3 += dI13;
1831  dLodeAngleTemp = dLode;
1832  dLodeAngleTemp *= sin(pi23 + Lode) * TwoOverSqrThreeJ2;
1833  dSigma3 -= dLodeAngleTemp;
1834 }
1835 
1836 template <>
1837 inline void TPZTensor<TFad<6, REAL> >::Print(std::ostream &output) const {
1838  output << "XX = " << XX() << "\nXY = " << XY() << "\nXZ = " << XZ() << "\nYY = " << YY() << "\nYZ = " << YZ() << "\nZZ = " << ZZ() << std::endl;
1839 }
1840 
1841 template <>
1842 inline void TPZTensor<TFad<9, REAL> >::Print(std::ostream &output) const {
1843  output << "XX = " << XX() << "\nXY = " << XY() << "\nXZ = " << XZ() << "\nYY = " << YY() << "\nYZ = " << YZ() << "\nZZ = " << ZZ() << std::endl;
1844 }
1845 
1846 template <class T>
1847 inline void TPZTensor<T>::Print(std::ostream &output) const {
1848  output << "XX = " << XX() << " XY = " << XY() << " XZ = " << XZ() << " YY = " << YY() << " YZ = " << YZ() << " ZZ = " << ZZ() << std::endl;
1849 }
1850 
1851 #endif //TPZTENSOR_H
static int & ref(int &number)
Definition: pzextractval.h:58
#define _XZ_
Definition: TPZTensor.h:29
void Print(std::ostream &out=std::cout)
Prints the structural information of the vector object to the output stream. This method will not p...
Definition: pzvec.h:482
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ fabs
Definition: tfadfunc.h:140
void CopyTo(TPZTensor< T1 > &target) const
Definition: TPZTensor.h:819
void Add(const TPZTensor< T1 > &tensor, const T2 &constant)
Definition: TPZTensor.h:757
void CopyFrom(const TPZFMatrix< T > &source)
Definition: TPZTensor.h:833
void Multiply(const T1 &multipl, const T2 &constant)
Definition: TPZTensor.h:766
void Print(std::ostream &out) const
Definition: TPZTensor.h:71
T Norm() const
Definition: TPZTensor.h:854
T & operator()(const int64_t row, const int64_t col)
Definition: TPZTensor.h:359
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
void DeviatoricDiagonal_T(TPZVec< T > &vec) const
Definition: TPZTensor.h:841
TPZManVector< T, 6 > fData
Definition: TPZTensor.h:652
T I1() const
Definition: TPZTensor.h:903
virtual void resize(const int64_t newsize)
Definition: pzvec.h:213
void Write(TPZStream &buf, int withclassid) const override
Method to write to a pzstream.
Definition: TPZTensor.h:688
TPZTensor(const T &Init)
Definition: TPZTensor.h:251
void ComputeEigenvectors(TPZDecomposed &eigensystem) const
Definition: TPZTensor.h:1321
void Read(TPZStream &buf, void *context) override
Method to read the object from a pzstream.
Definition: TPZTensor.h:683
virtual bool SolveEigensystemJacobi(int64_t &numiterations, REAL &tol, TPZVec< TVar > &Eigenvalues, TPZFMatrix< TVar > &Eigenvectors) const
Compute Eigenvalues and Eigenvectors of this matrix. This method is efficient only for small matrice...
Definition: pzmatrix.cpp:1583
void EigenProjection(const TPZVec< T > &EigenVals, int index, const TPZVec< int > &DistinctEigenvalues, TPZTensor< T > &Ei) const
Definition: TPZTensor.h:1381
virtual const TVar & Get(const int64_t row, const int64_t col) const
Get value with bound checking.
Definition: pzmatrix.h:855
void ComputeEigenvectorsInternal(TPZDecomposed &eigensystem) const
Definition: TPZTensor.h:1569
T & YY() const
Definition: TPZTensor.h:578
TPZTensor(const TPZTensor< T > &source)
Definition: TPZTensor.h:257
static void ResidualCheckConv(TPZFMatrix< STATE > &state, TPZFMatrix< STATE > &residual, int icase)
Compute the residual for a particular state.
Definition: TPZTensor.h:165
TVar Dot(const TPZFMatrix< TVar > &A, const TPZFMatrix< TVar > &B)
Implement dot product for matrices.
Definition: pzfmatrix.cpp:2083
void Zero()
Definition: TPZTensor.h:801
void ComputeEigenvector1(const TPZManVector< T, 3 > &eigenvector0, const T &eigenvalue1, TPZManVector< T, 3 > &eigenvector1) const
Definition: TPZTensor.h:1466
clarg::argString input("-if", "input file", "cube1.txt")
This class implements a simple vector storage scheme for a templated class T. Utility.
Definition: pzgeopoint.h:19
REAL val(STATE &number)
Returns value of the variable.
Definition: pzartdiff.h:23
void ComputeEigenvalues(TPZDecomposed &eigensystem, const bool compute_eigenvectors=false) const
Definition: TPZTensor.h:1122
TPZManVector< TPZTensor< T >, 3 > fEigentensors
Definition: TPZTensor.h:50
void DeviatoricDiagonal(TPZVec< T > &vec) const
Definition: TPZTensor.h:849
TPZTensor< T > operator*(const T &multipl) const
Definition: TPZTensor.h:750
void Precondition(REAL &conditionFactor, TPZTensor< T > &A, TPZDecomposed &decomposition) const
Definition: TPZTensor.h:1591
bool AreEqual(const T &val1, const T &val2, const T tol=T(1.e-9)) const
Definition: TPZTensor.h:660
void saxpy(TPZVec< T1 > &x, const TPZVec< T2 > &y, Scalar s)
Performs a saxpy operation: x <- x + s * y.
Definition: pzvec_extras.h:24
T & operator()(const int64_t row, const int64_t col) const
Definition: TPZTensor.h:367
unsigned int fDistinctEigenvalues
Definition: TPZTensor.h:46
int ClassId() const override
Define the class id associated with the class.
Definition: TPZTensor.h:275
void DirectEigenValues(TPZDecomposed &eigensystem, bool compute_eigenvectors) const
Definition: TPZTensor.h:1612
const TPZTensor< T > & operator*=(const T &multipl)
Definition: TPZTensor.h:731
static void TangentCheckConv(TPZFMatrix< STATE > &state, TPZFMatrix< STATE > &tangent, int icase)
Compute the tangent matrix for a particular case.
Definition: TPZTensor.h:128
TPZManVector< unsigned int, 3 > fGeometricMultiplicity
Definition: TPZTensor.h:47
void HaighWestergaard(T &LodeAngle, T &qsi, T &rho) const
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
expr_ expr_ expr_ expr_ acos
Definition: tfadfunc.h:75
sin
Definition: fadfunc.h:63
T & YZ() const
Definition: TPZTensor.h:582
T Det() const
Definition: TPZTensor.h:875
static const double tol
Definition: pzgeoprism.cpp:23
#define LOGPZ_INFO(A, B)
Define log for informations.
Definition: pzlog.h:89
void CopyToTensor(TPZFMatrix< T > &Tensor) const
Definition: TPZTensor.h:988
TPZDecomposed(const TPZDecomposed &copy)
Definition: TPZTensor.h:55
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
TPZTensor< T > operator-(const TPZTensor< T > &source) const
Definition: TPZTensor.h:744
Contains TPZMatrixclass which implements full matrix (using column major representation).
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
static T Polynom(const T &x, const T &I1, const T &I2, const T &I3)
Definition: TPZTensor.h:999
#define _XX_
Definition: TPZTensor.h:27
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
void dJ3(TPZTensor< T > &deriv) const
Definition: TPZTensor.h:956
void EigenSystem(TPZDecomposed &eigensystem) const
Definition: TPZTensor.h:1265
void Lodeangle(TPZTensor< T > &GradLode, T &Lode) const
Definition: TPZTensor.h:1675
#define _YZ_
Definition: TPZTensor.h:31
void dJ2(TPZTensor< T > &Tangent) const
Definition: TPZTensor.h:935
Free store vector implementation.
void sscal(TPZVec< T1 > &x, const Scalar s)
Performs a sscal operation: x <- x * s.
Definition: pzvec_extras.h:49
void Scale(const T2 &constant)
Definition: TPZTensor.h:792
#define _XY_
Definition: TPZTensor.h:28
TPZTensor(const TPZFMatrix< T > &input)
Definition: TPZTensor.h:296
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
Definition: tfadfunc.h:120
void SetUp(const TPZVec< REAL > &Solution)
Definition: TPZTensor.h:810
T J2() const
Definition: TPZTensor.h:927
bool IsZeroTensor(T tol=1.e-9) const
Definition: TPZTensor.h:534
void EigenVector(TPZVec< TPZVec< T > > &eigVec) const
TPZManVector< TPZManVector< T, 3 >, 3 > fEigenvectors
Definition: TPZTensor.h:49
void Adjust(TPZVec< T > &sigIJ, TPZTensor< T > &result) const
adjust the tensor to the given values of I1 and sqj2
Definition: TPZTensor.h:490
void Identity()
Definition: TPZTensor.h:705
void EigenSystemJacobi(TPZDecomposed &eigensystem) const
Definition: TPZTensor.h:1018
T & operator[](int i) const
Definition: TPZTensor.h:590
#define LOGPZ_ERROR(A, B)
Define log for errors (cout)
Definition: pzlog.h:93
static REAL val(const int number)
Definition: pzextractval.h:21
#define _YY_
Definition: TPZTensor.h:30
const TPZTensor< T > & operator+=(const TPZTensor< T > &source)
Definition: TPZTensor.h:717
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
void Print(std::ostream &out) const
Definition: TPZTensor.h:1847
static REAL angle
Angle in radians to test.
Definition: pzsubcmesh.cpp:53
void ApplyStrainComputeElasticStress(TPZTensor< T > &Stress, REAL &K, REAL &G)
Definition: TPZTensor.h:224
#define _ZZ_
Definition: TPZTensor.h:32
void ComputeEigenvector0(const T &eigenvalue, TPZManVector< T, 3 > &eigenvector) const
Definition: TPZTensor.h:1410
void Eigenvalue(TPZTensor< T > &eigenval, TPZTensor< T > &dSigma1, TPZTensor< T > &dSigma2, TPZTensor< T > &dSigma3) const
Definition: TPZTensor.h:1744
TPZFlopCounter pow(const TPZFlopCounter &orig, const TPZFlopCounter &xp)
Returns the power and increments the counter of the power.
Definition: pzreal.h:487
T I2() const
Definition: TPZTensor.h:908
This class implements a stack object. Utility.
Definition: pzcheckmesh.h:14
static T DerivPolynom(const T &x, const T &I1, const T &I2, const T &I3)
Definition: TPZTensor.h:1005
T & XX() const
Definition: TPZTensor.h:566
static int NumCasesCheckConv()
Number of test cases implemented by this class.
Definition: TPZTensor.h:121
T I3() const
Definition: TPZTensor.h:918
TPZTensor< T > operator+(const TPZTensor< T > &source) const
Definition: TPZTensor.h:738
static T & NonNegative(T &value)
Definition: TPZAssert.h:18
static bool IsZeroVal(const T &val, T tol=1.e-9)
Definition: TPZTensor.h:656
TPZDecomposed(const TPZTensor< T > &source)
Definition: TPZTensor.h:67
static T UpdateNewton(const T &x, const T &I1, const T &I2, const T &I3)
Definition: TPZTensor.h:1011
T & XY() const
Definition: TPZTensor.h:570
static STATE gEigval[3]
Definition: TPZTensor.h:125
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
T & ZZ() const
Definition: TPZTensor.h:586
virtual void Print(std::ostream &out) const
Definition: pzmatrix.h:253
int Resize(const int64_t newRows, const int64_t wCols) override
Redimension a matrix, but maintain your elements.
Definition: pzfmatrix.cpp:1016
TPZManVector< T, 3 > fEigenvalues
Definition: TPZTensor.h:48
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
const TPZTensor< T > & operator-=(const TPZTensor< T > &source)
Definition: TPZTensor.h:724
const TPZTensor< T > & operator=(const TPZTensor< T > &source)
Definition: TPZTensor.h:711
Extra utilities for TPZVec. Implementations of the saxpy, sscal, sdot, intercept, max and min functio...
T & XZ() const
Definition: TPZTensor.h:574
REAL ZeroTolerance()
Returns the tolerance to Zero value. Actually: .
Definition: pzreal.h:633
This class defines the interface to save and restore objects from TPZStream objects. Persistency.
Definition: TPZSavable.h:67
TPZFlopCounter cos(const TPZFlopCounter &orig)
Returns the cosine in radians and increments the counter of the Cosine.
Definition: pzreal.h:514
TPZDecomposed & operator=(const TPZDecomposed &copy)
Definition: TPZTensor.h:58
void push_back(const T object)
Definition: pzstack.h:48
const TVar & GetVal(const int64_t row, const int64_t col) const override
Get values without bounds checking This method is faster than "Get" if DEBUG is defined.
Definition: pzfmatrix.h:566
bool IsDiagonal(T tol=1.e-9) const
Definition: TPZTensor.h:544
TPZTensor(const TPZDecomposed &eigensystem)
Definition: TPZTensor.h:263
void S(TPZTensor< T > &s) const
Definition: TPZTensor.h:894
T J3() const
Definition: TPZTensor.h:946
void Cross(const TPZVec< T > &x1, const TPZVec< T > &x2, TPZVec< T > &result)
Definition: pzvec_extras.h:255
virtual void Read(bool &val)
Definition: TPZStream.cpp:91
void dDet(TPZTensor< T > &grad) const
Definition: TPZTensor.h:884
obj
Definition: test.py:225
void Identity_T(TBASE &)
Definition: TPZTensor.h:694