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.
solid_mechanics_math_utilities.hpp
Go to the documentation of this file.
1 //
2 // Project Name: KratosSolidMechanicsApplication $
3 // Created by: $Author: JMCarbonell $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: July 2013 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 #if !defined(KRATOS_SOLID_MECHANICS_MATH_UTILITIES_H_INCLUDED)
11 #define KRATOS_SOLID_MECHANICS_MATH_UTILITIES_H_INCLUDED
12 
13 
14 #ifdef FIND_MAX
15 #undef FIND_MAX
16 #endif
17 
18 #define FIND_MAX(a, b) ((a)>(b)?(a):(b))
19 
20 // System includes
21 #include <cmath>
22 
23 // External includes
24 
25 // Project includes
27 #include "utilities/math_utils.h"
28 #include "geometries/point.h"
29 
30 
31 namespace Kratos
32 {
33 template<class TDataType>
34 class SolidMechanicsMathUtilities
35 {
36 public:
41  typedef Matrix MatrixType;
42 
43  typedef Vector VectorType;
44 
45  typedef unsigned int IndexType;
46 
47  typedef unsigned int SizeType;
48 
50 
52 
54 
56 
58 
59 
76  static inline bool CardanoFormula(double a, double b, double c, double d, Vector& solution)
77  {
78  solution.resize(3,false);
80 
81  if(a==0)
82  {
83  std::cout<<"This is not a cubic equation: CardanoFormula"<<std::endl;
84 
85  return false;
86  }
87 
88  double p= (3.0*a*c-b*b)/(3.0*a*a);
89 
90  double q= 2.0*b*b*b/(27.0*a*a*a)-b*c/(3.0*a*a)+d/a;
91 
92  double discriminante= p*p*p/27.0+q*q/4.0;
93 
94  if(discriminante>0)
95  {
96  return false;
97  }
98 
99  if(discriminante==0)
100  {
101  if( a == 0 )
102  return false;
103 
104  solution(0)= pow(q/2.0, 1.0/3.0)-b/(3*a);
105  solution(1)= pow(q/2.0, 1.0/3.0)-b/(3*a);
106  solution(2)= pow(-4.0*q, 1.0/3.0)-b/(3*a);
107 
108  return true;
109  }
110 
111  if(p < 0) return false; //in this case the square roots below will be negative. This substitutes with better efficiency lines 107-110
112 
113  solution(0)=
114  -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)
115  -b/(3*a);
116  solution(1)=
117  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  ;
119  solution(2)=
120  -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)
121  -b/(3*a);
122 
123 // if(std::isnan<double>(solution(0)) || std::isnan<double>(solution(1))|| std::isnan<double>(solution(2)))
124 // {
125 // return false;
126 // }
127 
128  return true;
129  }
143  static inline Vector EigenValues(const Matrix& A, double tolerance, double zero)
144  {
145  int dim= A.size1();
146 
147  Matrix Convergence(2,dim);
148  noalias(Convergence) = ZeroMatrix(2,dim);
149 
150  double delta = 0.0;
151 
152  double abs = 0.0;
153 
154  Vector Result(dim);
155  noalias(Result) = ZeroVector(dim);
156 
157  Matrix HelpA(dim,dim);
158  noalias(HelpA) = ZeroMatrix(dim, dim);
159 
160  Matrix HelpQ(dim,dim);
161  noalias(HelpQ) = ZeroMatrix(dim, dim);
162 
163  Matrix HelpR(dim,dim);
164  noalias(HelpR) = ZeroMatrix(dim, dim);
165 
166  HelpA=A;
167 
168  bool is_converged=false;
169  unsigned int max_iters = 10;
170  unsigned int iter = 0;
171 
172  while(is_converged == false && iter<max_iters )
173  {
174  double shift= HelpA((dim-1),(dim-1));
175  //
176  for(int i=0; i<dim; i++)
177  {
178  HelpA(i,i) = HelpA(i,i)- shift;
179  }
180 
182 
183  HelpA= ZeroMatrix(dim, dim);
184 
185  for(int i=0; i<dim; i++)
186  {
187  HelpA(i,i) += shift;
188  for(int j=0; j< dim; j++)
189  {
190  for(int k=0; k< dim; k++)
191  {
192  HelpA(i,j) += HelpR(i,k)*HelpQ(k,j);
193  }
194  }
195  }
196 
197  delta= 0.0;
198 
199  abs = 0.0;
200 
201  for(int i=0; i<dim; i++)
202  {
203  Convergence(0,i)=Convergence(1,i);
204  Convergence(1,i)=HelpA(i,i);
205  delta+= (Convergence(1,i)-Convergence(0,i))*(Convergence(1,i)-Convergence(0,i));
206  abs+=(Convergence(1,i))*(Convergence(1,i));
207  }
208 
209  delta= sqrt(delta);
210 
211  abs=sqrt(abs);
212 
213  if(abs < zero)
214  abs=1.0;
215 
216  if(delta < zero || (delta/abs) < tolerance)
217  is_converged=true;
218 
219  iter++;
220  }
221 
222 
223  for(int i=0; i<dim; i++)
224  {
225  Result(i)= HelpA(i,i);
226 
227  if(fabs(Result(i)) <zero)
228  Result(i)=0.0;
229  }
230 
231  return Result;
232  }
233 
244  static inline Vector EigenValuesDirectMethod(const Matrix& A)
245  {
246  // Given a real symmetric 3x3 matrix A, compute the eigenvalues
247  int dim= A.size1();
248  Vector Result(dim);
249  noalias(Result) = ZeroVector(dim);
250 
251  const double p1 = A(0,1)*A(0,1) + A(0,2)*A(0,2) + A(1,2)*A(1,2);
252  if (p1 == 0)
253  {//A is diagonal.
254  Result[0] = A(0,0);
255  Result[1] = A(1,1);
256  Result[2] = A(2,2);
257  return Result;
258  }
259 
260  const double q = (A(0,0) + A(1,1) + A(2,2)) / 3.0;
261  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;
262  const double p = sqrt(p2 / 6.0);
263 
264  Matrix B(3,3);
265  const double inv_p = 1.0/p;
266 
267  // B = (1 / p) * (A - q * I) where I is the identity matrix
268  B(0,0) = inv_p * (A(0,0) - q);
269  B(1,1) = inv_p * (A(1,1) - q);
270  B(2,2) = inv_p * (A(2,2) - q);
271  B(0,1) = inv_p * A(0,1);
272  B(1,0) = inv_p * A(1,0);
273  B(0,2) = inv_p * A(0,2);
274  B(2,0) = inv_p * A(2,0);
275  B(1,2) = inv_p * A(1,2);
276  B(2,1) = inv_p * A(2,1);
277 
278  //r = det(B) / 2
279  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) );
280 
281  // In exact arithmetic for a symmetric matrix -1 <= r <= 1
282  // but computation error can leave it slightly outside this range.
283  double phi = 0.0;
284  if (r <= -1) { phi = Globals::Pi / 3.0; }
285  else if (r >= 1) { phi = 0.0; }
286  else { phi = acos(r) / 3.0;}
287 
288  // the eigenvalues satisfy eig3 <= eig2 <= eig1
289  Result[0] = q + 2.0 * p * cos(phi);
290  Result[2] = q + 2.0 * p * cos(phi + (2.0 * Globals::Pi / 3.0));
291  Result[1] = 3.0 * q - Result[0] - Result[2]; //% since trace(A) = eig1 + eig2 + eig3
292 
293  return Result;
294  }
295 
296 
308  static inline void QRFactorization(const MatrixType& A, MatrixType& Q, MatrixType& R)
309  {
310 
311  //QR Factorization with Householder-Algo
312  int dim= A.size1();
313 
314  Vector y(dim);
315 
316  Vector w(dim);
317 
318  R.resize(dim,dim,false);
319 
321 
322  Q.resize(dim,dim,false);
323 
325 
326  Matrix Help(A.size1(),A.size2());
327  noalias(Help) = A;
328 
329  Matrix unity(dim,dim);
330  noalias(unity) = ZeroMatrix(dim,dim);
331 
332  for(int j=0; j<dim; j++)
333  unity(j,j)=1.0;
334 
335  std::vector<Matrix> HelpQ(dim-1);
336 
337  std::vector<Matrix> HelpR(dim-1);
338 
339  for(int i=0; i< dim-1; i++)
340  {
341  HelpQ[i].resize(dim,dim,false);
342  HelpR[i].resize(dim,dim,false);
343  noalias(HelpQ[i])= unity;
344  noalias(HelpR[i])= ZeroMatrix(dim,dim);
345  }
346 
347  for(int iteration=0; iteration< dim-1; iteration++)
348  {
349  //Vector y
350  for(int i=iteration; i<dim; i++)
351  y(i)= Help(i,iteration);
352 
353 
354  //Helpvalue l
355  double normy=0.0;
356 
357  for(int i=iteration; i<dim; i++)
358  normy += y(i)*y(i);
359 
360  normy= sqrt(normy);
361 
362  double l= sqrt((normy*(normy+fabs(y(iteration))))/2);
363 
364  double k=0.0;
365 
366  if(y[iteration] !=0)
367  k= - y(iteration)/fabs(y(iteration))*normy;
368  else
369  k= -normy;
370 
371  for(int i=iteration; i<dim; i++)
372  {
373  double e=0;
374 
375  if(i==iteration)
376  e=1;
377 
378  w(i)= 1/(2*l)*(y(i)-k*e);
379  }
380 
381  for(int i=iteration; i<dim; i++)
382  for(int j=iteration; j<dim; j++)
383  HelpQ[iteration](i,j)= unity(i,j)- 2*w(i)*w(j);
384 
385 
386  for(int i=iteration; i<dim; i++)
387  for(int j=iteration; j<dim; j++)
388  for(int k=iteration; k<dim; k++)
389  HelpR[iteration](i,j)+= HelpQ[iteration](i,k)*Help(k,j);
390 
391  Help= HelpR[iteration];
392 
393  }
394 
395  //Assembling R
396  for(int k=0; k<dim-1; k++)
397  {
398  for(int i=k; i<dim; i++)
399  for(int j=k; j<dim; j++)
400  R(i,j) =HelpR[k](i,j);
401 
402  }
403 
404 
405  for(int k=1; k<dim-1; k++)
406  {
407  for(int i=0; i<dim; i++)
408  for(int j=0; j<dim; j++)
409  for(int l=0; l<dim; l++)
410  Q(i,j)+= HelpQ[(k-1)](i,l)*HelpQ[k](l,j);
411  noalias(HelpQ[k])=Q;
412  }
413  if(dim-1==1)
414  noalias(Q)=HelpQ[0];
415 
416  }
417 
433  static inline void EigenVectors(const MatrixType& A,
434  MatrixType& vectors,
435  VectorType& lambda,
436  double zero_tolerance =1e-9,
437  int max_iterations = 10)
438  {
439  Matrix Help= A;
440 
441  for(int i=0; i<3; i++)
442  for(int j=0; j<3; j++)
443  Help(i,j)= Help(i,j);
444 
445 
446  vectors.resize(Help.size1(),Help.size2(),false);
447 
448  lambda.resize(Help.size1(),false);
449 
450  Matrix HelpDummy(Help.size1(),Help.size2());
451 
452  bool is_converged = false;
453 
454  Matrix unity(Help.size1(),Help.size2());
455  noalias(unity) = ZeroMatrix(Help.size1(),Help.size2());
456 
457  for(unsigned int i=0; i< Help.size1(); i++)
458  unity(i,i)= 1.0;
459 
460  Matrix V= unity;
461 
462  Matrix VDummy(Help.size1(),Help.size2());
463 
464  Matrix Rotation(Help.size1(),Help.size2());
465 
466 
467  for(int iterations=0; iterations<max_iterations; iterations++)
468  {
469 
470  is_converged= true;
471 
472  double a= 0.0;
473 
474  unsigned int index1= 0;
475 
476  unsigned int index2= 1;
477 
478  for(unsigned int i=0; i< Help.size1(); i++)
479  {
480  for(unsigned int j=(i+1); j< Help.size2(); j++)
481  {
482  if((fabs(Help(i,j)) > a ) && (fabs(Help(i,j)) > zero_tolerance))
483  {
484  a= fabs(Help(i,j));
485 
486  index1= i;
487  index2= j;
488 
489  is_converged= false;
490  }
491  }
492  }
493 
494 // KRATOS_WATCH( Help )
495 
496  if(is_converged)
497  break;
498 
499  //Calculation of Rotationangle
500 
501  double gamma= (Help(index2,index2)-Help(index1,index1))/(2*Help(index1,index2));
502 
503  double u=1.0;
504 
505  if(fabs(gamma) > zero_tolerance && fabs(gamma)< (1/zero_tolerance))
506  {
507  u= gamma/fabs(gamma)*1.0/(fabs(gamma)+sqrt(1.0+gamma*gamma));
508  }
509  else
510  {
511  if (fabs(gamma)>= (1.0/zero_tolerance))
512  u= 0.5/gamma;
513  }
514 
515  double c= 1.0/(sqrt(1.0+u*u));
516 
517  double s= c*u;
518 
519  double teta= s/(1.0+c);
520 
521  //Ratotion of the Matrix
522  HelpDummy= Help;
523 
524  HelpDummy(index2,index2)= Help(index2,index2)+u*Help(index1,index2);
525  HelpDummy(index1,index1)= Help(index1,index1)-u*Help(index1,index2);
526  HelpDummy(index1,index2)= 0.0;
527  HelpDummy(index2,index1)= 0.0;
528 
529  for(unsigned int i=0; i<Help.size1(); i++)
530  {
531  if((i!= index1) && (i!= index2))
532  {
533  HelpDummy(index2,i)=Help(index2,i)+s*(Help(index1,i)- teta*Help(index2,i));
534  HelpDummy(i,index2)=Help(index2,i)+s*(Help(index1,i)- teta*Help(index2,i));
535 
536  HelpDummy(index1,i)=Help(index1,i)-s*(Help(index2,i)+ teta*Help(index1,i));
537  HelpDummy(i,index1)=Help(index1,i)-s*(Help(index2,i)+ teta*Help(index1,i));
538  }
539  }
540 
541 
542  Help= HelpDummy;
543 
544  //Calculation of the eigenvectors V
545  Rotation =unity;
546  Rotation(index2,index1)=-s;
547  Rotation(index1,index2)=s;
548  Rotation(index1,index1)=c;
549  Rotation(index2,index2)=c;
550 
551 // Help.resize(A.size1(),A.size1(),false);
552 // noalias(Help)=ZeroMatrix(A.size1(),A.size1());
553 
554  noalias(VDummy) = ZeroMatrix(Help.size1(), Help.size2());
555 
556  for(unsigned int i=0; i< Help.size1(); i++)
557  {
558  for(unsigned int j=0; j< Help.size1(); j++)
559  {
560  for(unsigned int k=0; k< Help.size1(); k++)
561  {
562  VDummy(i,j) += V(i,k)*Rotation(k,j);
563  }
564  }
565  }
566  V= VDummy;
567 
568 // Matrix VTA(3,3);
569 // noalias(VTA) = ZeroMatrix(3,3);
570 // for(int i=0; i< Help.size1(); i++)
571 // {
572 // for(int j=0; j< Help.size1(); j++)
573 // {
574 // for(int k=0; k< Help.size1(); k++)
575 // {
576 // VTA(i,j) += V(k,i)*A(k,j);
577 // }
578 // }
579 // }
580 //
581 // for(int i=0; i< Help.size1(); i++)
582 // {
583 // for(int j=0; j< Help.size1(); j++)
584 // {
585 // for(int k=0; k< Help.size1(); k++)
586 // {
587 // Help(i,j) += VTA(i,k)*V(k,j);
588 // }
589 // }
590 // }
591 
592  }
593 
594  if(!(is_converged))
595  {
596  std::cout<<"########################################################"<<std::endl;
597  std::cout<<"Max_Iterations exceed in Jacobi-Seidel-Iteration (eigenvectors)"<<std::endl;
598  std::cout<<"########################################################"<<std::endl;
599  }
600 
601  for(unsigned int i=0; i< Help.size1(); i++)
602  {
603  for(unsigned int j=0; j< Help.size1(); j++)
604  {
605  vectors(i,j)= V(j,i);
606  }
607  }
608 
609  for(unsigned int i=0; i<Help.size1(); i++)
610  lambda(i)= Help(i,i);
611 
612  }
613 
614 
626  static inline void EigenVectors3x3(const Matrix& A, Matrix&V, Vector& d)
627  {
628 
629  if(A.size1()!=3 || A.size2()!=3)
630  std::cout<<" GIVEN MATRIX IS NOT 3x3 eigenvectors calculation "<<std::endl;
631 
632  Vector e(3);
633  noalias(e) = ZeroVector(3);
634  noalias(V) = ZeroMatrix(3,3);
635 
636  for (int i = 0; i < 3; i++) {
637  for (int j = 0; j < 3; j++) {
638  V(i,j) = A(i,j);
639  }
640  }
641 
642  // *******************//
643  //Symmetric Housholder reduction to tridiagonal form
644 
645  for (int j = 0; j < 3; j++) {
646  d[j] = V(2,j);
647  }
648 
649  // Householder reduction to tridiagonal form.
650 
651  for (int i = 2; i > 0; i--) {
652 
653  // Scale to avoid under/overflow.
654 
655  double scale = 0.0;
656  double h = 0.0;
657  for (int k = 0; k < i; k++) {
658  scale = scale + fabs(d[k]);
659  }
660  if (scale == 0.0) {
661  e[i] = d[i-1];
662  for (int j = 0; j < i; j++) {
663  d[j] = V(i-1,j);
664  V(i,j) = 0.0;
665  V(j,i) = 0.0;
666  }
667  } else {
668 
669  // Generate Householder vector.
670 
671  for (int k = 0; k < i; k++) {
672  d[k] /= scale;
673  h += d[k] * d[k];
674  }
675  double f = d[i-1];
676  double g = sqrt(h);
677  if (f > 0) {
678  g = -g;
679  }
680  e[i] = scale * g;
681  h = h - f * g;
682  d[i-1] = f - g;
683  for (int j = 0; j < i; j++) {
684  e[j] = 0.0;
685  }
686 
687  // Apply similarity transformation to remaining columns.
688 
689  for (int j = 0; j < i; j++) {
690  f = d[j];
691  V(j,i) = f;
692  g = e[j] + V(j,j) * f;
693  for (int k = j+1; k <= i-1; k++) {
694  g += V(k,j) * d[k];
695  e[k] += V(k,j) * f;
696  }
697  e[j] = g;
698  }
699  f = 0.0;
700  for (int j = 0; j < i; j++) {
701  e[j] /= h;
702  f += e[j] * d[j];
703  }
704  double hh = f / (h + h);
705  for (int j = 0; j < i; j++) {
706  e[j] -= hh * d[j];
707  }
708  for (int j = 0; j < i; j++) {
709  f = d[j];
710  g = e[j];
711  for (int k = j; k <= i-1; k++) {
712  V(k,j) -= (f * e[k] + g * d[k]);
713  }
714  d[j] = V(i-1,j);
715  V(i,j) = 0.0;
716  }
717  }
718  d[i] = h;
719  }
720 
721  // Accumulate transformations.
722 
723  for (int i = 0; i < 2; i++) {
724  V(2,i) = V(i,i);
725  V(i,i) = 1.0;
726  double h = d[i+1];
727  if (h != 0.0) {
728  for (int k = 0; k <= i; k++) {
729  d[k] = V(k,i+1) / h;
730  }
731  for (int j = 0; j <= i; j++) {
732  double g = 0.0;
733  for (int k = 0; k <= i; k++) {
734  g += V(k,i+1) * V(k,j);
735  }
736  for (int k = 0; k <= i; k++) {
737  V(k,j) -= g * d[k];
738  }
739  }
740  }
741  for (int k = 0; k <= i; k++) {
742  V(k,i+1) = 0.0;
743  }
744  }
745  for (int j = 0; j < 3; j++) {
746  d[j] = V(2,j);
747  V(2,j) = 0.0;
748  }
749  V(2,2) = 1.0;
750  e[0] = 0.0;
751 
752  // *******************//
753 
754  // Symmetric tridiagonal QL algorithm.
755 
756  for (int i = 1; i < 3; i++) {
757  e[i-1] = e[i];
758  }
759  e[2] = 0.0;
760 
761  double f = 0.0;
762  double tst1 = 0.0;
763  double eps = std::pow(2.0,-52.0);
764  for (int l = 0; l < 3; l++) {
765 
766  // Find small subdiagonal element
767 
768  tst1 = FIND_MAX(tst1,fabs(d[l]) + fabs(e[l]));
769  int m = l;
770  while (m < 3) {
771  if (fabs(e[m]) <= eps*tst1) {
772  break;
773  }
774  m++;
775  }
776 
777  // If m == l, d[l] is an eigenvalue,
778  // otherwise, iterate.
779 
780  if (m > l) {
781  int iter = 0;
782  do {
783  iter = iter + 1; // (Could check iteration count here.)
784 
785  // Compute implicit shift
786 
787  double g = d[l];
788  double p = (d[l+1] - g) / (2.0 * e[l]);
789  double r = hypot2(p,1.0);
790  if (p < 0) {
791  r = -r;
792  }
793  d[l] = e[l] / (p + r);
794  d[l+1] = e[l] * (p + r);
795  double dl1 = d[l+1];
796  double h = g - d[l];
797  for (int i = l+2; i < 3; i++) {
798  d[i] -= h;
799  }
800  f = f + h;
801 
802  // Implicit QL transformation.
803 
804  p = d[m];
805  double c = 1.0;
806  double c2 = c;
807  double c3 = c;
808  double el1 = e[l+1];
809  double s = 0.0;
810  double s2 = 0.0;
811  for (int i = m-1; i >= l; i--) {
812  c3 = c2;
813  c2 = c;
814  s2 = s;
815  g = c * e[i];
816  h = c * p;
817  r = hypot2(p,e[i]);
818  e[i+1] = s * r;
819  s = e[i] / r;
820  c = p / r;
821  p = c * d[i] - s * g;
822  d[i+1] = h + s * (c * g + s * d[i]);
823 
824  // Accumulate transformation.
825 
826  for (int k = 0; k < 3; k++) {
827  h = V(k,i+1);
828  V(k,i+1) = s * V(k,i) + c * h;
829  V(k,i) = c * V(k,i) - s * h;
830  }
831  }
832  p = -s * s2 * c3 * el1 * e[l] / dl1;
833  e[l] = s * p;
834  d[l] = c * p;
835 
836  // Check for convergence.
837 
838  } while (fabs(e[l]) > eps*tst1);
839  }
840  d[l] = d[l] + f;
841  e[l] = 0.0;
842  }
843 
844  // Sort eigenvalues and corresponding vectors.
845 
846  for (int i = 0; i < 2; i++) {
847  int k = i;
848  double p = d[i];
849  for (int j = i+1; j < 3; j++) {
850  if (d[j] < p) {
851  k = j;
852  p = d[j];
853  }
854  }
855  if (k != i) {
856  d[k] = d[i];
857  d[i] = p;
858  for (int j = 0; j < 3; j++) {
859  p = V(j,i);
860  V(j,i) = V(j,k);
861  V(j,k) = p;
862  }
863  }
864  }
865 
866  V = trans(V);
867 
868  // *******************//
869 
870 
871  }
872 
873 
874  static double hypot2(double x, double y) {
875  return std::sqrt(x*x+y*y);
876  }
877 
891  static inline void EigenVectors( MatrixType& A,
892  MatrixType& V,
893  TDataType& error_tolerance,
894  TDataType zero_tolerance)
895  {
896  //initial error
897  TDataType error = 1.0;
898  int n = A.size2();
899  //setting V to identity matrix
900  if( V.size1() != n )
901  V.resize(n,n,false);
903  //calculation loop (as long as there is no convergence)
904  //WARNING: iteration never exceeds
905  while( error > error_tolerance )
906  {
907  for( int i=0; i<n; i++ )
908  {
909  for( int j=i+1; j<n; j++ )
910  {
911  double theta = 0.0;
912  if( std::abs( A(i,j) ) >= zero_tolerance )
913  {
914  if( std::abs( A(i,i)-A(j,j) ) > 0.0 )
915  {
916  theta = 0.5*atan(2*A(i,j)/(A(i,i)-A(j,j)));
917  }
918  else theta = 0.25 * Globals::Pi;
919  }
920  MatrixType T(n,n);
921  noalias(T) = IdentityMatrix( n );
922 
923  T(i,i) = cos(theta);
924  T(i,j) = -sin(theta);
925  T(j,i) = -T(i,j);
926  T(j,j) = T(i,i);
927 
928  A = Mult( A, T );
929  MatrixType TT = Transpose(T);
930  A = Mult( TT, A );
931  V = Mult( V, T );
932  }
933  }
934  double sTot = 0.0;
935  double sDiag = 0.0;
936  for( unsigned int i=0; i<A.size1(); i++ )
937  {
938  for( unsigned int j=0; j<A.size2(); j++ )
939  {
940  sTot += std::abs(A(i,j));
941  }
942  sDiag+= std::abs(A(i,i));
943  }
944  error=(sTot-sDiag)/sDiag;
945  }
946  //sorting eigenvalues
947  int maxIndex = 0;
948  TDataType maxEv = A(0,0);
949  for( unsigned int i=0; i<A.size1(); i++ )
950  {
951  for( unsigned int j=i; j<A.size1(); j++ )
952  {
953  //searching current maximum
954  if( A(j,j) > maxEv )
955  {
956  maxIndex = j;
957  maxEv = A(j,j);
958  }
959  //swapping eigenvalue matrix
960  TDataType dummy = A(i,i);
961  A(i,i) = A(maxIndex,maxIndex);
962  A(maxIndex,maxIndex) = dummy;
963  //swapping eigenvector matrix
964  for( unsigned int k=0; k<A.size2(); k++ )
965  {
966  dummy = V(k,i);
967  V(k,i) = V(k,maxIndex);
968  V(k,maxIndex) = dummy;
969  }
970  }
971 
972  }
973  }//EigenVectors
974 
980  static inline MatrixType IdentityMatrix( SizeType size )
981  {
982  MatrixType A(size,size);
983  noalias(A) = ZeroMatrix( size, size );
984  for( unsigned int i=0; i<size ; i++ )
985  {
986  A(i,i) = 1.0;
987  }
988  return A;
989  }//IdentityMatrix
990 
997  static inline void Add( MatrixType& A, MatrixType& B )
998  {
999  for( unsigned int i=0; i<A.size1(); i++ )
1000  {
1001  for( unsigned int j=0; j<A.size2(); j++ )
1002  {
1003  A(i,j) += B(i,j);
1004  }
1005  }
1006  }
1007 
1014  static inline MatrixType Mult( MatrixType& A,
1015  MatrixType& B)
1016  {
1017  MatrixType C(A.size1(),B.size2());
1018  for( unsigned int i=0; i<A.size1(); i++ )
1019  {
1020  for( unsigned int j=0; j<B.size2(); j++ )
1021  {
1022  for( unsigned int k=0; k<A.size2(); k++ )
1023  {
1024  C(i,j) += B(k,j)*A(i,k);
1025  }
1026  }
1027  }
1028  return C;
1029  }//Mult
1030 
1034  static inline void Mult( MatrixType& M, TDataType a )
1035  {
1036  for( unsigned int i=0; i<M.size1(); i++ )
1037  {
1038  for( unsigned int j=0; j<M.size2(); j++ )
1039  {
1040  M(i,j) = M(i,j)*a;
1041  }
1042  }
1043  }
1044 
1048  static inline void Mult( VectorType& v, TDataType a )
1049  {
1050  for( unsigned int i=0; i<v.size(); i++ )
1051  {
1052  v(i) = v(i)*a;
1053  }
1054  }//Mult
1055 
1061  static inline MatrixType Transpose( MatrixType& A )
1062  {
1063  MatrixType AT(A.size2(),A.size1());
1064  noalias(AT) = ZeroMatrix(A.size2(),A.size1());
1065  for( unsigned int i=0; i<A.size1(); i++ )
1066  {
1067  for( unsigned int j=0; j<A.size2(); j++ )
1068  {
1069  AT(j,i) = A(i,j);
1070  }
1071  }
1072  return AT;
1073  }//Transpose
1074 
1078  static inline void Normalize( VectorType& v )
1079  {
1080  Mult( v, 1.0/(MathUtilsType::Norm( v )) );
1081  }
1082 
1093  static inline MatrixType StrainVectorToTensor( const VectorType& Strains )
1094  {
1095  KRATOS_TRY
1096 
1097  Matrix StrainTensor;
1098  //KRATOS_WATCH( Strains )
1099  if (Strains.size()==3)
1100  {
1101  StrainTensor.resize(2,2, false);
1102  //KRATOS_WATCH( StrainTensor )
1103  StrainTensor(0,0) = Strains[0];
1104  StrainTensor(0,1) = 0.5*Strains[2];
1105  StrainTensor(1,0) = 0.5*Strains[2];
1106  StrainTensor(1,1) = Strains[1];
1107  }
1108  else if (Strains.size()==6)
1109  {
1110  StrainTensor.resize(3,3, false);
1111  StrainTensor(0,0) = Strains[0];
1112  StrainTensor(0,1) = 0.5*Strains[3];
1113  StrainTensor(0,2) = 0.5*Strains[5];
1114  StrainTensor(1,0) = 0.5*Strains[3];
1115  StrainTensor(1,1) = Strains[1];
1116  StrainTensor(1,2) = 0.5*Strains[4];
1117  StrainTensor(2,0) = 0.5*Strains[5];
1118  StrainTensor(2,1) = 0.5*Strains[4];
1119  StrainTensor(2,2) = Strains[2];
1120  }
1121 
1122  //KRATOS_WATCH( StrainTensor )
1123  return StrainTensor;
1124  KRATOS_CATCH( "" )
1125  }
1126 
1127  static inline Vector TensorToStrainVector( const Matrix& Tensor )
1128  {
1129  KRATOS_TRY
1130  Vector StrainVector;
1131 
1132 
1133  if (Tensor.size1()==2)
1134  {
1135  StrainVector.resize(3);
1136  noalias(StrainVector) = ZeroVector(3);
1137  StrainVector(0) = Tensor(0,0);
1138  StrainVector(1) = Tensor(1,1);
1139  StrainVector(2) = 2.00*Tensor(0,1);
1140  }
1141  else if (Tensor.size1()==3)
1142  {
1143  StrainVector.resize(6);
1144  noalias(StrainVector) = ZeroVector(6);
1145  StrainVector(0) = Tensor(0,0);
1146  StrainVector(1) = Tensor(1,1);
1147  StrainVector(2) = Tensor(2,2);
1148  StrainVector(3) = 2.00*Tensor(0,1);
1149  StrainVector(4) = 2.00*Tensor(1,2);
1150  StrainVector(5) = 2.00*Tensor(0,2);
1151  }
1152 
1153 
1154  return StrainVector;
1155  KRATOS_CATCH( "" )
1156  }
1157 
1158 
1164  static int InvertMatrix( const MatrixType& input, MatrixType& inverse )
1165  {
1166  typedef permutation_matrix<std::size_t> pmatrix;
1167  Matrix A(input);
1168  pmatrix pm(A.size1());
1169  int singular = lu_factorize(A,pm);
1170  inverse.assign( IdentityMatrix(A.size1()));
1171  lu_substitute(A, pm, inverse);
1172  return singular;
1173  }
1174 
1180  static double NormTensor(Matrix& Tensor)
1181  {
1182  double result=0.0;
1183  for(unsigned int i=0; i< Tensor.size1(); i++)
1184  for(unsigned int j=0; j< Tensor.size2(); j++)
1185  result+= Tensor(i,j)*Tensor(i,j);
1186 
1187  result= sqrt(result);
1188 
1189  return result;
1190  }
1191 
1197  static inline void VectorToTensor(const Vector& Stress,Matrix& Tensor)
1198  {
1199  if(Stress.size()==6)
1200  {
1201  Tensor.resize(3,3,false);
1202  Tensor(0,0)= Stress(0);
1203  Tensor(0,1)= Stress(3);
1204  Tensor(0,2)= Stress(5);
1205  Tensor(1,0)= Stress(3);
1206  Tensor(1,1)= Stress(1);
1207  Tensor(1,2)= Stress(4);
1208  Tensor(2,0)= Stress(5);
1209  Tensor(2,1)= Stress(4);
1210  Tensor(2,2)= Stress(2);
1211  }
1212  if(Stress.size()==3)
1213  {
1214  Tensor.resize(2,2,false);
1215  Tensor(0,0)= Stress(0);
1216  Tensor(0,1)= Stress(2);
1217  Tensor(1,0)= Stress(2);
1218  Tensor(1,1)= Stress(1);
1219  }
1220 
1221  }
1222 
1228  static void TensorToVector( const Matrix& Tensor, Vector& Vector)
1229  {
1230  //if(Vector.size()!= 6)
1231  unsigned int dim = Tensor.size1();
1232  if (dim==3)
1233  {
1234  Vector.resize(6,false);
1235  Vector(0)= Tensor(0,0);
1236  Vector(1)= Tensor(1,1);
1237  Vector(2)= Tensor(2,2);
1238  Vector(3)= Tensor(0,1);
1239  Vector(4)= Tensor(1,2);
1240  Vector(5)= Tensor(2,0);
1241  }
1242  else if(dim==2)
1243  {
1244  Vector.resize(3,false);
1245  Vector(0)= Tensor(0,0);
1246  Vector(1)= Tensor(1,1);
1247  Vector(2)= Tensor(0,1);
1248  }
1249 
1250  }
1251 
1252  static inline void TensorToMatrix(Fourth_Order_Tensor& Tensor,Matrix& Matrix)
1253  {
1254 
1255 
1256  // Simetrias seguras
1257  // Cijkl = Cjilk;
1258  // Cijkl = Cklji;
1259  if (Tensor[0].size()== 3)
1260  {
1261  // Tensor de cuarto orden cuyos componentes correspondes a una matriz de 3x3
1262  if(Matrix.size1()!=6 || Matrix.size2()!=6)
1263  Matrix.resize(6,6,false);
1264  Matrix(0,0) = Tensor[0][0](0,0);
1265  Matrix(0,1) = Tensor[0][0](1,1);
1266  Matrix(0,2) = Tensor[0][0](2,2);
1267  Matrix(0,3) = Tensor[0][0](0,1);
1268  Matrix(0,4) = Tensor[0][0](0,2);
1269  Matrix(0,5) = Tensor[0][0](1,2);
1270 
1271  Matrix(1,0) = Tensor[1][1](0,0);
1272  Matrix(1,1) = Tensor[1][1](1,1);
1273  Matrix(1,2) = Tensor[1][1](2,2);
1274  Matrix(1,3) = Tensor[1][1](0,1);
1275  Matrix(1,4) = Tensor[1][1](0,2);
1276  Matrix(1,5) = Tensor[1][1](1,2);
1277 
1278  Matrix(2,0) = Tensor[2][2](0,0);
1279  Matrix(2,1) = Tensor[2][2](1,1);
1280  Matrix(2,2) = Tensor[2][2](2,2);
1281  Matrix(2,3) = Tensor[2][2](0,1);
1282  Matrix(2,4) = Tensor[2][2](0,2);
1283  Matrix(2,5) = Tensor[2][2](1,2);
1284 
1285  Matrix(3,0) = Tensor[0][1](0,0);
1286  Matrix(3,1) = Tensor[0][1](1,1);
1287  Matrix(3,2) = Tensor[0][1](2,2);
1288  Matrix(3,3) = Tensor[0][1](0,1);
1289  Matrix(3,4) = Tensor[0][1](0,2);
1290  Matrix(3,5) = Tensor[0][1](1,2);
1291 
1292  Matrix(4,0) = Tensor[0][2](0,0);
1293  Matrix(4,1) = Tensor[0][2](1,1);
1294  Matrix(4,2) = Tensor[0][2](2,2);
1295  Matrix(4,3) = Tensor[0][2](0,1);
1296  Matrix(4,4) = Tensor[0][2](0,2);
1297  Matrix(4,5) = Tensor[0][2](1,2);
1298 
1299  Matrix(5,0) = Tensor[1][2](0,0);
1300  Matrix(5,1) = Tensor[1][2](1,1);
1301  Matrix(5,2) = Tensor[1][2](2,2);
1302  Matrix(5,3) = Tensor[1][2](0,1);
1303  Matrix(5,4) = Tensor[1][2](0,2);
1304  Matrix(5,5) = Tensor[1][2](1,2);
1305  }
1306  else
1307  {
1308  // Tensor de cuarto orden cuyos componentes correspondes a una matriz de 2x2
1309  if(Matrix.size1()!=3 || Matrix.size2()!=3)
1310  Matrix.resize(3,3,false);
1311  Matrix(0,0) = Tensor[0][0](0,0);
1312  Matrix(0,1) = Tensor[0][0](1,1);
1313  Matrix(0,2) = Tensor[0][0](0,1);
1314  Matrix(1,0) = Tensor[1][1](0,0);
1315  Matrix(1,1) = Tensor[1][1](1,1);
1316  Matrix(1,2) = Tensor[1][1](0,1);
1317  Matrix(2,0) = Tensor[0][1](0,0);
1318  Matrix(2,1) = Tensor[0][1](1,1);
1319  Matrix(2,2) = Tensor[0][1](0,1);
1320 
1321  }
1322 
1323  }
1324 
1330  static void MatrixToTensor(MatrixType& A,std::vector<std::vector<Matrix> >& Tensor)
1331  {
1332  int help1 = 0;
1333  int help2 = 0;
1334  double coeff = 1.0;
1335 
1336  Tensor.resize(3);
1337 
1338  for(unsigned int i=0; i<3; i++)
1339  {
1340  Tensor[i].resize(3);
1341  for(unsigned int j=0; j<3; j++)
1342  {
1343  Tensor[i][j].resize(3,3,false);
1344  noalias(Tensor[i][j])= ZeroMatrix(3,3);
1345  for(unsigned int k=0; k<3; k++)
1346  for(unsigned int l=0; l<3; l++)
1347  {
1348  if(i==j) help1= i;
1349  else
1350  {
1351  if((i==0 && j==1) || (i==1 && j==0)) help1= 3;
1352  if((i==1 && j==2) || (i==2 && j==1)) help1= 4;
1353  if((i==2 && j==0) || (i==0 && j==2)) help1= 5;
1354  }
1355  if(k==l)
1356  {
1357  help2= k;
1358  coeff=1.0;
1359  }
1360  else
1361  {
1362  coeff=0.5;
1363  if((k==0 && l==1) || (k==1 && l==0)) help2= 3;
1364  if((k==1 && l==2) || (k==2 && l==1)) help2= 4;
1365  if((k==2 && l==0) || (k==0 && l==2)) help2= 5;
1366  }
1367 
1368  Tensor[i][j](k,l)= A(help1,help2)*coeff;
1369  }
1370  }
1371  }
1372 
1373 
1374  }
1381  {
1382  int help1 = 0;
1383  int help2 = 0;
1384  double coeff = 1.0;
1385  std::fill(Tensor.begin(), Tensor.end(), 0.0);
1386  for(unsigned int i=0; i<3; i++)
1387  {
1388  for(unsigned int j=0; j<3; j++)
1389  {
1390  for(unsigned int k=0; k<3; k++)
1391  for(unsigned int l=0; l<3; l++)
1392  {
1393  if(i==j) help1= i;
1394  else
1395  {
1396  if((i==0 && j==1) || (i==1 && j==0)) help1= 3;
1397  if((i==1 && j==2) || (i==2 && j==1)) help1= 4;
1398  if((i==2 && j==0) || (i==0 && j==2)) help1= 5;
1399  }
1400  if(k==l)
1401  {
1402  help2= k;
1403  coeff=1.0;
1404  }
1405  else
1406  {
1407  coeff=0.5;
1408  if((k==0 && l==1) || (k==1 && l==0)) help2= 3;
1409  if((k==1 && l==2) || (k==2 && l==1)) help2= 4;
1410  if((k==2 && l==0) || (k==0 && l==2)) help2= 5;
1411  }
1412 
1413  Tensor[i*27+j*9+k*3+l]= A(help1,help2)*coeff;
1414  }
1415  }
1416  }
1417 
1418 
1419  }
1425  static void TensorToMatrix(std::vector<std::vector<Matrix> >& Tensor,Matrix& Matrix)
1426  {
1427  int help1 = 0;
1428  int help2 = 0;
1429  int help3 = 0;
1430  int help4 = 0;
1431  double coeff = 1.0;
1432 
1433  if(Matrix.size1()!=6 || Matrix.size2()!=6)
1434  Matrix.resize(6,6,false);
1435 
1436  for(unsigned int i=0; i<6; i++)
1437  for(unsigned int j=0; j<6; j++)
1438  {
1439  if(i<3)
1440  {
1441  help1= i;
1442  help2= i;
1443  }
1444  else
1445  {
1446  if(i==3)
1447  {
1448  help1= 0;
1449  help2= 1;
1450  }
1451  if(i==4)
1452  {
1453  help1= 1;
1454  help2= 2;
1455  }
1456  if(i==5)
1457  {
1458  help1= 2;
1459  help2= 0;
1460  }
1461  }
1462 
1463  if(j<3)
1464  {
1465  help3= j;
1466  help4= j;
1467  coeff= 1.0;
1468  }
1469  else
1470  {
1471  if(j==3)
1472  {
1473  help3= 0;
1474  help4= 1;
1475  }
1476  if(j==4)
1477  {
1478  help3= 1;
1479  help4= 2;
1480  }
1481  if(j==5)
1482  {
1483  help3= 2;
1484  help4= 0;
1485  }
1486  coeff= 2.0;
1487  }
1488 
1489  Matrix(i,j)= Tensor[help1][help2](help3,help4)*coeff;
1490  }
1491 
1492  }
1493 
1499  static void TensorToMatrix( const array_1d<double, 81>& Tensor, Matrix& Matrix )
1500  {
1501  if(Matrix.size1()!=6 || Matrix.size2()!=6)
1502  Matrix.resize(6,6,false);
1503 
1504  Matrix(0,0) = Tensor[0];
1505  Matrix(0,1) = Tensor[4];
1506  Matrix(0,2) = Tensor[8];
1507  Matrix(0,3) = 2.0*Tensor[1];
1508  Matrix(0,4) = 2.0*Tensor[5];
1509  Matrix(0,5) = 2.0*Tensor[6];
1510 
1511  Matrix(1,0) = Tensor[36];
1512  Matrix(1,1) = Tensor[40];
1513  Matrix(1,2) = Tensor[44];
1514  Matrix(1,3) = 2.0*Tensor[37];
1515  Matrix(1,4) = 0.0*Tensor[41];
1516  Matrix(1,5) = 0.0*Tensor[42];
1517 
1518  Matrix(2,0) = Tensor[72];
1519  Matrix(2,1) = Tensor[76];
1520  Matrix(2,2) = Tensor[80];
1521  Matrix(2,3) = 2.0*Tensor[73];
1522  Matrix(2,4) = 2.0*Tensor[77];
1523  Matrix(2,5) = 2.0*Tensor[78];
1524 
1525  Matrix(3,0) = Tensor[9];
1526  Matrix(3,1) = Tensor[13];
1527  Matrix(3,2) = Tensor[18];
1528  Matrix(3,3) = 2.0*Tensor[10];
1529  Matrix(3,4) = 2.0*Tensor[14];
1530  Matrix(3,5) = 2.0*Tensor[15];
1531 
1532  Matrix(4,0) = Tensor[45];
1533  Matrix(4,1) = Tensor[49];
1534  Matrix(4,2) = Tensor[53];
1535  Matrix(4,3) = 2.0*Tensor[46];
1536  Matrix(4,4) = 0.0*Tensor[50];
1537  Matrix(4,5) = 0.0*Tensor[51];
1538 
1539  Matrix(5,0) = Tensor[54];
1540  Matrix(5,1) = Tensor[58];
1541  Matrix(5,2) = Tensor[62];
1542  Matrix(5,3) = 2.0*Tensor[55];
1543  Matrix(5,4) = 2.0*Tensor[59];
1544  Matrix(5,5) = 2.0*Tensor[60];
1545 
1546  }
1551  static void DeviatoricUnity(std::vector<std::vector<Matrix> >& Unity)
1552  {
1553  Unity.resize(3);
1554 
1555  Matrix kronecker(3,3);
1556  noalias(kronecker)=ZeroMatrix(3,3);
1557  for(unsigned int i=0; i<3; i++)
1558  {
1559  kronecker(i,i)=1;
1560  }
1561 
1562  for(unsigned int i=0; i<3; i++)
1563  {
1564  Unity[i].resize(3);
1565  for(unsigned int j=0; j<3; j++)
1566  {
1567  Unity[i][j].resize(3,3,false);
1568  noalias(Unity[i][j])= ZeroMatrix(3,3);
1569 
1570  for(unsigned int k=0; k<3; k++)
1571  {
1572  for(unsigned int l=0; l<3; l++)
1573  {
1574  Unity[i][j](k,l)=kronecker(i,k)*kronecker(j,l)
1575  -1.0/3.0*kronecker(i,j)*kronecker(k,l);
1576  }
1577  }
1578  }
1579  }
1580  }
1581 
1587  {
1588  Matrix kronecker(3,3);
1589  noalias(kronecker)=ZeroMatrix(3,3);
1590  for(unsigned int i=0; i<3; i++)
1591  {
1592  kronecker(i,i)=1;
1593  }
1594 
1595  for(unsigned int i=0; i<3; i++)
1596  for(unsigned int j=0; j<3; j++)
1597  for(unsigned int k=0; k<3; k++)
1598  for(unsigned int l=0; l<3; l++)
1599  Unity[27*i+9*j+3*k+l]=kronecker(i,k)*kronecker(j,l)
1600  -1.0/3.0*kronecker(i,j)*kronecker(k,l);
1601  }
1602 
1613  static bool Clipping(std::vector<Point* >& clipping_points,std::vector<Point* >& subjected_points, std::vector<Point* >& result_points, double tolerance)
1614  {
1615  result_points= subjected_points;
1616  Vector actual_edge(3);
1617  Vector actual_normal(3);
1618  std::vector<Point* > temp_results;
1619  bool is_visible= false;
1620  for(unsigned int clipp_edge=0; clipp_edge<clipping_points.size(); clipp_edge++)
1621  {
1622  temp_results.clear();
1623  unsigned int index_clipp_2=0;
1624  if(clipp_edge< (clipping_points.size()-1))
1625  index_clipp_2= clipp_edge+1;
1626  //define clipping edge vector
1627  noalias(actual_edge)= *(clipping_points[clipp_edge])-*(clipping_points[index_clipp_2]);
1628  noalias(actual_edge)= actual_edge/sqrt(inner_prod(actual_edge,actual_edge));
1629 
1630  //define normal on clipping-edge vector towards visible side
1631  if(clipp_edge< (clipping_points.size()-2))
1632  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));
1633  else if(clipp_edge< (clipping_points.size()-1))
1634  actual_normal=*(clipping_points[0])-(*(clipping_points[clipp_edge])+actual_edge*inner_prod((*(clipping_points[0])-*(clipping_points[clipp_edge])),actual_edge));
1635  else
1636  actual_normal=*(clipping_points[1])-(*(clipping_points[clipp_edge])+actual_edge*inner_prod((*(clipping_points[1])-*(clipping_points[clipp_edge])),actual_edge));
1637 
1638  noalias(actual_normal)=actual_normal/(sqrt(inner_prod(actual_normal,actual_normal)));
1639 
1640  //test if the first point is visible or unvisible
1641  if( inner_prod((*(result_points[0])-*(clipping_points[clipp_edge])), actual_normal)> tolerance)
1642  {
1643  is_visible= true;
1644  }
1645  else
1646  {
1647  is_visible= false;
1648  }
1649 
1650  for(unsigned int subj_edge=0; subj_edge< result_points.size(); subj_edge++)
1651  {
1652  unsigned int index_subj_2=0;
1653 
1654  if(subj_edge< (result_points.size()-1))
1655  index_subj_2= subj_edge+1;
1656 
1657  //Test whether the points of the actual subj_edge lay on clipp_edge
1658  if(fabs(inner_prod((*(result_points[subj_edge])-(*(clipping_points[clipp_edge]))), actual_normal))<= tolerance)
1659  {
1660  temp_results.push_back(result_points[subj_edge]);
1661  if( inner_prod((*(result_points[index_subj_2])-*(clipping_points[clipp_edge])), actual_normal)> tolerance)
1662  is_visible= true;
1663  else
1664  is_visible= false;
1665 
1666  continue;
1667  }
1668  //Calculate minimal distance between the two points
1669  Vector b(2);
1670  b(0)= -inner_prod((*(result_points[index_subj_2])-*(result_points[subj_edge])),(*(result_points[subj_edge])-*(clipping_points[clipp_edge])));
1671  b(1)= inner_prod((*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])),(*(result_points[subj_edge])-*(clipping_points[clipp_edge])));
1672  Matrix A(2,2);
1673  A(0,0)=inner_prod((*(result_points[index_subj_2])-*(result_points[subj_edge])),(*(result_points[index_subj_2])-*(result_points[subj_edge])));
1674  A(0,1)=-inner_prod((*(result_points[index_subj_2])-*(result_points[subj_edge])),(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])));
1675  A(1,0)= A(0,1);
1676  A(1,1)=inner_prod(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge]),*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge]));
1677  Vector coeff(2);
1678  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)));
1679  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));
1680 
1681 
1682  //TEST on distance to endpoints of the line
1683  Vector dist_vec(3);
1684  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])));
1685 
1686  if( coeff(0) > tolerance && coeff(0) < (1-tolerance)&& (sqrt(inner_prod(dist_vec,dist_vec))< tolerance))
1687  {
1688  if(is_visible)
1689  temp_results.push_back(result_points[subj_edge]);
1690 
1691  temp_results.push_back(new Point((*(clipping_points[clipp_edge])+coeff(1)*(*(clipping_points[index_clipp_2])-*(clipping_points[clipp_edge])))));
1692 
1693  is_visible= !is_visible;
1694 
1695  continue;
1696  }
1697  if(is_visible)
1698  temp_results.push_back(result_points[subj_edge]);
1699  }
1700  result_points=temp_results;
1701  }
1702  if(result_points.size()==0)
1703  return false;
1704  else
1705  return true;
1706  }
1707 
1708 
1709  inline static VectorType range(const unsigned int start, const unsigned int end)
1710  {
1711  int size = end-start;
1712  if(size<0)
1713  KRATOS_ERROR<<" range out of bounds start:"<<start<<" end:"<<end<<std::endl;
1714 
1715  VectorType b(size);
1716 
1717  for(int i = 0; i<size; ++i)
1718  b[i] = start + i;
1719 
1720  return b;
1721  }
1722 
1723 
1724  inline static MatrixType project(const MatrixType& rMatrix, VectorType irange, VectorType jrange)
1725  {
1726 
1727  MatrixType A(irange.size(), jrange.size());
1728 
1729  for(unsigned int i = 0; i<irange.size(); ++i)
1730  for(unsigned int j = 0; j<jrange.size(); ++j)
1731  A(i,j) = rMatrix(irange[i],jrange[j]);
1732 
1733  return A;
1734  }
1735 
1736 
1737  inline static MatrixType& project(MatrixType& rMatrixA, VectorType irange, VectorType jrange, const MatrixType& rMatrixB)
1738  {
1739 
1740  for(unsigned int i = 0; i<irange.size(); ++i)
1741  for(unsigned int j = 0; j<jrange.size(); ++j)
1742  rMatrixA(irange[i],jrange[j]) = rMatrixB(i,j);
1743 
1744  return rMatrixA;
1745  }
1746 
1747 
1748  inline static VectorType project(const VectorType& rVector, VectorType irange)
1749  {
1750 
1751  VectorType b(irange.size());
1752 
1753  for(unsigned int i = 0; i<irange.size(); ++i)
1754  b[i] = rVector[irange[i]];
1755 
1756  return b;
1757  }
1758 
1759 
1760 
1761 private:
1762 };// class SolidMechanicsMathUtilities
1763 }
1764 #endif /* KRATOS_SOLID_MECHANICS_MATH_UTILITIESS_H_INCLUDED defined */
#define FIND_MAX(a, b)
Definition: solid_mechanics_math_utilities.hpp:18
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
Point class.
Definition: point.h:59
static void TensorToVector(const Matrix &Tensor, Vector &Vector)
Definition: solid_mechanics_math_utilities.hpp:1228
static VectorType project(const VectorType &rVector, VectorType irange)
Definition: solid_mechanics_math_utilities.hpp:1748
static void TensorToMatrix(std::vector< std::vector< Matrix > > &Tensor, Matrix &Matrix)
Definition: solid_mechanics_math_utilities.hpp:1425
static MatrixType IdentityMatrix(SizeType size)
Definition: solid_mechanics_math_utilities.hpp:979
static void Normalize(VectorType &v)
Definition: solid_mechanics_math_utilities.hpp:1078
static MatrixType StrainVectorToTensor(const VectorType &Strains)
Definition: solid_mechanics_math_utilities.hpp:1093
static void QRFactorization(const MatrixType &A, MatrixType &Q, MatrixType &R)
Definition: solid_mechanics_math_utilities.hpp:307
static void EigenVectors(const MatrixType &A, MatrixType &vectors, VectorType &lambda, double zero_tolerance=1e-9, int max_iterations=10)
Definition: solid_mechanics_math_utilities.hpp:433
static void MatrixToTensor(MatrixType &A, array_1d< double, 81 > &Tensor)
Definition: solid_mechanics_math_utilities.hpp:1380
static MatrixType project(const MatrixType &rMatrix, VectorType irange, VectorType jrange)
Definition: solid_mechanics_math_utilities.hpp:1724
static Vector EigenValues(const Matrix &A, double tolerance, double zero)
Definition: solid_mechanics_math_utilities.hpp:143
static void DeviatoricUnity(array_1d< double, 81 > &Unity)
Definition: solid_mechanics_math_utilities.hpp:1586
static Vector EigenValuesDirectMethod(const Matrix &A)
Definition: solid_mechanics_math_utilities.hpp:244
DenseVector< Vector > Second_Order_Tensor
Definition: solid_mechanics_math_utilities.hpp:51
Matrix MatrixType
Definition: solid_mechanics_math_utilities.hpp:41
unsigned int SizeType
Definition: solid_mechanics_math_utilities.hpp:47
static void DeviatoricUnity(std::vector< std::vector< Matrix > > &Unity)
Definition: solid_mechanics_math_utilities.hpp:1551
static VectorType range(const unsigned int start, const unsigned int end)
Definition: solid_mechanics_math_utilities.hpp:1709
static MatrixType Transpose(MatrixType &A)
Definition: solid_mechanics_math_utilities.hpp:1060
static void TensorToMatrix(const array_1d< double, 81 > &Tensor, Matrix &Matrix)
Definition: solid_mechanics_math_utilities.hpp:1499
static bool CardanoFormula(double a, double b, double c, double d, Vector &solution)
Definition: solid_mechanics_math_utilities.hpp:76
DenseMatrix< Second_Order_Tensor > Matrix_Second_Tensor
Definition: solid_mechanics_math_utilities.hpp:57
static void Mult(MatrixType &M, TDataType a)
Definition: solid_mechanics_math_utilities.hpp:1034
static MatrixType Mult(MatrixType &A, MatrixType &B)
Definition: solid_mechanics_math_utilities.hpp:1013
static void EigenVectors3x3(const Matrix &A, Matrix &V, Vector &d)
Definition: solid_mechanics_math_utilities.hpp:626
static Vector TensorToStrainVector(const Matrix &Tensor)
Definition: solid_mechanics_math_utilities.hpp:1127
MathUtils< TDataType > MathUtilsType
Definition: solid_mechanics_math_utilities.hpp:49
static int InvertMatrix(const MatrixType &input, MatrixType &inverse)
Definition: solid_mechanics_math_utilities.hpp:1164
static void MatrixToTensor(MatrixType &A, std::vector< std::vector< Matrix > > &Tensor)
Definition: solid_mechanics_math_utilities.hpp:1330
static bool Clipping(std::vector< Point * > &clipping_points, std::vector< Point * > &subjected_points, std::vector< Point * > &result_points, double tolerance)
Definition: solid_mechanics_math_utilities.hpp:1613
static void Add(MatrixType &A, MatrixType &B)
Definition: solid_mechanics_math_utilities.hpp:997
static void Mult(VectorType &v, TDataType a)
Definition: solid_mechanics_math_utilities.hpp:1048
static void EigenVectors(MatrixType &A, MatrixType &V, TDataType &error_tolerance, TDataType zero_tolerance)
Definition: solid_mechanics_math_utilities.hpp:891
unsigned int IndexType
Definition: solid_mechanics_math_utilities.hpp:45
Vector VectorType
Definition: solid_mechanics_math_utilities.hpp:43
static double NormTensor(Matrix &Tensor)
Definition: solid_mechanics_math_utilities.hpp:1180
static void VectorToTensor(const Vector &Stress, Matrix &Tensor)
Definition: solid_mechanics_math_utilities.hpp:1197
static double hypot2(double x, double y)
Definition: solid_mechanics_math_utilities.hpp:873
DenseVector< Second_Order_Tensor > Third_Order_Tensor
Definition: solid_mechanics_math_utilities.hpp:53
static MatrixType & project(MatrixType &rMatrixA, VectorType irange, VectorType jrange, const MatrixType &rMatrixB)
Definition: solid_mechanics_math_utilities.hpp:1737
static void TensorToMatrix(Fourth_Order_Tensor &Tensor, Matrix &Matrix)
Definition: solid_mechanics_math_utilities.hpp:1252
DenseVector< DenseVector< Matrix > > Fourth_Order_Tensor
Definition: solid_mechanics_math_utilities.hpp:55
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
#define KRATOS_ERROR
Definition: exception.h:161
start
Definition: DEM_benchmarks.py:17
end
Definition: DEM_benchmarks.py:180
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
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
float error
Definition: PecletTest.py:102
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
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
f
Definition: generate_convection_diffusion_explicit_element.py:112
V
Definition: generate_droplet_dynamics.py:256
h
Definition: generate_droplet_dynamics.py:91
input
Definition: generate_frictional_mortar_condition.py:435
int C
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:27
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 n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int m
Definition: run_marine_rain_substepping.py:8
dummy
Definition: script.py:194
A
Definition: sensitivityMatrix.py:70
p
Definition: sensitivityMatrix.py:52
x
Definition: sensitivityMatrix.py:49
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