KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
math_utilities.hpp
Go to the documentation of this file.
1 // KRATOS___
2 // // ) )
3 // // ___ ___
4 // // ____ //___) ) // ) )
5 // // / / // // / /
6 // ((____/ / ((____ ((___/ / MECHANICS
7 //
8 // License: geo_mechanics_application/license.txt
9 //
10 // Main authors: JMCarbonell,
11 // Vahid Galavi
12 //
13 
14 #pragma once
15 
16 
17 #ifdef FIND_MAX
18 #undef FIND_MAX
19 #endif
20 
21 #define FIND_MAX(a, b) ((a)>(b)?(a):(b))
22 
23 // System includes
24 #include <cmath>
25 
26 // External includes
27 
28 // Project includes
29 #include "utilities/math_utils.h"
30 #include "geometries/point.h"
32 
33 
34 namespace Kratos
35 {
36 template<class TDataType>
38 {
39 public:
44  typedef Matrix MatrixType;
45 
46  typedef Vector VectorType;
47 
48  typedef unsigned int IndexType;
49 
50  typedef unsigned int SizeType;
51 
53 
55 
57 
59 
60  typedef matrix<Second_Order_Tensor> Matrix_Second_Tensor;
61 
62 
79  static inline bool CardanoFormula(double a, double b, double c, double d, Vector& solution)
80  {
81  solution.resize(3,false);
83 
84  if (a==0)
85  {
86  std::cout<<"This is not a cubic equation: CardanoFormula"<<std::endl;
87 
88  return false;
89  }
90 
91  double p= (3.0*a*c-b*b)/(3.0*a*a);
92 
93  double q= 2.0*b*b*b/(27.0*a*a*a)-b*c/(3.0*a*a)+d/a;
94 
95  double discriminante= p*p*p/27.0+q*q/4.0;
96 
97  if(discriminante>0)
98  {
99  return false;
100  }
101 
102  if(discriminante==0)
103  {
104  if( a == 0 )
105  return false;
106 
107  solution(0)= pow(q/2.0, 1.0/3.0)-b/(3*a);
108  solution(1)= pow(q/2.0, 1.0/3.0)-b/(3*a);
109  solution(2)= pow(-4.0*q, 1.0/3.0)-b/(3*a);
110 
111  return true;
112  }
113 
114  if(p < 0) return false; //in this case the square roots below will be negative. This substitutes with better efficiency lines 107-110
115 
116  solution(0) = -sqrt(-4.0/3.0*p)*cos(1.0/3.0*acos(-q/2.0*sqrt(-27.0/(p*p*p)))+ Globals::Pi / 3.0) -b/(3*a);
117  solution(1) = sqrt(-4.0/3.0*p)*cos(1.0/3.0*acos(-q/2.0*sqrt(-27.0/(p*p*p))))-b/(3*a);
118  solution(2) = -sqrt(-4.0/3.0*p)*cos(1.0/3.0*acos(-q/2.0*sqrt(-27.0/(p*p*p)))- Globals::Pi / 3.0) -b/(3*a);
119 
120 // if(std::isnan<double>(solution(0)) || std::isnan<double>(solution(1))|| std::isnan<double>(solution(2)))
121 // {
122 // return false;
123 // }
124 
125  return true;
126  }
140  static inline Vector EigenValues(const Matrix& A, double tolerance, double zero)
141  {
142  int dim= A.size1();
143 
144  Matrix Convergence(2,dim);
145  noalias(Convergence) = ZeroMatrix(2,dim);
146 
147  double delta = 0.0;
148 
149  double abs = 0.0;
150 
151  Vector Result(dim);
152  noalias(Result) = ZeroVector(dim);
153 
154  Matrix HelpA(dim,dim);
155  noalias(HelpA) = ZeroMatrix(dim, dim);
156 
157  Matrix HelpQ(dim,dim);
158  noalias(HelpQ) = ZeroMatrix(dim, dim);
159 
160  Matrix HelpR(dim,dim);
161  noalias(HelpR) = ZeroMatrix(dim, dim);
162 
163  HelpA=A;
164 
165  bool is_converged=false;
166  unsigned int max_iters = 10;
167  unsigned int iter = 0;
168 
169  while(is_converged == false && iter<max_iters )
170  {
171  double shift= HelpA((dim-1),(dim-1));
172  //
173  for(int i=0; i<dim; i++)
174  {
175  HelpA(i,i) = HelpA(i,i)- shift;
176  }
177 
179 
180  HelpA= ZeroMatrix(dim, dim);
181 
182  for(int i=0; i<dim; i++)
183  {
184  HelpA(i,i) += shift;
185  for(int j=0; j< dim; j++)
186  {
187  for(int k=0; k< dim; k++)
188  {
189  HelpA(i,j) += HelpR(i,k)*HelpQ(k,j);
190  }
191  }
192  }
193 
194  delta= 0.0;
195 
196  abs = 0.0;
197 
198  for(int i=0; i<dim; i++)
199  {
200  Convergence(0,i)=Convergence(1,i);
201  Convergence(1,i)=HelpA(i,i);
202  delta+= (Convergence(1,i)-Convergence(0,i))*(Convergence(1,i)-Convergence(0,i));
203  abs+=(Convergence(1,i))*(Convergence(1,i));
204  }
205 
206  delta= sqrt(delta);
207 
208  abs=sqrt(abs);
209 
210  if(abs < zero)
211  abs=1.0;
212 
213  if(delta < zero || (delta/abs) < tolerance)
214  is_converged=true;
215 
216  iter++;
217  }
218 
219 
220  for(int i=0; i<dim; i++)
221  {
222  Result(i)= HelpA(i,i);
223 
224  if(fabs(Result(i)) <zero)
225  Result(i)=0.0;
226  }
227 
228  return Result;
229  }
230 
241  static inline Vector EigenValuesDirectMethod(const Matrix& A)
242  {
243  // Given a real symmetric 3x3 matrix A, compute the eigenvalues
244  int dim= A.size1();
245  Vector Result(dim);
246  noalias(Result) = ZeroVector(dim);
247 
248  const double p1 = A(0,1)*A(0,1) + A(0,2)*A(0,2) + A(1,2)*A(1,2);
249  if (p1 == 0)
250  {//A is diagonal.
251  Result[0] = A(0,0);
252  Result[1] = A(1,1);
253  Result[2] = A(2,2);
254  return Result;
255  }
256 
257  const double q = (A(0,0) + A(1,1) + A(2,2)) / 3.0;
258  const double p2 = (A(0,0) - q) * (A(0,0) - q) + (A(1,1) - q) * (A(1,1) - q) + (A(2,2) - q) * (A(2,2) - q) + 2.0 * p1;
259  const double p = sqrt(p2 / 6.0);
260 
261  Matrix B(3,3);
262  const double inv_p = 1.0/p;
263 
264  // B = (1 / p) * (A - q * I) where I is the identity matrix
265  B(0,0) = inv_p * (A(0,0) - q);
266  B(1,1) = inv_p * (A(1,1) - q);
267  B(2,2) = inv_p * (A(2,2) - q);
268  B(0,1) = inv_p * A(0,1);
269  B(1,0) = inv_p * A(1,0);
270  B(0,2) = inv_p * A(0,2);
271  B(2,0) = inv_p * A(2,0);
272  B(1,2) = inv_p * A(1,2);
273  B(2,1) = inv_p * A(2,1);
274 
275  //r = det(B) / 2
276  double r = 0.5 * ( B(0,0)*B(1,1)*B(2,2) + B(0,1)*B(1,2)*B(2,0) + B(1,0)*B(2,1)*B(0,2) - B(2,0)*B(1,1)*B(0,2) - B(1,0)*B(0,1)*B(2,2) - B(0,0)*B(2,1)*B(1,2) );
277 
278  // In exact arithmetic for a symmetric matrix -1 <= r <= 1
279  // but computation error can leave it slightly outside this range.
280  double phi = 0.0;
281  if (r <= -1) { phi = Globals::Pi / 3.0; }
282  else if (r >= 1) { phi = 0.0; }
283  else { phi = acos(r) / 3.0;}
284 
285  // the eigenvalues satisfy eig3 <= eig2 <= eig1
286  Result[0] = q + 2.0 * p * cos(phi);
287  Result[2] = q + 2.0 * p * cos(phi + (2.0 * Globals::Pi / 3.0));
288  Result[1] = 3.0 * q - Result[0] - Result[2]; //% since trace(A) = eig1 + eig2 + eig3
289 
290  return Result;
291  }
292 
293 
305  static inline void QRFactorization(const MatrixType& A, MatrixType& Q, MatrixType& R)
306  {
307 
308  //QR Factorization with Householder-Algo
309  int dim= A.size1();
310 
311  Vector y(dim);
312 
313  Vector w(dim);
314 
315  R.resize(dim,dim,false);
316 
318 
319  Q.resize(dim,dim,false);
320 
322 
323  Matrix Help(A.size1(),A.size2());
324  noalias(Help) = A;
325 
326  Matrix unity(dim,dim);
327  noalias(unity) = ZeroMatrix(dim,dim);
328 
329  for(int j=0; j<dim; j++)
330  unity(j,j)=1.0;
331 
332  std::vector<Matrix> HelpQ(dim-1);
333 
334  std::vector<Matrix> HelpR(dim-1);
335 
336  for(int i=0; i< dim-1; i++)
337  {
338  HelpQ[i].resize(dim,dim,false);
339  HelpR[i].resize(dim,dim,false);
340  noalias(HelpQ[i])= unity;
341  noalias(HelpR[i])= ZeroMatrix(dim,dim);
342  }
343 
344  for(int iteration=0; iteration< dim-1; iteration++)
345  {
346  //Vector y
347  for(int i=iteration; i<dim; i++)
348  y(i)= Help(i,iteration);
349 
350 
351  //Helpvalue l
352  double normy=0.0;
353 
354  for(int i=iteration; i<dim; i++)
355  normy += y(i)*y(i);
356 
357  normy= sqrt(normy);
358 
359  double l= sqrt((normy*(normy+fabs(y(iteration))))/2);
360 
361  double k=0.0;
362 
363  if(y[iteration] !=0)
364  k= - y(iteration)/fabs(y(iteration))*normy;
365  else
366  k= -normy;
367 
368  for(int i=iteration; i<dim; i++)
369  {
370  double e=0;
371 
372  if(i==iteration)
373  e=1;
374 
375  w(i)= 1/(2*l)*(y(i)-k*e);
376  }
377 
378  for(int i=iteration; i<dim; i++)
379  for(int j=iteration; j<dim; j++)
380  HelpQ[iteration](i,j)= unity(i,j)- 2*w(i)*w(j);
381 
382 
383  for(int i=iteration; i<dim; i++)
384  for(int j=iteration; j<dim; j++)
385  for(int k=iteration; k<dim; k++)
386  HelpR[iteration](i,j)+= HelpQ[iteration](i,k)*Help(k,j);
387 
388  Help= HelpR[iteration];
389 
390  }
391 
392  //Assembling R
393  for(int k=0; k<dim-1; k++)
394  {
395  for(int i=k; i<dim; i++)
396  for(int j=k; j<dim; j++)
397  R(i,j) =HelpR[k](i,j);
398 
399  }
400 
401 
402  for(int k=1; k<dim-1; k++)
403  {
404  for(int i=0; i<dim; i++)
405  for(int j=0; j<dim; j++)
406  for(int l=0; l<dim; l++)
407  Q(i,j)+= HelpQ[(k-1)](i,l)*HelpQ[k](l,j);
408  noalias(HelpQ[k])=Q;
409  }
410  if(dim-1==1)
411  noalias(Q)=HelpQ[0];
412 
413  }
414 
430  static inline void EigenVectors(const MatrixType& A,
431  MatrixType& vectors,
432  VectorType& lambda,
433  double zero_tolerance =1e-9,
434  int max_iterations = 10)
435  {
436  Matrix Help= A;
437 
438  for(int i=0; i<3; i++)
439  for(int j=0; j<3; j++)
440  Help(i,j)= Help(i,j);
441 
442 
443  vectors.resize(Help.size1(),Help.size2(),false);
444 
445  lambda.resize(Help.size1(),false);
446 
447  Matrix HelpDummy(Help.size1(),Help.size2());
448 
449  bool is_converged = false;
450 
451  Matrix unity(Help.size1(),Help.size2());
452  noalias(unity) = ZeroMatrix(Help.size1(),Help.size2());
453 
454  for(unsigned int i=0; i< Help.size1(); i++)
455  unity(i,i)= 1.0;
456 
457  Matrix V= unity;
458 
459  Matrix VDummy(Help.size1(),Help.size2());
460 
461  Matrix Rotation(Help.size1(),Help.size2());
462 
463 
464  for(int iterations=0; iterations<max_iterations; iterations++)
465  {
466 
467  is_converged= true;
468 
469  double a= 0.0;
470 
471  unsigned int index1= 0;
472 
473  unsigned int index2= 1;
474 
475  for(unsigned int i=0; i< Help.size1(); i++)
476  {
477  for(unsigned int j=(i+1); j< Help.size2(); j++)
478  {
479  if((fabs(Help(i,j)) > a ) && (fabs(Help(i,j)) > zero_tolerance))
480  {
481  a= fabs(Help(i,j));
482 
483  index1= i;
484  index2= j;
485 
486  is_converged= false;
487  }
488  }
489  }
490 
491 // KRATOS_WATCH( Help )
492 
493  if(is_converged)
494  break;
495 
496  //Calculation of Rotationangle
497 
498  double gamma= (Help(index2,index2)-Help(index1,index1))/(2*Help(index1,index2));
499 
500  double u=1.0;
501 
502  if(fabs(gamma) > zero_tolerance && fabs(gamma)< (1/zero_tolerance))
503  {
504  u= gamma/fabs(gamma)*1.0/(fabs(gamma)+sqrt(1.0+gamma*gamma));
505  }
506  else
507  {
508  if (fabs(gamma)>= (1.0/zero_tolerance))
509  u= 0.5/gamma;
510  }
511 
512  double c= 1.0/(sqrt(1.0+u*u));
513 
514  double s= c*u;
515 
516  double teta= s/(1.0+c);
517 
518  //Ratotion of the Matrix
519  HelpDummy= Help;
520 
521  HelpDummy(index2,index2)= Help(index2,index2)+u*Help(index1,index2);
522  HelpDummy(index1,index1)= Help(index1,index1)-u*Help(index1,index2);
523  HelpDummy(index1,index2)= 0.0;
524  HelpDummy(index2,index1)= 0.0;
525 
526  for(unsigned int i=0; i<Help.size1(); i++)
527  {
528  if((i!= index1) && (i!= index2))
529  {
530  HelpDummy(index2,i)=Help(index2,i)+s*(Help(index1,i)- teta*Help(index2,i));
531  HelpDummy(i,index2)=Help(index2,i)+s*(Help(index1,i)- teta*Help(index2,i));
532 
533  HelpDummy(index1,i)=Help(index1,i)-s*(Help(index2,i)+ teta*Help(index1,i));
534  HelpDummy(i,index1)=Help(index1,i)-s*(Help(index2,i)+ teta*Help(index1,i));
535  }
536  }
537 
538 
539  Help= HelpDummy;
540 
541  //Calculation of the eigenvectors V
542  Rotation =unity;
543  Rotation(index2,index1)=-s;
544  Rotation(index1,index2)=s;
545  Rotation(index1,index1)=c;
546  Rotation(index2,index2)=c;
547 
548 // Help.resize(A.size1(),A.size1(),false);
549 // noalias(Help)=ZeroMatrix(A.size1(),A.size1());
550 
551  noalias(VDummy) = ZeroMatrix(Help.size1(), Help.size2());
552 
553  for(unsigned int i=0; i< Help.size1(); i++)
554  {
555  for(unsigned int j=0; j< Help.size1(); j++)
556  {
557  for(unsigned int k=0; k< Help.size1(); k++)
558  {
559  VDummy(i,j) += V(i,k)*Rotation(k,j);
560  }
561  }
562  }
563  V= VDummy;
564 
565 // Matrix VTA(3,3);
566 // noalias(VTA) = ZeroMatrix(3,3);
567 // for(int i=0; i< Help.size1(); i++)
568 // {
569 // for(int j=0; j< Help.size1(); j++)
570 // {
571 // for(int k=0; k< Help.size1(); k++)
572 // {
573 // VTA(i,j) += V(k,i)*A(k,j);
574 // }
575 // }
576 // }
577 //
578 // for(int i=0; i< Help.size1(); i++)
579 // {
580 // for(int j=0; j< Help.size1(); j++)
581 // {
582 // for(int k=0; k< Help.size1(); k++)
583 // {
584 // Help(i,j) += VTA(i,k)*V(k,j);
585 // }
586 // }
587 // }
588 
589  }
590 
591  if(!(is_converged))
592  {
593  std::cout<<"########################################################"<<std::endl;
594  std::cout<<"Max_Iterations exceed in Jacobi-Seidel-Iteration (eigenvectors)"<<std::endl;
595  std::cout<<"########################################################"<<std::endl;
596  }
597 
598  for(unsigned int i=0; i< Help.size1(); i++)
599  {
600  for(unsigned int j=0; j< Help.size1(); j++)
601  {
602  vectors(i,j)= V(j,i);
603  }
604  }
605 
606  for(unsigned int i=0; i<Help.size1(); i++)
607  lambda(i)= Help(i,i);
608 
609  }
610 
611 
636  static inline MatrixType StrainVectorToTensor( const VectorType& Strains )
637  {
638  KRATOS_TRY
639 
640  Matrix StrainTensor;
641  //KRATOS_WATCH( Strains )
642  if (Strains.size()==3)
643  {
644  StrainTensor.resize(2,2, false);
645  //KRATOS_WATCH( StrainTensor )
646  StrainTensor(0,0) = Strains[0];
647  StrainTensor(0,1) = 0.5*Strains[2];
648  StrainTensor(1,0) = 0.5*Strains[2];
649  StrainTensor(1,1) = Strains[1];
650  }
651  else if (Strains.size()==6)
652  {
653  StrainTensor.resize(3,3, false);
654  StrainTensor(0,0) = Strains[0];
655  StrainTensor(0,1) = 0.5*Strains[3];
656  StrainTensor(0,2) = 0.5*Strains[5];
657  StrainTensor(1,0) = 0.5*Strains[3];
658  StrainTensor(1,1) = Strains[1];
659  StrainTensor(1,2) = 0.5*Strains[4];
660  StrainTensor(2,0) = 0.5*Strains[5];
661  StrainTensor(2,1) = 0.5*Strains[4];
662  StrainTensor(2,2) = Strains[2];
663  }
664 
665  //KRATOS_WATCH( StrainTensor )
666  return StrainTensor;
667  KRATOS_CATCH( "" )
668  }
669 
670  static inline Vector TensorToStrainVector( const Matrix& Tensor )
671  {
672  KRATOS_TRY
673  Vector StrainVector;
674 
675 
676  if (Tensor.size1()==2)
677  {
678  StrainVector.resize(3);
679  noalias(StrainVector) = ZeroVector(3);
680  StrainVector(0) = Tensor(0,0);
681  StrainVector(1) = Tensor(1,1);
682  StrainVector(2) = 2.00*Tensor(0,1);
683  }
684  else if (Tensor.size1()==3)
685  {
686  StrainVector.resize(6);
687  noalias(StrainVector) = ZeroVector(6);
688  StrainVector(0) = Tensor(0,0);
689  StrainVector(1) = Tensor(1,1);
690  StrainVector(2) = Tensor(2,2);
691  StrainVector(3) = 2.00*Tensor(0,1);
692  StrainVector(4) = 2.00*Tensor(1,2);
693  StrainVector(5) = 2.00*Tensor(0,2);
694  }
695 
696 
697  return StrainVector;
698  KRATOS_CATCH( "" )
699  }
700 
701 
702 
708  static double NormTensor(Matrix& Tensor)
709  {
710  double result=0.0;
711  for(unsigned int i=0; i< Tensor.size1(); i++)
712  for(unsigned int j=0; j< Tensor.size2(); j++)
713  result+= Tensor(i,j)*Tensor(i,j);
714 
715  result= sqrt(result);
716 
717  return result;
718  }
719 
725  static inline void VectorToTensor(const Vector& Stress,Matrix& Tensor)
726  {
727  if(Stress.size()==6)
728  {
729  Tensor.resize(3,3);
730  Tensor(0,0)= Stress(0);
731  Tensor(0,1)= Stress(3);
732  Tensor(0,2)= Stress(5);
733  Tensor(1,0)= Stress(3);
734  Tensor(1,1)= Stress(1);
735  Tensor(1,2)= Stress(4);
736  Tensor(2,0)= Stress(5);
737  Tensor(2,1)= Stress(4);
738  Tensor(2,2)= Stress(2);
739  }
740  if(Stress.size()==3)
741  {
742  Tensor.resize(2,2);
743  Tensor(0,0)= Stress(0);
744  Tensor(0,1)= Stress(2);
745  Tensor(1,0)= Stress(2);
746  Tensor(1,1)= Stress(1);
747  }
748 
749  }
750 
756  static void TensorToVector( const Matrix& Tensor, Vector& Vector)
757  {
758  //if(Vector.size()!= 6)
759  unsigned int dim = Tensor.size1();
760  if (dim==3)
761  {
762  Vector.resize(6,false);
763  Vector(0)= Tensor(0,0);
764  Vector(1)= Tensor(1,1);
765  Vector(2)= Tensor(2,2);
766  Vector(3)= Tensor(0,1);
767  Vector(4)= Tensor(1,2);
768  Vector(5)= Tensor(2,0);
769  }
770  else if(dim==2)
771  {
772  Vector.resize(3,false);
773  Vector(0)= Tensor(0,0);
774  Vector(1)= Tensor(1,1);
775  Vector(2)= Tensor(0,1);
776  }
777 
778  }
779 
780  static inline void TensorToMatrix(Fourth_Order_Tensor& Tensor,Matrix& Matrix)
781  {
782 
783 
784  // Simetrias seguras
785  // Cijkl = Cjilk;
786  // Cijkl = Cklji;
787  if (Tensor[0].size()== 3)
788  {
789  // Tensor de cuarto orden cuyos componentes correspondes a una matriz de 3x3
790  if(Matrix.size1()!=6 || Matrix.size2()!=6)
791  Matrix.resize(6,6,false);
792  Matrix(0,0) = Tensor[0][0](0,0);
793  Matrix(0,1) = Tensor[0][0](1,1);
794  Matrix(0,2) = Tensor[0][0](2,2);
795  Matrix(0,3) = Tensor[0][0](0,1);
796  Matrix(0,4) = Tensor[0][0](0,2);
797  Matrix(0,5) = Tensor[0][0](1,2);
798 
799  Matrix(1,0) = Tensor[1][1](0,0);
800  Matrix(1,1) = Tensor[1][1](1,1);
801  Matrix(1,2) = Tensor[1][1](2,2);
802  Matrix(1,3) = Tensor[1][1](0,1);
803  Matrix(1,4) = Tensor[1][1](0,2);
804  Matrix(1,5) = Tensor[1][1](1,2);
805 
806  Matrix(2,0) = Tensor[2][2](0,0);
807  Matrix(2,1) = Tensor[2][2](1,1);
808  Matrix(2,2) = Tensor[2][2](2,2);
809  Matrix(2,3) = Tensor[2][2](0,1);
810  Matrix(2,4) = Tensor[2][2](0,2);
811  Matrix(2,5) = Tensor[2][2](1,2);
812 
813  Matrix(3,0) = Tensor[0][1](0,0);
814  Matrix(3,1) = Tensor[0][1](1,1);
815  Matrix(3,2) = Tensor[0][1](2,2);
816  Matrix(3,3) = Tensor[0][1](0,1);
817  Matrix(3,4) = Tensor[0][1](0,2);
818  Matrix(3,5) = Tensor[0][1](1,2);
819 
820  Matrix(4,0) = Tensor[0][2](0,0);
821  Matrix(4,1) = Tensor[0][2](1,1);
822  Matrix(4,2) = Tensor[0][2](2,2);
823  Matrix(4,3) = Tensor[0][2](0,1);
824  Matrix(4,4) = Tensor[0][2](0,2);
825  Matrix(4,5) = Tensor[0][2](1,2);
826 
827  Matrix(5,0) = Tensor[1][2](0,0);
828  Matrix(5,1) = Tensor[1][2](1,1);
829  Matrix(5,2) = Tensor[1][2](2,2);
830  Matrix(5,3) = Tensor[1][2](0,1);
831  Matrix(5,4) = Tensor[1][2](0,2);
832  Matrix(5,5) = Tensor[1][2](1,2);
833  }
834  else
835  {
836  // Tensor de cuarto orden cuyos componentes correspondes a una matriz de 2x2
837  if(Matrix.size1()!=3 || Matrix.size2()!=3)
838  Matrix.resize(3,3,false);
839  Matrix(0,0) = Tensor[0][0](0,0);
840  Matrix(0,1) = Tensor[0][0](1,1);
841  Matrix(0,2) = Tensor[0][0](0,1);
842  Matrix(1,0) = Tensor[1][1](0,0);
843  Matrix(1,1) = Tensor[1][1](1,1);
844  Matrix(1,2) = Tensor[1][1](0,1);
845  Matrix(2,0) = Tensor[0][1](0,0);
846  Matrix(2,1) = Tensor[0][1](1,1);
847  Matrix(2,2) = Tensor[0][1](0,1);
848 
849  }
850 
851  }
852 
858  static void MatrixToTensor(MatrixType& A,std::vector<std::vector<Matrix> >& Tensor)
859  {
860  int help1 = 0;
861  int help2 = 0;
862  double coeff = 1.0;
863 
864  Tensor.resize(3);
865 
866  for(unsigned int i=0; i<3; i++)
867  {
868  Tensor[i].resize(3);
869  for(unsigned int j=0; j<3; j++)
870  {
871  Tensor[i][j].resize(3,3,false);
872  noalias(Tensor[i][j])= ZeroMatrix(3,3);
873  for(unsigned int k=0; k<3; k++)
874  for(unsigned int l=0; l<3; l++)
875  {
876  if(i==j) help1= i;
877  else
878  {
879  if((i==0 && j==1) || (i==1 && j==0)) help1= 3;
880  if((i==1 && j==2) || (i==2 && j==1)) help1= 4;
881  if((i==2 && j==0) || (i==0 && j==2)) help1= 5;
882  }
883  if(k==l)
884  {
885  help2= k;
886  coeff=1.0;
887  }
888  else
889  {
890  coeff=0.5;
891  if((k==0 && l==1) || (k==1 && l==0)) help2= 3;
892  if((k==1 && l==2) || (k==2 && l==1)) help2= 4;
893  if((k==2 && l==0) || (k==0 && l==2)) help2= 5;
894  }
895 
896  Tensor[i][j](k,l)= A(help1,help2)*coeff;
897  }
898  }
899  }
900 
901 
902  }
909  {
910  int help1 = 0;
911  int help2 = 0;
912  double coeff = 1.0;
913  std::fill(Tensor.begin(), Tensor.end(), 0.0);
914  for(unsigned int i=0; i<3; i++)
915  {
916  for(unsigned int j=0; j<3; j++)
917  {
918  for(unsigned int k=0; k<3; k++)
919  for(unsigned int l=0; l<3; l++)
920  {
921  if(i==j) help1= i;
922  else
923  {
924  if((i==0 && j==1) || (i==1 && j==0)) help1= 3;
925  if((i==1 && j==2) || (i==2 && j==1)) help1= 4;
926  if((i==2 && j==0) || (i==0 && j==2)) help1= 5;
927  }
928  if(k==l)
929  {
930  help2= k;
931  coeff=1.0;
932  }
933  else
934  {
935  coeff=0.5;
936  if((k==0 && l==1) || (k==1 && l==0)) help2= 3;
937  if((k==1 && l==2) || (k==2 && l==1)) help2= 4;
938  if((k==2 && l==0) || (k==0 && l==2)) help2= 5;
939  }
940 
941  Tensor[i*27+j*9+k*3+l]= A(help1,help2)*coeff;
942  }
943  }
944  }
945 
946 
947  }
953  static void TensorToMatrix(std::vector<std::vector<Matrix> >& Tensor,Matrix& Matrix)
954  {
955  int help1 = 0;
956  int help2 = 0;
957  int help3 = 0;
958  int help4 = 0;
959  double coeff = 1.0;
960 
961  if(Matrix.size1()!=6 || Matrix.size2()!=6)
962  Matrix.resize(6,6,false);
963 
964  for(unsigned int i=0; i<6; i++)
965  for(unsigned int j=0; j<6; j++)
966  {
967  if(i<3)
968  {
969  help1= i;
970  help2= i;
971  }
972  else
973  {
974  if(i==3)
975  {
976  help1= 0;
977  help2= 1;
978  }
979  if(i==4)
980  {
981  help1= 1;
982  help2= 2;
983  }
984  if(i==5)
985  {
986  help1= 2;
987  help2= 0;
988  }
989  }
990 
991  if(j<3)
992  {
993  help3= j;
994  help4= j;
995  coeff= 1.0;
996  }
997  else
998  {
999  if(j==3)
1000  {
1001  help3= 0;
1002  help4= 1;
1003  }
1004  if(j==4)
1005  {
1006  help3= 1;
1007  help4= 2;
1008  }
1009  if(j==5)
1010  {
1011  help3= 2;
1012  help4= 0;
1013  }
1014  coeff= 2.0;
1015  }
1016 
1017  Matrix(i,j)= Tensor[help1][help2](help3,help4)*coeff;
1018  }
1019 
1020  }
1021 
1027  static void TensorToMatrix( const array_1d<double, 81>& Tensor, Matrix& Matrix )
1028  {
1029  if(Matrix.size1()!=6 || Matrix.size2()!=6)
1030  Matrix.resize(6,6,false);
1031 
1032  Matrix(0,0) = Tensor[0];
1033  Matrix(0,1) = Tensor[4];
1034  Matrix(0,2) = Tensor[8];
1035  Matrix(0,3) = 2.0*Tensor[1];
1036  Matrix(0,4) = 2.0*Tensor[5];
1037  Matrix(0,5) = 2.0*Tensor[6];
1038 
1039  Matrix(1,0) = Tensor[36];
1040  Matrix(1,1) = Tensor[40];
1041  Matrix(1,2) = Tensor[44];
1042  Matrix(1,3) = 2.0*Tensor[37];
1043  Matrix(1,4) = 0.0*Tensor[41];
1044  Matrix(1,5) = 0.0*Tensor[42];
1045 
1046  Matrix(2,0) = Tensor[72];
1047  Matrix(2,1) = Tensor[76];
1048  Matrix(2,2) = Tensor[80];
1049  Matrix(2,3) = 2.0*Tensor[73];
1050  Matrix(2,4) = 2.0*Tensor[77];
1051  Matrix(2,5) = 2.0*Tensor[78];
1052 
1053  Matrix(3,0) = Tensor[9];
1054  Matrix(3,1) = Tensor[13];
1055  Matrix(3,2) = Tensor[18];
1056  Matrix(3,3) = 2.0*Tensor[10];
1057  Matrix(3,4) = 2.0*Tensor[14];
1058  Matrix(3,5) = 2.0*Tensor[15];
1059 
1060  Matrix(4,0) = Tensor[45];
1061  Matrix(4,1) = Tensor[49];
1062  Matrix(4,2) = Tensor[53];
1063  Matrix(4,3) = 2.0*Tensor[46];
1064  Matrix(4,4) = 0.0*Tensor[50];
1065  Matrix(4,5) = 0.0*Tensor[51];
1066 
1067  Matrix(5,0) = Tensor[54];
1068  Matrix(5,1) = Tensor[58];
1069  Matrix(5,2) = Tensor[62];
1070  Matrix(5,3) = 2.0*Tensor[55];
1071  Matrix(5,4) = 2.0*Tensor[59];
1072  Matrix(5,5) = 2.0*Tensor[60];
1073 
1074  }
1079  static void DeviatoricUnity(std::vector<std::vector<Matrix> >& Unity)
1080  {
1081  Unity.resize(3);
1082 
1083  Matrix kronecker(3,3);
1084  noalias(kronecker)=ZeroMatrix(3,3);
1085  for(unsigned int i=0; i<3; i++)
1086  {
1087  kronecker(i,i)=1;
1088  }
1089 
1090  for(unsigned int i=0; i<3; i++)
1091  {
1092  Unity[i].resize(3);
1093  for(unsigned int j=0; j<3; j++)
1094  {
1095  Unity[i][j].resize(3,3,false);
1096  noalias(Unity[i][j])= ZeroMatrix(3,3);
1097 
1098  for(unsigned int k=0; k<3; k++)
1099  {
1100  for(unsigned int l=0; l<3; l++)
1101  {
1102  Unity[i][j](k,l)=kronecker(i,k)*kronecker(j,l)
1103  -1.0/3.0*kronecker(i,j)*kronecker(k,l);
1104  }
1105  }
1106  }
1107  }
1108  }
1109 
1115  {
1116  Matrix kronecker(3,3);
1117  noalias(kronecker)=ZeroMatrix(3,3);
1118  for(unsigned int i=0; i<3; i++)
1119  {
1120  kronecker(i,i)=1;
1121  }
1122 
1123  for(unsigned int i=0; i<3; i++)
1124  for(unsigned int j=0; j<3; j++)
1125  for(unsigned int k=0; k<3; k++)
1126  for(unsigned int l=0; l<3; l++)
1127  Unity[27*i+9*j+3*k+l]=kronecker(i,k)*kronecker(j,l)
1128  -1.0/3.0*kronecker(i,j)*kronecker(k,l);
1129  }
1130 
1141  static bool Clipping(std::vector<Point* >& clipping_points,std::vector<Point* >& subjected_points, std::vector<Point* >& result_points, double tolerance)
1142  {
1143  result_points= subjected_points;
1144  Vector actual_edge(3);
1145  Vector actual_normal(3);
1146  std::vector<Point* > temp_results;
1147  bool is_visible= false;
1148  for(unsigned int clipp_edge=0; clipp_edge<clipping_points.size(); clipp_edge++)
1149  {
1150  temp_results.clear();
1151  unsigned int index_clipp_2=0;
1152  if(clipp_edge< (clipping_points.size()-1))
1153  index_clipp_2= clipp_edge+1;
1154  //define clipping edge vector
1155  noalias(actual_edge)= *(clipping_points[clipp_edge])-*(clipping_points[index_clipp_2]);
1156  noalias(actual_edge)= actual_edge/sqrt(inner_prod(actual_edge,actual_edge));
1157 
1158  //define normal on clipping-edge vector towards visible side
1159  if(clipp_edge< (clipping_points.size()-2))
1160  actual_normal=*(clipping_points[clipp_edge+2])-(*(clipping_points[clipp_edge])+actual_edge*inner_prod((*(clipping_points[clipp_edge+2])-*(clipping_points[clipp_edge])),actual_edge));
1161  else if(clipp_edge< (clipping_points.size()-1))
1162  actual_normal=*(clipping_points[0])-(*(clipping_points[clipp_edge])+actual_edge*inner_prod((*(clipping_points[0])-*(clipping_points[clipp_edge])),actual_edge));
1163  else
1164  actual_normal=*(clipping_points[1])-(*(clipping_points[clipp_edge])+actual_edge*inner_prod((*(clipping_points[1])-*(clipping_points[clipp_edge])),actual_edge));
1165 
1166  noalias(actual_normal)=actual_normal/(sqrt(inner_prod(actual_normal,actual_normal)));
1167 
1168  //test if the first point is visible or unvisible
1169  if( inner_prod((*(result_points[0])-*(clipping_points[clipp_edge])), actual_normal)> tolerance)
1170  {
1171  is_visible= true;
1172  }
1173  else
1174  {
1175  is_visible= false;
1176  }
1177 
1178  for(unsigned int subj_edge=0; subj_edge< result_points.size(); subj_edge++)
1179  {
1180  unsigned int index_subj_2=0;
1181 
1182  if(subj_edge< (result_points.size()-1))
1183  index_subj_2= subj_edge+1;
1184 
1185  //Test whether the points of the actual subj_edge lay on clipp_edge
1186  if(fabs(inner_prod((*(result_points[subj_edge])-(*(clipping_points[clipp_edge]))), actual_normal))<= tolerance)
1187  {
1188  temp_results.push_back(result_points[subj_edge]);
1189  if( inner_prod((*(result_points[index_subj_2])-*(clipping_points[clipp_edge])), actual_normal)> tolerance)
1190  is_visible= true;
1191  else
1192  is_visible= false;
1193 
1194  continue;
1195  }
1196  //Calculate minimal distance between the two points
1197  Vector b(2);
1198  b(0)= -inner_prod((*(result_points[index_subj_2])-*(result_points[subj_edge])),(*(result_points[subj_edge])-*(clipping_points[clipp_edge])));
1199  b(1)= inner_prod((*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])),(*(result_points[subj_edge])-*(clipping_points[clipp_edge])));
1200  Matrix A(2,2);
1201  A(0,0)=inner_prod((*(result_points[index_subj_2])-*(result_points[subj_edge])),(*(result_points[index_subj_2])-*(result_points[subj_edge])));
1202  A(0,1)=-inner_prod((*(result_points[index_subj_2])-*(result_points[subj_edge])),(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])));
1203  A(1,0)= A(0,1);
1204  A(1,1)=inner_prod(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge]),*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge]));
1205  Vector coeff(2);
1206  coeff(0)=1.0/A(0,0)*(b(0)-A(0,1)/(A(1,1)-A(0,1)*A(1,0)/A(0,0))*(b(1)-b(0)*A(1,0)/A(0,0)));
1207  coeff(1)=1.0/(A(1,1)-A(0,1)*A(1,0)/A(0,0))*(b(1)-b(0)*A(1,0)/A(0,0));
1208 
1209 
1210  //TEST on distance to endpoints of the line
1211  Vector dist_vec(3);
1212  noalias(dist_vec)= *(result_points[subj_edge])+coeff(0)*(*(result_points[index_subj_2])-*(result_points[subj_edge]))-(*(clipping_points[clipp_edge])+coeff(1)*(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])));
1213 
1214  if( coeff(0) > tolerance && coeff(0) < (1-tolerance)&& (sqrt(inner_prod(dist_vec,dist_vec))< tolerance))
1215  {
1216  if(is_visible)
1217  temp_results.push_back(result_points[subj_edge]);
1218 
1219  temp_results.push_back(new Point((*(clipping_points[clipp_edge])+coeff(1)*(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])))));
1220 
1221  is_visible= !is_visible;
1222 
1223  continue;
1224  }
1225  if(is_visible)
1226  temp_results.push_back(result_points[subj_edge]);
1227  }
1228  result_points=temp_results;
1229  }
1230  if(result_points.size()==0)
1231  return false;
1232  else
1233  return true;
1234  }
1235 };// class GeoMechanicsMathUtilities
1236 
1237 }
Definition: math_utilities.hpp:38
Vector VectorType
Definition: math_utilities.hpp:46
static void VectorToTensor(const Vector &Stress, Matrix &Tensor)
Definition: math_utilities.hpp:725
static bool CardanoFormula(double a, double b, double c, double d, Vector &solution)
Definition: math_utilities.hpp:79
static Vector EigenValues(const Matrix &A, double tolerance, double zero)
Definition: math_utilities.hpp:140
static double NormTensor(Matrix &Tensor)
Definition: math_utilities.hpp:708
static void MatrixToTensor(MatrixType &A, std::vector< std::vector< Matrix > > &Tensor)
Definition: math_utilities.hpp:858
unsigned int SizeType
Definition: math_utilities.hpp:50
static void DeviatoricUnity(std::vector< std::vector< Matrix > > &Unity)
Definition: math_utilities.hpp:1079
DenseVector< Second_Order_Tensor > Third_Order_Tensor
Definition: math_utilities.hpp:56
static void DeviatoricUnity(array_1d< double, 81 > &Unity)
Definition: math_utilities.hpp:1114
static void EigenVectors(const MatrixType &A, MatrixType &vectors, VectorType &lambda, double zero_tolerance=1e-9, int max_iterations=10)
Definition: math_utilities.hpp:430
MathUtils< TDataType > MathUtilsType
Definition: math_utilities.hpp:52
static void TensorToMatrix(std::vector< std::vector< Matrix > > &Tensor, Matrix &Matrix)
Definition: math_utilities.hpp:953
static bool Clipping(std::vector< Point * > &clipping_points, std::vector< Point * > &subjected_points, std::vector< Point * > &result_points, double tolerance)
Definition: math_utilities.hpp:1141
static Vector EigenValuesDirectMethod(const Matrix &A)
Definition: math_utilities.hpp:241
matrix< Second_Order_Tensor > Matrix_Second_Tensor
Definition: math_utilities.hpp:60
static void TensorToMatrix(const array_1d< double, 81 > &Tensor, Matrix &Matrix)
Definition: math_utilities.hpp:1027
static Vector TensorToStrainVector(const Matrix &Tensor)
Definition: math_utilities.hpp:670
DenseVector< Vector > Second_Order_Tensor
Definition: math_utilities.hpp:54
unsigned int IndexType
Definition: math_utilities.hpp:48
static void MatrixToTensor(MatrixType &A, array_1d< double, 81 > &Tensor)
Definition: math_utilities.hpp:908
static void QRFactorization(const MatrixType &A, MatrixType &Q, MatrixType &R)
Definition: math_utilities.hpp:305
Matrix MatrixType
Definition: math_utilities.hpp:44
static MatrixType StrainVectorToTensor(const VectorType &Strains)
Definition: math_utilities.hpp:636
DenseVector< DenseVector< Matrix > > Fourth_Order_Tensor
Definition: math_utilities.hpp:58
static void TensorToVector(const Matrix &Tensor, Vector &Vector)
Definition: math_utilities.hpp:756
static void TensorToMatrix(Fourth_Order_Tensor &Tensor, Matrix &Matrix)
Definition: math_utilities.hpp:780
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
Various mathematical utilitiy functions.
Definition: math_utils.h:62
Point class.
Definition: point.h:59
Short class definition.
Definition: array_1d.h:61
BOOST_UBLAS_INLINE const_iterator end() const
Definition: array_1d.h:611
BOOST_UBLAS_INLINE const_iterator begin() const
Definition: array_1d.h:606
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
iteration
Definition: DEM_benchmarks.py:172
constexpr double Pi
Definition: global_variables.h:25
solution
Definition: KratosDEM.py:9
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
Internals::Matrix< double, AMatrix::dynamic, AMatrix::dynamic > Matrix
Definition: amatrix_interface.h:470
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
int max_iterations
Definition: ProjectParameters.py:53
list coeff
Definition: bombardelli_test.py:41
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
w
Definition: generate_convection_diffusion_explicit_element.py:108
q
Definition: generate_convection_diffusion_explicit_element.py:109
V
Definition: generate_droplet_dynamics.py:256
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
u
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:30
float gamma
Definition: generate_two_fluid_navier_stokes.py:131
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
phi
Definition: isotropic_damage_automatic_differentiation.py:168
R
Definition: isotropic_damage_automatic_differentiation.py:172
Stress
Definition: isotropic_damage_automatic_differentiation.py:135
tuple Q
Definition: isotropic_damage_automatic_differentiation.py:235
int d
Definition: ode_solve.py:397
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
A
Definition: sensitivityMatrix.py:70
p
Definition: sensitivityMatrix.py:52
int dim
Definition: sensitivityMatrix.py:25
B
Definition: sensitivityMatrix.py:76
integer i
Definition: TensorModule.f:17
double precision, dimension(3, 3), public delta
Definition: TensorModule.f:16
integer l
Definition: TensorModule.f:17
zero
Definition: test_pureconvectionsolver_benchmarking.py:94
e
Definition: run_cpp_mpi_tests.py:31