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.
particle_mechanics_math_utilities.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ \.
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Bodhinanda Chandra
11 //
12 // References: This class is adapted from applications/SolidMechanicsApplication/custom_utilities/solid_mechanics_math_utilities.hpp
13 
14 
15 #if !defined(KRATOS_PARTICLE_MECHANICS_MATH_UTILITIES_H_INCLUDED)
16 #define KRATOS_PARTICLE_MECHANICS_MATH_UTILITIES_H_INCLUDED
17 
18 
19 #ifdef FIND_MAX
20 #undef FIND_MAX
21 #endif
22 
23 #define FIND_MAX(a, b) ((a)>(b)?(a):(b))
24 
25 // System includes
26 #include <cmath>
27 
28 // External includes
29 
30 // Project includes
31 #include "utilities/math_utils.h"
32 #include "geometries/point.h"
33 #include "geometries/geometry.h"
34 #include "includes/node.h"
36 
37 #if !defined(INITIAL_CURRENT)
38 #define INITIAL_CURRENT
39  enum Configuration {Initial = 0, Current = 1};
40 #endif
41 
42 namespace Kratos
43 {
44 template<class TDataType>
46 {
47 public:
52  typedef Matrix MatrixType;
53 
54  typedef Vector VectorType;
55 
56  typedef unsigned int IndexType;
57 
58  typedef unsigned int SizeType;
59 
61 
62  typedef Node NodeType;
63 
65 
67 
69 
71 
73 
80  static inline void GetRotationMatrix(
81  MatrixType& rRotationMatrix,
82  const VectorType& rNormalVector,
83  const unsigned int Dimension
84  )
85  {
86  if(Dimension == 2){
87  if (rRotationMatrix.size1() != 2 && rRotationMatrix.size2() != 2)
88  rRotationMatrix.resize(2,2,false);
89  noalias(rRotationMatrix) = IdentityMatrix(Dimension);
90 
91  double aux = rNormalVector[0]*rNormalVector[0] + rNormalVector[1]*rNormalVector[1];
92  aux = std::sqrt(aux);
93  if (std::abs(aux) < std::numeric_limits<double>::epsilon()) aux = std::numeric_limits<double>::epsilon();
94 
95  rRotationMatrix(0,0) = rNormalVector[0]/aux;
96  rRotationMatrix(0,1) = rNormalVector[1]/aux;
97  rRotationMatrix(1,0) = -rNormalVector[1]/aux;
98  rRotationMatrix(1,1) = rNormalVector[0]/aux;
99  }
100  else if (Dimension == 3){
101  if (rRotationMatrix.size1() != 3 && rRotationMatrix.size2() != 3)
102  rRotationMatrix.resize(2,2,false);
103  noalias(rRotationMatrix) = IdentityMatrix(Dimension);
104 
105  double aux = rNormalVector[0]*rNormalVector[0] + rNormalVector[1]*rNormalVector[1] + rNormalVector[2]*rNormalVector[2];
106  aux = std::sqrt(aux);
107  if (std::abs(aux) < std::numeric_limits<double>::epsilon()) aux = std::numeric_limits<double>::epsilon();
108 
109  rRotationMatrix(0,0) = rNormalVector[0]/aux;
110  rRotationMatrix(0,1) = rNormalVector[1]/aux;
111  rRotationMatrix(0,2) = rNormalVector[2]/aux;
112 
113  // Define the new coordinate system, where the first vector is aligned with the normal
114  // To choose the remaining two vectors, we project the first component of the cartesian base to the tangent plane
115  Vector rT1 = ZeroVector(3);
116  rT1(0) = 1.0;
117  rT1(1) = 0.0;
118  rT1(2) = 0.0;
119  double dot = rRotationMatrix(0,0); //this->Dot(rN,rT1);
120 
121  // It is possible that the normal is aligned with (1,0,0), resulting in norm(rT1) = 0
122  // If this is the case, repeat the procedure using (0,1,0)
123  if ( std::abs(dot) > 0.99 )
124  {
125  rT1(0) = 0.0;
126  rT1(1) = 1.0;
127  rT1(2) = 0.0;
128 
129  dot = rRotationMatrix(0,1); //this->Dot(rN,rT1);
130  }
131 
132  // Calculate projection and normalize
133  rT1[0] -= dot*rRotationMatrix(0,0);
134  rT1[1] -= dot*rRotationMatrix(0,1);
135  rT1[2] -= dot*rRotationMatrix(0,2);
137 
138  rRotationMatrix(1,0) = rT1[0];
139  rRotationMatrix(1,0) = rT1[1];
140  rRotationMatrix(1,0) = rT1[2];
141 
142  // The third base component is choosen as N x T1, which is normalized by construction
143  rRotationMatrix(2,0) = rRotationMatrix(0,1)*rT1[2] - rRotationMatrix(0,2)*rT1[1];
144  rRotationMatrix(2,1) = rRotationMatrix(0,2)*rT1[0] - rRotationMatrix(0,0)*rT1[2];
145  rRotationMatrix(2,2) = rRotationMatrix(0,0)*rT1[1] - rRotationMatrix(0,1)*rT1[0];
146  }
147  else{
148  KRATOS_ERROR << "Dimension given is wrong!" << std::endl;
149  }
150  }
151 
159  static inline double CalculateRadius(
160  const Matrix& rN,
161  GeometryType& Geom,
162  const Configuration ThisConfiguration = Current,
163  const IndexType IntegrationPointIndex = 0
164  )
165  {
166  double radius = 0.0;
167 
168  for (unsigned int iNode = 0; iNode < Geom.size(); iNode++)
169  {
170  // Displacement from the reference to the current configuration
171  if (ThisConfiguration == Current)
172  {
173  const array_1d<double, 3 >& delta_displacement = Geom[iNode].FastGetSolutionStepValue(DISPLACEMENT);
174  const array_1d<double, 3 >& reference_position = Geom[iNode].Coordinates();
175 
176  const array_1d<double, 3 > current_position = reference_position + delta_displacement;
177  radius += current_position[0] * rN(IntegrationPointIndex, iNode);
178  }
179  else
180  {
181  const array_1d<double, 3 >& reference_position = Geom[iNode].Coordinates();
182  radius += reference_position[0] * rN(IntegrationPointIndex, iNode);
183  }
184  }
185 
186  return radius;
187  }
188 
195  static inline double CalculateRadiusPoint(
196  GeometryType& Geom,
197  const Configuration ThisConfiguration = Current
198  )
199  {
200  // Displacement from the reference to the current configuration
201  if (ThisConfiguration == Current)
202  {
203  const array_1d<double, 3 >& delta_displacement = Geom[0].FastGetSolutionStepValue(DISPLACEMENT);
204  const array_1d<double, 3 >& reference_position = Geom[0].Coordinates();
205 
206  const array_1d<double, 3 > current_position = reference_position + delta_displacement;
207  return current_position[0];
208  }
209  else
210  {
211  const array_1d<double, 3 >& reference_position = Geom[0].Coordinates();
212  return reference_position[0];
213  }
214  }
215 
223  static inline void QRFactorization(const MatrixType& A, MatrixType& Q, MatrixType& R)
224  {
225 
226  if(A.size1()!= A.size2())
227  KRATOS_ERROR<<" GIVEN MATRIX IS NOT A SQUARE MATRIX: QRFactorization calculation"<<std::endl;
228 
229  // QR Factorization with Householder-Algorithm
230  unsigned int dimension= A.size1();
231 
232  Vector y(dimension);
233 
234  Vector w(dimension);
235 
236  R.resize(dimension,dimension,false);
237 
239 
240  Q.resize(dimension,dimension,false);
241 
243 
244  Matrix Help(A.size1(),A.size2());
245  noalias(Help) = A;
246 
247  Matrix unity(dimension,dimension);
249 
250  for(unsigned int j=0; j<dimension; j++)
251  unity(j,j)=1.0;
252 
253  std::vector<Matrix> HelpQ(dimension-1);
254 
255  std::vector<Matrix> HelpR(dimension-1);
256 
257  for(unsigned int i=0; i< dimension-1; i++)
258  {
259  HelpQ[i].resize(dimension,dimension,false);
260  HelpR[i].resize(dimension,dimension,false);
261  noalias(HelpQ[i])= unity;
263  }
264 
265  for(unsigned int iteration=0; iteration< dimension-1; iteration++)
266  {
267  // Vector y
268  for(unsigned int i=iteration; i<dimension; i++)
269  y[i]= Help(i,iteration);
270 
271 
272  // Helpvalue l
273  double normy=0.0;
274 
275  for(unsigned int i=iteration; i<dimension; i++)
276  normy += y[i]*y[i];
277 
278  normy= std::sqrt(normy);
279 
280  double l= std::sqrt((normy*(normy+std::abs(y(iteration))))/2);
281 
282  double k=0.0;
283 
284  if(y[iteration] !=0)
285  k= - y(iteration)/std::abs(y(iteration))*normy;
286  else
287  k= -normy;
288 
289  for(unsigned int i=iteration; i<dimension; i++)
290  {
291  double e=0;
292 
293  if(i==iteration)
294  e=1;
295 
296  w[i]= 1/(2*l)*(y[i]-k*e);
297  }
298 
299  for(unsigned int i=iteration; i<dimension; i++)
300  for(unsigned int j=iteration; j<dimension; j++)
301  HelpQ[iteration](i,j)= unity(i,j)- 2*w[i]*w[j];
302 
303 
304  for(unsigned int i=iteration; i<dimension; i++)
305  for(unsigned int j=iteration; j<dimension; j++)
306  for(unsigned int k=iteration; k<dimension; k++)
307  HelpR[iteration](i,j)+= HelpQ[iteration](i,k)*Help(k,j);
308 
309  Help= HelpR[iteration];
310 
311  }
312 
313  // Assembling R
314  for(unsigned int k=0; k<dimension-1; k++)
315  {
316  for(unsigned int i=k; i<dimension; i++)
317  for(unsigned int j=k; j<dimension; j++)
318  R(i,j) =HelpR[k](i,j);
319 
320  }
321 
322  for(unsigned int k=1; k<dimension-1; k++)
323  {
324  for(unsigned int i=0; i<dimension; i++)
325  for(unsigned int j=0; j<dimension; j++)
326  for(unsigned int l=0; l<dimension; l++)
327  Q(i,j)+= HelpQ[(k-1)](i,l)*HelpQ[k](l,j);
328  noalias(HelpQ[k])=Q;
329  }
330  if(dimension-1==1)
331  noalias(Q)=HelpQ[0];
332 
333  }
334 
335 
345  static inline Vector EigenValues(const Matrix& A, const double rTolerance = 1e-9, const double rZeroTolerance = 1e-9)
346  {
347  unsigned int dimension= A.size1();
348 
349  Matrix Convergence(2,dimension);
350  noalias(Convergence) = ZeroMatrix(2,dimension);
351 
352  double delta = 0.0;
353 
354  double abs = 0.0;
355 
356  Vector Result(dimension);
357  noalias(Result) = ZeroVector(dimension);
358 
359  Matrix HelpA(dimension,dimension);
361 
362  Matrix HelpQ(dimension,dimension);
364 
365  Matrix HelpR(dimension,dimension);
367 
368  HelpA=A;
369 
370  bool is_converged=false;
371  unsigned int max_iters = 10;
372  unsigned int iter = 0;
373 
374  while(is_converged == false && iter<max_iters )
375  {
376  double shift= HelpA((dimension-1),(dimension-1));
377 
378  for(unsigned int i=0; i<dimension; i++)
379  {
380  HelpA(i,i) = HelpA(i,i)- shift;
381  }
382 
384 
385  HelpA= ZeroMatrix(dimension, dimension);
386 
387  for(unsigned int i=0; i<dimension; i++)
388  {
389  HelpA(i,i) += shift;
390  for(unsigned int j=0; j< dimension; j++)
391  {
392  for(unsigned int k=0; k< dimension; k++)
393  {
394  HelpA(i,j) += HelpR(i,k)*HelpQ(k,j);
395  }
396  }
397  }
398 
399  delta= 0.0;
400 
401  abs = 0.0;
402 
403  for(unsigned int i=0; i<dimension; i++)
404  {
405  Convergence(0,i)=Convergence(1,i);
406  Convergence(1,i)=HelpA(i,i);
407  delta+= (Convergence(1,i)-Convergence(0,i))*(Convergence(1,i)-Convergence(0,i));
408  abs+=(Convergence(1,i))*(Convergence(1,i));
409  }
410 
411  delta= std::sqrt(delta);
412 
413  abs=std::sqrt(abs);
414 
415  if(abs < rZeroTolerance)
416  abs=1.0;
417 
418  if(delta < rZeroTolerance || (delta/abs) < rTolerance)
419  is_converged=true;
420 
421  iter++;
422  }
423 
424 
425  for(unsigned int i=0; i<dimension; i++)
426  {
427  Result[i]= HelpA(i,i);
428 
429  if(std::abs(Result[i]) <rZeroTolerance)
430  Result[i]=0.0;
431  }
432 
433  return Result;
434  }
435 
436 
443  static inline Vector EigenValuesDirectMethod(const Matrix& A)
444  {
445  // Given a real symmetric 3x3 matrix A, compute the eigenvalues
446  unsigned int dimension= A.size1();
447  Vector Result(dimension);
448  noalias(Result) = ZeroVector(dimension);
449 
450  const double p1 = A(0,1)*A(0,1) + A(0,2)*A(0,2) + A(1,2)*A(1,2);
451  if (p1 == 0)
452  {//A is diagonal.
453  Result[0] = A(0,0);
454  Result[1] = A(1,1);
455  Result[2] = A(2,2);
456  return Result;
457  }
458 
459  const double q = (A(0,0) + A(1,1) + A(2,2)) / 3.0;
460  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;
461  const double p = std::sqrt(p2 / 6.0);
462 
463  Matrix B(3,3);
464  const double inv_p = 1.0/p;
465 
466  // B = (1 / p) * (A - q * I) where I is the identity matrix
467  B(0,0) = inv_p * (A(0,0) - q);
468  B(1,1) = inv_p * (A(1,1) - q);
469  B(2,2) = inv_p * (A(2,2) - q);
470  B(0,1) = inv_p * A(0,1);
471  B(1,0) = inv_p * A(1,0);
472  B(0,2) = inv_p * A(0,2);
473  B(2,0) = inv_p * A(2,0);
474  B(1,2) = inv_p * A(1,2);
475  B(2,1) = inv_p * A(2,1);
476 
477  //r = det(B) / 2
478  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) );
479 
480  // In exact arithmetic for a symmetric matrix -1 <= r <= 1
481  // but computation error can leave it slightly outside this range.
482  double phi = 0.0;
483  if (r <= -1) { phi = Globals::Pi / 3.0; }
484  else if (r >= 1) { phi = 0.0; }
485  else { phi = acos(r) / 3.0;}
486 
487  // the eigenvalues satisfy eig3 <= eig2 <= eig1
488  Result[0] = q + 2.0 * p * cos(phi);
489  Result[2] = q + 2.0 * p * cos(phi + (2.0 * Globals::Pi / 3.0));
490  Result[1] = 3.0 * q - Result[0] - Result[2]; //% since trace(A) = eig1 + eig2 + eig3
491 
492  return Result;
493  }
494 
495 
506  static inline void EigenVectors(const MatrixType& A,
507  MatrixType& rEigenVectors,
508  VectorType& rEigenValues,
509  const double rZeroTolerance = 1e-9,
510  const unsigned int rMaxIteration = 10)
511  {
512  if(A.size1()!=3 || A.size2()!=3)
513  KRATOS_ERROR<<" GIVEN MATRIX IS NOT 3x3: Eigenvectors calculation"<<std::endl;
514 
515  Matrix Help= A;
516 
517  for(unsigned int i=0; i<3; i++)
518  for(unsigned int j=0; j<3; j++)
519  Help(i,j)= Help(i,j);
520 
521 
522  rEigenVectors.resize(Help.size1(),Help.size2(),false);
523 
524  rEigenValues.resize(Help.size1(),false);
525 
526  Matrix HelpDummy(Help.size1(),Help.size2());
527 
528  bool is_converged = false;
529 
530  Matrix unity(Help.size1(),Help.size2());
531  noalias(unity) = ZeroMatrix(Help.size1(),Help.size2());
532 
533  for(unsigned int i=0; i< Help.size1(); i++)
534  unity(i,i)= 1.0;
535 
536  Matrix V= unity;
537 
538  Matrix VDummy(Help.size1(),Help.size2());
539 
540  Matrix Rotation(Help.size1(),Help.size2());
541 
542 
543  for(unsigned int iterations=0; iterations<rMaxIteration; iterations++)
544  {
545 
546  is_converged= true;
547 
548  double a= 0.0;
549 
550  unsigned int index1= 0;
551 
552  unsigned int index2= 1;
553 
554  for(unsigned int i=0; i< Help.size1(); i++)
555  {
556  for(unsigned int j=(i+1); j< Help.size2(); j++)
557  {
558  if((std::abs(Help(i,j)) > a ) && (std::abs(Help(i,j)) > rZeroTolerance))
559  {
560  a= std::abs(Help(i,j));
561 
562  index1= i;
563  index2= j;
564 
565  is_converged= false;
566  }
567  }
568  }
569 
570  if(is_converged)
571  break;
572 
573  // Calculation of Rotationangle
574 
575  double gamma= (Help(index2,index2)-Help(index1,index1))/(2*Help(index1,index2));
576 
577  double u=1.0;
578 
579  if(std::abs(gamma) > rZeroTolerance && std::abs(gamma)< (1/rZeroTolerance))
580  {
581  u= gamma/std::abs(gamma)*1.0/(std::abs(gamma)+std::sqrt(1.0+gamma*gamma));
582  }
583  else
584  {
585  if (std::abs(gamma)>= (1.0/rZeroTolerance))
586  u= 0.5/gamma;
587  }
588 
589  double c= 1.0/(std::sqrt(1.0+u*u));
590 
591  double s= c*u;
592 
593  double teta= s/(1.0+c);
594 
595  // Rotation of the Matrix
596  HelpDummy= Help;
597 
598  HelpDummy(index2,index2)= Help(index2,index2)+u*Help(index1,index2);
599  HelpDummy(index1,index1)= Help(index1,index1)-u*Help(index1,index2);
600  HelpDummy(index1,index2)= 0.0;
601  HelpDummy(index2,index1)= 0.0;
602 
603  for(unsigned int i=0; i<Help.size1(); i++)
604  {
605  if((i!= index1) && (i!= index2))
606  {
607  HelpDummy(index2,i)=Help(index2,i)+s*(Help(index1,i)- teta*Help(index2,i));
608  HelpDummy(i,index2)=Help(index2,i)+s*(Help(index1,i)- teta*Help(index2,i));
609 
610  HelpDummy(index1,i)=Help(index1,i)-s*(Help(index2,i)+ teta*Help(index1,i));
611  HelpDummy(i,index1)=Help(index1,i)-s*(Help(index2,i)+ teta*Help(index1,i));
612  }
613  }
614 
615 
616  Help= HelpDummy;
617 
618  //Calculation of the eigenvectors V
619  Rotation =unity;
620  Rotation(index2,index1)=-s;
621  Rotation(index1,index2)=s;
622  Rotation(index1,index1)=c;
623  Rotation(index2,index2)=c;
624 
625  noalias(VDummy) = ZeroMatrix(Help.size1(), Help.size2());
626 
627  for(unsigned int i=0; i< Help.size1(); i++)
628  {
629  for(unsigned int j=0; j< Help.size1(); j++)
630  {
631  for(unsigned int k=0; k< Help.size1(); k++)
632  {
633  VDummy(i,j) += V(i,k)*Rotation(k,j);
634  }
635  }
636  }
637  V= VDummy;
638 
639  }
640 
641  if(!(is_converged))
642  {
643  KRATOS_WARNING("ParticleMechanicsMathUtilities")<<"########################################################"<<std::endl;
644  KRATOS_WARNING("ParticleMechanicsMathUtilities")<<"rMaxIteration exceed in Jacobi-Seidel-Iteration (eigenvectors)"<<std::endl;
645  KRATOS_WARNING("ParticleMechanicsMathUtilities")<<"########################################################"<<std::endl;
646  }
647 
648  for(unsigned int i=0; i< Help.size1(); i++)
649  {
650  for(unsigned int j=0; j< Help.size1(); j++)
651  {
652  rEigenVectors(i,j)= V(j,i);
653  }
654  }
655 
656  for(unsigned int i=0; i<Help.size1(); i++)
657  rEigenValues[i]= Help(i,i);
658 
659  }
660 
661 
666  template< class TVectorType >
667  static inline void Normalize( TVectorType& v )
668  {
669  if (MathUtilsType::Norm( v ) > std::numeric_limits<double>::epsilon())
670  v *= 1.0/(MathUtilsType::Norm( v ));
671  }
672 
673 
679  static double NormTensor(Matrix& rTensor)
680  {
681  double result=0.0;
682  for(unsigned int i=0; i< rTensor.size1(); i++)
683  for(unsigned int j=0; j< rTensor.size2(); j++)
684  result += rTensor(i,j)*rTensor(i,j);
685 
686  result = std::sqrt(result);
687 
688  return result;
689  }
690 
691 
697  static inline void TensorToMatrix(const Fourth_Order_Tensor& rTensor, Matrix& rMatrix)
698  {
699  if (rTensor[0].size()== 3)
700  {
701  if(rMatrix.size1()!=6 || rMatrix.size2()!=6)
702  rMatrix.resize(6,6,false);
703 
704  rMatrix(0,0) = rTensor[0][0](0,0);
705  rMatrix(0,1) = rTensor[0][0](1,1);
706  rMatrix(0,2) = rTensor[0][0](2,2);
707  rMatrix(0,3) = rTensor[0][0](0,1);
708  rMatrix(0,4) = rTensor[0][0](0,2);
709  rMatrix(0,5) = rTensor[0][0](1,2);
710 
711  rMatrix(1,0) = rTensor[1][1](0,0);
712  rMatrix(1,1) = rTensor[1][1](1,1);
713  rMatrix(1,2) = rTensor[1][1](2,2);
714  rMatrix(1,3) = rTensor[1][1](0,1);
715  rMatrix(1,4) = rTensor[1][1](0,2);
716  rMatrix(1,5) = rTensor[1][1](1,2);
717 
718  rMatrix(2,0) = rTensor[2][2](0,0);
719  rMatrix(2,1) = rTensor[2][2](1,1);
720  rMatrix(2,2) = rTensor[2][2](2,2);
721  rMatrix(2,3) = rTensor[2][2](0,1);
722  rMatrix(2,4) = rTensor[2][2](0,2);
723  rMatrix(2,5) = rTensor[2][2](1,2);
724 
725  rMatrix(3,0) = rTensor[0][1](0,0);
726  rMatrix(3,1) = rTensor[0][1](1,1);
727  rMatrix(3,2) = rTensor[0][1](2,2);
728  rMatrix(3,3) = rTensor[0][1](0,1);
729  rMatrix(3,4) = rTensor[0][1](0,2);
730  rMatrix(3,5) = rTensor[0][1](1,2);
731 
732  rMatrix(4,0) = rTensor[0][2](0,0);
733  rMatrix(4,1) = rTensor[0][2](1,1);
734  rMatrix(4,2) = rTensor[0][2](2,2);
735  rMatrix(4,3) = rTensor[0][2](0,1);
736  rMatrix(4,4) = rTensor[0][2](0,2);
737  rMatrix(4,5) = rTensor[0][2](1,2);
738 
739  rMatrix(5,0) = rTensor[1][2](0,0);
740  rMatrix(5,1) = rTensor[1][2](1,1);
741  rMatrix(5,2) = rTensor[1][2](2,2);
742  rMatrix(5,3) = rTensor[1][2](0,1);
743  rMatrix(5,4) = rTensor[1][2](0,2);
744  rMatrix(5,5) = rTensor[1][2](1,2);
745  }
746  else
747  {
748  if(rMatrix.size1()!=3 || rMatrix.size2()!=3)
749  rMatrix.resize(3,3,false);
750 
751  rMatrix(0,0) = rTensor[0][0](0,0);
752  rMatrix(0,1) = rTensor[0][0](1,1);
753  rMatrix(0,2) = rTensor[0][0](0,1);
754  rMatrix(1,0) = rTensor[1][1](0,0);
755  rMatrix(1,1) = rTensor[1][1](1,1);
756  rMatrix(1,2) = rTensor[1][1](0,1);
757  rMatrix(2,0) = rTensor[0][1](0,0);
758  rMatrix(2,1) = rTensor[0][1](1,1);
759  rMatrix(2,2) = rTensor[0][1](0,1);
760 
761  }
762 
763  }
764 
765 
771  static void MatrixToTensor(const MatrixType& A, std::vector<std::vector<Matrix> >& rTensor)
772  {
773  int help1 = 0;
774  int help2 = 0;
775  double coeff = 1.0;
776 
777  rTensor.resize(3);
778 
779  for(unsigned int i=0; i<3; i++)
780  {
781  rTensor[i].resize(3);
782  for(unsigned int j=0; j<3; j++)
783  {
784  rTensor[i][j].resize(3,3,false);
785  noalias(rTensor[i][j])= ZeroMatrix(3,3);
786  for(unsigned int k=0; k<3; k++)
787  for(unsigned int l=0; l<3; l++)
788  {
789  if(i==j) help1= i;
790  else
791  {
792  if((i==0 && j==1) || (i==1 && j==0)) help1= 3;
793  if((i==1 && j==2) || (i==2 && j==1)) help1= 4;
794  if((i==2 && j==0) || (i==0 && j==2)) help1= 5;
795  }
796  if(k==l)
797  {
798  help2= k;
799  coeff=1.0;
800  }
801  else
802  {
803  coeff=0.5;
804  if((k==0 && l==1) || (k==1 && l==0)) help2= 3;
805  if((k==1 && l==2) || (k==2 && l==1)) help2= 4;
806  if((k==2 && l==0) || (k==0 && l==2)) help2= 5;
807  }
808 
809  rTensor[i][j](k,l)= A(help1,help2)*coeff;
810  }
811  }
812  }
813 
814 
815  }
816 
817 
823  static void MatrixToTensor(const MatrixType& A,array_1d<double, 81>& rTensor)
824  {
825  int help1 = 0;
826  int help2 = 0;
827  double coeff = 1.0;
828  std::fill(rTensor.begin(), rTensor.end(), 0.0);
829  for(unsigned int i=0; i<3; i++)
830  {
831  for(unsigned int j=0; j<3; j++)
832  {
833  for(unsigned int k=0; k<3; k++)
834  for(unsigned int l=0; l<3; l++)
835  {
836  if(i==j) help1= i;
837  else
838  {
839  if((i==0 && j==1) || (i==1 && j==0)) help1= 3;
840  if((i==1 && j==2) || (i==2 && j==1)) help1= 4;
841  if((i==2 && j==0) || (i==0 && j==2)) help1= 5;
842  }
843  if(k==l)
844  {
845  help2= k;
846  coeff=1.0;
847  }
848  else
849  {
850  coeff=0.5;
851  if((k==0 && l==1) || (k==1 && l==0)) help2= 3;
852  if((k==1 && l==2) || (k==2 && l==1)) help2= 4;
853  if((k==2 && l==0) || (k==0 && l==2)) help2= 5;
854  }
855 
856  rTensor[i*27+j*9+k*3+l]= A(help1,help2)*coeff;
857  }
858  }
859  }
860  }
861 
862 
868  static void TensorToMatrix(const std::vector<std::vector<Matrix> >& rTensor, Matrix& rMatrix)
869  {
870  int help1 = 0;
871  int help2 = 0;
872  int help3 = 0;
873  int help4 = 0;
874  double coeff = 1.0;
875 
876  if(rMatrix.size1()!=6 || rMatrix.size2()!=6)
877  rMatrix.resize(6,6,false);
878 
879  for(unsigned int i=0; i<6; i++)
880  for(unsigned int j=0; j<6; j++)
881  {
882  if(i<3)
883  {
884  help1= i;
885  help2= i;
886  }
887  else
888  {
889  if(i==3)
890  {
891  help1= 0;
892  help2= 1;
893  }
894  if(i==4)
895  {
896  help1= 1;
897  help2= 2;
898  }
899  if(i==5)
900  {
901  help1= 2;
902  help2= 0;
903  }
904  }
905 
906  if(j<3)
907  {
908  help3= j;
909  help4= j;
910  coeff= 1.0;
911  }
912  else
913  {
914  if(j==3)
915  {
916  help3= 0;
917  help4= 1;
918  }
919  if(j==4)
920  {
921  help3= 1;
922  help4= 2;
923  }
924  if(j==5)
925  {
926  help3= 2;
927  help4= 0;
928  }
929  coeff= 2.0;
930  }
931 
932  rMatrix(i,j)= rTensor[help1][help2](help3,help4)*coeff;
933  }
934 
935  }
936 
937 
943  static void TensorToMatrix( const array_1d<double, 81>& rTensor, Matrix& rMatrix )
944  {
945  if(rMatrix.size1()!=6 || rMatrix.size2()!=6)
946  rMatrix.resize(6,6,false);
947 
948  rMatrix(0,0) = rTensor[0];
949  rMatrix(0,1) = rTensor[4];
950  rMatrix(0,2) = rTensor[8];
951  rMatrix(0,3) = 2.0*rTensor[1];
952  rMatrix(0,4) = 2.0*rTensor[5];
953  rMatrix(0,5) = 2.0*rTensor[6];
954 
955  rMatrix(1,0) = rTensor[36];
956  rMatrix(1,1) = rTensor[40];
957  rMatrix(1,2) = rTensor[44];
958  rMatrix(1,3) = 2.0*rTensor[37];
959  rMatrix(1,4) = 0.0*rTensor[41];
960  rMatrix(1,5) = 0.0*rTensor[42];
961 
962  rMatrix(2,0) = rTensor[72];
963  rMatrix(2,1) = rTensor[76];
964  rMatrix(2,2) = rTensor[80];
965  rMatrix(2,3) = 2.0*rTensor[73];
966  rMatrix(2,4) = 2.0*rTensor[77];
967  rMatrix(2,5) = 2.0*rTensor[78];
968 
969  rMatrix(3,0) = rTensor[9];
970  rMatrix(3,1) = rTensor[13];
971  rMatrix(3,2) = rTensor[18];
972  rMatrix(3,3) = 2.0*rTensor[10];
973  rMatrix(3,4) = 2.0*rTensor[14];
974  rMatrix(3,5) = 2.0*rTensor[15];
975 
976  rMatrix(4,0) = rTensor[45];
977  rMatrix(4,1) = rTensor[49];
978  rMatrix(4,2) = rTensor[53];
979  rMatrix(4,3) = 2.0*rTensor[46];
980  rMatrix(4,4) = 0.0*rTensor[50];
981  rMatrix(4,5) = 0.0*rTensor[51];
982 
983  rMatrix(5,0) = rTensor[54];
984  rMatrix(5,1) = rTensor[58];
985  rMatrix(5,2) = rTensor[62];
986  rMatrix(5,3) = 2.0*rTensor[55];
987  rMatrix(5,4) = 2.0*rTensor[59];
988  rMatrix(5,5) = 2.0*rTensor[60];
989 
990  }
991 
992 
993 private:
994 };// class ParticleMechanicsMathUtilities
995 }
996 #endif /* KRATOS_PARTICLE_MECHANICS_MATH_UTILITIES_H_INCLUDED defined */
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
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
static double Norm(const Vector &a)
Calculates the norm of vector "a".
Definition: math_utils.h:703
This class defines the node.
Definition: node.h:65
Definition: particle_mechanics_math_utilities.h:46
DenseMatrix< Second_Order_Tensor > Matrix_Second_Tensor
Definition: particle_mechanics_math_utilities.h:72
unsigned int IndexType
Definition: particle_mechanics_math_utilities.h:56
static void Normalize(TVectorType &v)
Normalises a vector. Vector is scaled by .
Definition: particle_mechanics_math_utilities.h:667
static Vector EigenValues(const Matrix &A, const double rTolerance=1e-9, const double rZeroTolerance=1e-9)
Calculates Eigenvalues of given square matrix A. The QR Algorithm with shifts is used.
Definition: particle_mechanics_math_utilities.h:345
static double NormTensor(Matrix &rTensor)
Builds the norm of a given second order tensor.
Definition: particle_mechanics_math_utilities.h:679
static void MatrixToTensor(const MatrixType &A, std::vector< std::vector< Matrix > > &rTensor)
Transforms a given 6*6 Matrix to a corresponing 4th order tensor.
Definition: particle_mechanics_math_utilities.h:771
DenseVector< Vector > Second_Order_Tensor
Definition: particle_mechanics_math_utilities.h:66
Node NodeType
Definition: particle_mechanics_math_utilities.h:62
Matrix MatrixType
Definition: particle_mechanics_math_utilities.h:52
static void GetRotationMatrix(MatrixType &rRotationMatrix, const VectorType &rNormalVector, const unsigned int Dimension)
Definition: particle_mechanics_math_utilities.h:80
static void TensorToMatrix(const Fourth_Order_Tensor &rTensor, Matrix &rMatrix)
Transforms a given fourth order tensor to a corresponing Matrix.
Definition: particle_mechanics_math_utilities.h:697
unsigned int SizeType
Definition: particle_mechanics_math_utilities.h:58
DenseVector< Second_Order_Tensor > Third_Order_Tensor
Definition: particle_mechanics_math_utilities.h:68
static void TensorToMatrix(const array_1d< double, 81 > &rTensor, Matrix &rMatrix)
Transforms a given 4th order Tensor to a corresponing 6*6 Matrix.
Definition: particle_mechanics_math_utilities.h:943
static double CalculateRadiusPoint(GeometryType &Geom, const Configuration ThisConfiguration=Current)
Definition: particle_mechanics_math_utilities.h:195
static double CalculateRadius(const Matrix &rN, GeometryType &Geom, const Configuration ThisConfiguration=Current, const IndexType IntegrationPointIndex=0)
Definition: particle_mechanics_math_utilities.h:159
static void MatrixToTensor(const MatrixType &A, array_1d< double, 81 > &rTensor)
Transforms a given 6*6 Matrix to a corresponing 4th order tensor.
Definition: particle_mechanics_math_utilities.h:823
Geometry< Node > GeometryType
Definition: particle_mechanics_math_utilities.h:64
static void TensorToMatrix(const std::vector< std::vector< Matrix > > &rTensor, Matrix &rMatrix)
Transforms a given 4th order tensor to a corresponing 6*6 Matrix.
Definition: particle_mechanics_math_utilities.h:868
MathUtils< TDataType > MathUtilsType
Definition: particle_mechanics_math_utilities.h:60
Vector VectorType
Definition: particle_mechanics_math_utilities.h:54
static void EigenVectors(const MatrixType &A, MatrixType &rEigenVectors, VectorType &rEigenValues, const double rZeroTolerance=1e-9, const unsigned int rMaxIteration=10)
Calculates the Eigenvectors and Eigenvalues of given symmetric matrix A. The eigenvectors and eigenva...
Definition: particle_mechanics_math_utilities.h:506
static void QRFactorization(const MatrixType &A, MatrixType &Q, MatrixType &R)
Calculates the QR Factorization of given square matrix A=QR. The Factorization is performed using the...
Definition: particle_mechanics_math_utilities.h:223
static Vector EigenValuesDirectMethod(const Matrix &A)
Calculates the Eigenvalues using a direct method.
Definition: particle_mechanics_math_utilities.h:443
DenseVector< DenseVector< Matrix > > Fourth_Order_Tensor
Definition: particle_mechanics_math_utilities.h:70
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_ERROR
Definition: exception.h:161
#define KRATOS_WARNING(label)
Definition: logger.h:265
iteration
Definition: DEM_benchmarks.py:172
constexpr double Pi
Definition: global_variables.h:25
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
Configuration
Definition: structural_mechanics_math_utilities.hpp:30
@ Current
Definition: structural_mechanics_math_utilities.hpp:30
AMatrix::IdentityMatrix< double > IdentityMatrix
Definition: amatrix_interface.h:564
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
list coeff
Definition: bombardelli_test.py:41
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
v
Definition: generate_convection_diffusion_explicit_element.py:114
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
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
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
phi
Definition: isotropic_damage_automatic_differentiation.py:168
R
Definition: isotropic_damage_automatic_differentiation.py:172
tuple Q
Definition: isotropic_damage_automatic_differentiation.py:235
float radius
Definition: mesh_to_mdpa_converter.py:18
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
A
Definition: sensitivityMatrix.py:70
p
Definition: sensitivityMatrix.py:52
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
e
Definition: run_cpp_mpi_tests.py:31
Configuration
Definition: particle_mechanics_math_utilities.h:39
@ Current
Definition: particle_mechanics_math_utilities.h:39
@ Initial
Definition: particle_mechanics_math_utilities.h:39