NeoPZ
TPZYCSandlerDimaggioL2.h
Go to the documentation of this file.
1 // $Id: TPZYCSandlerDimaggio.h,v 1.11 2009-06-29 22:54:01 erick Exp $
2 
3 #ifndef TPZYCSANDLERDIMAGGIOL2_H
4 #define TPZYCSANDLERDIMAGGIOL2_H
5 
7 #include "pzlog.h"
8 
9 #ifndef CHECKCONV
10 #define CHECKCONV
11 #include "checkconv.h"
12 #endif
13 
14 #include "fadType.h"
15 
16 #ifdef LOG4CXX
17 #include "pzlog.h"
18 
19 static LoggerPtr loggerSML2(Logger::getLogger("material.plasticity.SML2"));
20 
21 #endif
22 
29 public:
30 
31  enum {
32  NYield = 2
33  };
34 
35  int ClassId() const override;
36 
38  }
39 
41  }
42 
45  return *this;
46  }
47 
49 
50  }
51 
52  const char * Name() const {
53  return "TPZYCSandlerDimaggioL2";
54  }
55 
56  void Print(std::ostream & out) const override {
57  out << "\n" << this->Name();
59  }
60 
61 
69  template < class T>
70  void Compute(const TPZTensor<T> & sigma, const T & A, TPZVec<T> &res, int checkForcedYield) const;
71 
79  template <class T>
80  void N(const TPZTensor<T> & sigma, const T & A, TPZVec<TPZTensor<T> > & Ndir, int checkForcedYield) const;
81 
89  template <class T>
90  void H(const TPZTensor<T> & sigma, const T & A, TPZVec<T> & h, int checkForcedYield) const;
91 
102  void InitialGuess(const TPZElasticResponse &ER, REAL L, TPZTensor<REAL> &sigtrial, REAL &epspproj,
103  TPZVec<REAL> &delgamma, TPZTensor<REAL> &sigproj);
104 
105  inline REAL InitialDamage() {
106  // for this particular case!!! toto
107  REAL X, L, alpha(0.);
108  ComputeX(alpha, X);
109  SolveL(X, L);
110  // L -= 0.01;
111  return L;
112 
113  }
114 
116  void ProjectBorder(const TPZElasticResponse &ER, REAL &L, TPZVec<STATE> &sigtrialIJ);
117 
118 public:
119 
120  virtual int GetNYield() const override {
121  return as_integer(NYield);
122  }
123 
125 
126 
127  static void McCormicRanchSand(TPZYCSandlerDimaggio & material);
128 public:
129 
130 };
131 
132 template <class T>
133 inline void TPZYCSandlerDimaggioL2::Compute(const TPZTensor<T> & sigma, const T & A, TPZVec<T> &res, int checkForcedYield) const {
134  // the thermo force A in this case is assumed to be the
135  // plastic volumetric strain itself. In fact it is not,
136  // but the resultant derivatives are correct for practical purposes.
137 
138  // The following line evaluates L, the value of the first
139  // invariant of stresses at the intersection of the
140  // shear and hardening cap yield criteria / plastic potential.
141  // It is first evaluated as REAL type to avoid unnecessary
142  // derivatives evaluation.
143 #ifdef LOG4CXX_PLASTICITY
144  {
145  LoggerPtr logger(Logger::getLogger("plasticity.SandlerDimaggioL"));
146  std::stringstream sout;
147  sout << ">>> TPZYCSandlerDimaggio::Compute *** - Plastic Potential / Yield - associative";
148  LOGPZ_INFO(logger, sout.str().c_str());
149  }
150 #endif
151 
152  // REAL L_REAL = TPZExtractVal::val(A);
153  // REAL X_REAL;
154  // ComputeX((REAL)TPZExtractVal::val(A), X_REAL);
155  // LInitialGuess(X_REAL, L_REAL);
156  // SolveL(X_REAL, L_REAL);
157 
158  T I1 = sigma.I1();
159  T J2 = sigma.J2();
160 
161  if (fIsonCap) {
162  REAL lmax = LMax();
163  REAL FI1;
164  ComputeF(lmax, FI1);
165  if (fabs((REAL) TPZExtractVal::val(J2)) < 1.e-6) {
166  res[1] = -FI1; // avoiding nan derivatives
167  } else {
168  res[1] = sqrt(J2) - FI1;
169  }
170  res[0] = I1 - T(lmax);
171 #ifdef LOG4CXX
172  if (loggerSML->isDebugEnabled()) {
173  std::stringstream sout;
174 
175  T sqj2 = J2;
176  if (fabs(TPZExtractVal::val(J2)) > 1.e-6) {
177  sqj2 = sqrt(sqj2);
178  }
179  sout << "Computing the distance from cap entry I1 " << I1 << " sqJ2 " << sqj2 << " lmax " << lmax << " F(lmax) " << FI1;
180  LOGPZ_DEBUG(loggerSML, sout.str())
181  }
182 #endif
183  } else {
184  // f1 - Modified Drucker-Prager as shear Yield Criterium
185  T FI1;
186  ComputeF(I1, FI1);
187  if (fabs((REAL) TPZExtractVal::val(J2)) < 1.e-6) {
188  res[0] = -FI1; // avoiding nan derivatives
189  } else {
190  res[0] = sqrt(J2) - FI1;
191  }
192 
193  // f2 - ellipsoidal hardening/softening cap
194  T L = A;
195  T FL;
196  // T L(L_REAL), X;
197  // ComputeX(A, X);
198  // SolveL(X, L); // evaluating the derivatives of L
199  ComputeF(L, FL);
200 
201 #ifdef LOG4CXX_PLASTICITY
202  if (fabs((REAL) TPZExtractVal::val(FL)) < 1.e-5) {
203  {
204  LoggerPtr logger(Logger::getLogger("plasticity.SandlerDimaggio"));
205  std::stringstream sout;
206  sout << "*** TPZYCSandlerDimaggio::ComputePlasticPotential ***";
207  sout << "\nDivision by F=" << TPZExtractVal::val(L) << " at f2 - ellipsoidal hardening/softening cap";
208  LOGPZ_WARN(logger, sout.str().c_str());
209  }
210  }
211 #endif
212 
213  T temp = J2 / (FL * FL);
214  if (TPZExtractVal::val(I1) > TPZExtractVal::val(L)) {
215  res[1] = temp - T(1.);
216  } else {
217  T temp2((L - I1) / (FL * T(fR)));
218  temp2 *= temp2;
219  res[1] = temp2 + temp - T(1.);
220  }
221  }
222 }
223 
224 template <class T>
225 inline void TPZYCSandlerDimaggioL2::N(const TPZTensor<T> & sigma, const T & A, TPZVec<TPZTensor<T> > & Ndir, int checkForcedYield) const {
226 
227  // the termoforce A in this case is assumed to be the
228  // plastic volumetric strain itself. In fact it is not,
229  // but the resultant derivatives are correct for practical purposes.
230 
231  //The following line evaluates L, the value of the first
232  // invariant of stresses at the intersection of the
233  // shear and hardening cap yield criteria / plastic potential.
234  // It is first evaluated as REAL type to avoid unnecessary
235  // derivatives evaluation.
236 
237 
238 #ifdef LOG4CXX_PLASTICITY
239  {
240  LoggerPtr logger(Logger::getLogger("plasticity.SandlerDimaggioL"));
241  std::stringstream sout;
242  sout << ">>> TPZYCSandlerDimaggio::N *** - Plastification direction - associative";
243  LOGPZ_INFO(logger, sout.str().c_str());
244  }
245 #endif
246 
247  // REAL ResTol = 1.e-6;
248 
249  REAL L_REAL;
250  // REAL X_REAL;
251  // ComputeX((REAL)TPZExtractVal::val(A), X_REAL);
252  // LInitialGuess(X_REAL, L_REAL);
253  // SolveL(X_REAL, L_REAL, ResTol);
254 
255  L_REAL = TPZExtractVal::val(A);
256  T I1 = sigma.I1();
257  T J2 = sigma.J2();
258  T SQRTJ2;
259  if (TPZExtractVal::val(J2) > 1.e-12) {
260  SQRTJ2 = sqrt(J2);
261  } else {
262  SQRTJ2 = sqrt(T(1.e-6) + J2);
263  }
264 
265  if (fIsonCap) {
266  Ndir[0].XX() = 1.;
267  Ndir[0].YY() = 1.;
268  Ndir[0].ZZ() = 1.;
269  // Ndir[0].YZ() = sigma.YZ() * Temp2;
270  // Ndir[0].XZ() = sigma.XZ() * Temp2;
271  // Ndir[0].XY() = sigma.XY() * Temp2;
272  Ndir[0].YZ() = 0.;
273  Ndir[0].XZ() = 0.;
274  Ndir[0].XY() = 0.;
275  } else {
276  //f1 - Modified Drucker-Prager as shear Yield Criterium / Plastic Potential
277  REAL fz = FZero();
278  T Temp1(0.);
279  if (TPZExtractVal::val(I1) < fz) {
280  Temp1 = I1 * T(fB);
281  Temp1 = exp(Temp1) * T(fB * fC);
282 
283  if ((REAL) TPZExtractVal::val(SQRTJ2) < 1.e-6) // just for robustness. f1 shouldn't be reached when J2 = 0.
284  {
285 #ifdef LOG4CXX_PLASTICITY
286  {
287  LoggerPtr logger(Logger::getLogger("plasticity.SandlerDimaggio"));
288  std::stringstream sout;
289  sout << "*** TPZYCSandlerDimaggio::N *** - SQRT(J2) = " << TPZExtractVal::val(SQRTJ2) << " < 1.e-6 causes error in 0-th yield function. Imposing J2 = 1.e-6 instead";
290  LOGPZ_WARN(logger, sout.str().c_str());
291  }
292 #endif
293  SQRTJ2 = T(1.e-6) + SQRTJ2;
294  }
295  }
296  Temp1 = Temp1 - I1 / SQRTJ2 / T(6.);
297  T Temp2 = T(1.) / SQRTJ2;
298  T Temp3 = Temp2 / T(2.);
299 
300  Ndir[0].XX() = Temp1 + sigma.XX() * Temp3;
301  Ndir[0].YY() = Temp1 + sigma.YY() * Temp3;
302  Ndir[0].ZZ() = Temp1 + sigma.ZZ() * Temp3;
303  // Ndir[0].YZ() = sigma.YZ() * Temp2;
304  // Ndir[0].XZ() = sigma.XZ() * Temp2;
305  // Ndir[0].XY() = sigma.XY() * Temp2;
306  Ndir[0].YZ() = sigma.YZ() * Temp3;
307  Ndir[0].XZ() = sigma.XZ() * Temp3;
308  Ndir[0].XY() = sigma.XY() * Temp3;
309 #ifdef LOG4CXX
310  if (loggerSML->isDebugEnabled()) {
311  std::stringstream sout;
312  Ndir[0].Print(sout);
313  LOGPZ_DEBUG(loggerSML, sout.str())
314  }
315 #endif
316  }
317 
318  if (fIsonCap) {//f2 - ellipsoidal hardening/softening cap
319  TPZTensor<T> Deviatoric;
320  sigma.S(Deviatoric);
321  Ndir[1] = Deviatoric;
322  } else {
323  T FL;
324  T L = A;
325  // T X;
326  // T L(L_REAL * 1.- ResTol); // guaranteeing that the function will be evaluated
327  // ComputeX(A, X);
328  // SolveL(X, L, ResTol); // evaluating the derivatives of L
329 
330  ComputeF(L, FL);
331  // the radius of the ellips needs to be positive
332  // this should be taken care of by the computation of L which is limited by LMax()
333  if (TPZExtractVal::val(FL) <= 0.) {
334  DebugStop();
335  }
336  if (TPZExtractVal::val(I1) < TPZExtractVal::val(L)) {
337 
338  T FL2 = FL * FL;
339  // T FL3 = FL2;// / T(2.);
340 
341  T Temp = (I1 - L) / T(fR * fR) - I1 / T(6.);
342  Temp = Temp / FL2 * T(2.);
343 
344 #ifdef LOG4CXX_PLASTICITY
345  {
346  LoggerPtr logger(Logger::getLogger("plasticity.SandlerDimaggio"));
347  std::stringstream sout;
348  sout << "*** TPZYCSandlerDimaggio::N *** X = " << X
349  << "\n L = " << L << " L_REAL = " << L_REAL
350  << "\n FL = " << FL
351  << "\n Temp = " << Temp
352  << "\n 3 Temp + I1/FL2 " << T(3.) * Temp + I1 / FL2;
353 
354  LOGPZ_DEBUG(logger, sout.str().c_str());
355  }
356 #endif
357 
358  Ndir[1].XX() = Temp + sigma.XX() / FL2;
359  Ndir[1].YY() = Temp + sigma.YY() / FL2;
360  Ndir[1].ZZ() = Temp + sigma.ZZ() / FL2;
361  Ndir[1].YZ() = sigma.YZ() / FL2;
362  Ndir[1].XZ() = sigma.XZ() / FL2;
363  Ndir[1].XY() = sigma.XY() / FL2;
364  } else {
365  TPZTensor<T> Deviatoric;
366  sigma.S(Deviatoric);
367  Deviatoric *= T(1.) / (FL * FL);
368  Ndir[1] = Deviatoric;
369 
370  }
371  }
372 
373 #ifdef LOG4CXX
374  {
375  LoggerPtr logger(Logger::getLogger("pz.plasticity.SandlerDimaggio.main"));
376  if (0 && logger->isDebugEnabled()) {
377  std::stringstream sout;
378  sout << "<< TPZYCSandlerDimaggioL2::N *** \n sigma = \n" << sigma
379  << "\nI1 = " << I1
380  << "\nJ2 = " << J2
381  << "\nSQRTJ2 = " << SQRTJ2
382  << "\nNdir = \n" << Ndir;
383  LOGPZ_DEBUG(logger, sout.str().c_str());
384  }
385  }
386 #endif
387 }
388 
389 template <class T>
390 inline void TPZYCSandlerDimaggioL2::H(const TPZTensor<T> & sigma, const T & A, TPZVec<T> & h, int checkForcedYield) const {
391 
392  // the termoforce A in this case is assumed to be the
393  // plastic volumetric strain itself. In fact it is not,
394  // but the resultant derivatives are correct for practical purposes.
395 
396  //The following line evaluates L, the value of the first
397  // invariant of stresses at the intersection of the
398  // shear and hardening cap yield criteria / plastic potential.
399  // It is first evaluated as REAL type to avoid unnecessary
400  // derivatives evaluation.
401 
402 #ifdef LOG4CXX_PLASTICITY
403  {
404  LoggerPtr logger(Logger::getLogger("plasticity.SandlerDimaggio"));
405  std::stringstream sout;
406  sout << ">>> TPZYCSandlerDimaggio::H *** - Hardening modulus";
407  LOGPZ_INFO(logger, sout.str().c_str());
408  }
409 #endif
410 
411  // REAL L_REAL = TPZExtractVal::val(A);
412  // REAL X_REAL;
413  // ComputeX((REAL)TPZExtractVal::val(A), X_REAL);
414  // LInitialGuess(X_REAL, L_REAL);
415  // SolveL(X_REAL, L_REAL);
416 
417  if (fIsonCap) {
418  h[0] = 0.;
419  h[1] = 0.;
420  } else {
421  T I1 = sigma.I1();
422 
423  {//f1 - Modified Drucker-Prager as shear Yield Criterium / Plastic Potential
424 
425  h[0] = exp(I1 * T(fB)) * T(3. * fB * fC);
426  // h > 0 because plastic deformation is dilatant
427  }
428 
429  {//f2 - ellipsoidal hardening/softening cap
430  if (TPZExtractVal::val(I1) < TPZExtractVal::val(A)) {
431  T FL;
432  T L = A;
433  // T X, L(L_REAL);
434  // ComputeX(A, X);
435  // SolveL(X, L); // evaluating the derivatives of L
436  ComputeF(L, FL);
437  T FL2 = FL * FL;
438  // DebugStop();
439  h[1] = (I1 - L) / FL2 * T(6. / fR / fR);
440  // h <=0 because plastic deformation is compactant
441  } else {
442  h[1] = T(0.);
443  }
444  }
445  }
446 }
447 
448 
449 
451 
453 
464 inline void TPZYCSandlerDimaggioL2::InitialGuess(const TPZElasticResponse &ER, REAL Lextern, TPZTensor<REAL> &sigtrial, REAL &Lproj,
465  TPZVec<REAL> &delgamma, TPZTensor<REAL> &sigproj) {
466  TPZManVector<REAL, 2> yield(2, 0.);
467  REAL L = Lextern;
468  TPZTensor<REAL> S;
469  sigtrial.S(S);
470  REAL J2 = S.J2();
471  REAL sqJ2 = sqrt(fabs(J2));
472  REAL I1 = sigtrial.I1();
473  TPZManVector<REAL, 2> sigtrialIJ(2), sigtrialIJF1(2), sigtrialIJF2(2), sigtrialIJkeep;
474  sigtrialIJ[0] = I1;
475  sigtrialIJ[1] = sqJ2;
476  sigtrialIJkeep = sigtrialIJ;
477  Compute(sigtrial, L, yield, 0);
478  int surfaceprojected = -1;
479 #ifdef LOG4CXX
480  if (loggerSML->isDebugEnabled()) {
481  std::stringstream sout;
482  sout << "Value of fIsonCap " << fIsonCap;
483  if (fIsonCap) {
484  sout << "\nI should stop";
485  }
486  LOGPZ_DEBUG(loggerSML, sout.str())
487  }
488 #endif
489  fIsonCap = false;
490 
491  if (yield[1] >= 0. && I1 < Lextern) {
492  surfaceprojected = 1;
493  NewtonF2L(ER, L, sigtrialIJ);
494 
495  sigtrial.Adjust(sigtrialIJ, sigproj);
496  Lproj = L;
497 
498  } else if (yield[0] >= 0. && I1 >= Lextern) {
499  surfaceprojected = 0;
500  NewtonF1(ER, L, sigtrialIJ);
501  sigtrial.Adjust(sigtrialIJ, sigproj);
502 
503  REAL LMAX = LMax();
504 
505  if (sigtrialIJ[0] <= LMAX) {
506  TPZManVector<REAL, 2> yieldCheck(2, 0.);
507  Compute(sigproj, L, yieldCheck, 0);
508  if (fabs(yieldCheck[0]) > 1.e-8) {
509  DebugStop();
510  }
511 
512  if (yieldCheck[1] > 0.) {
513  L = Lextern;
514  sigtrialIJ = sigtrialIJkeep;
515  ProjectBorder(ER, L, sigtrialIJ);
516  sigtrial.Adjust(sigtrialIJ, sigproj);
517  surfaceprojected = 2;
518  }
519  }
520 
521 
522  if (sigtrialIJ[0] > LMAX) {
523  fIsonCap = true;
524  sigtrialIJ[0] = LMax();
525  REAL F;
526  ComputeF(sigtrialIJ[0], F);
527  if (sqJ2 > F) {
528  sigtrialIJ[1] = F;
529  } else {
530  sigtrialIJ[1] = sqJ2;
531  }
532  sigtrial.Adjust(sigtrialIJ, sigproj);
533  L = LMax();
534  Lproj = Lextern;
535 #ifdef LOG4CXX
536  {
537  std::stringstream sout;
538  sout << "Projecting on the cap after projection on F2 : sigtrialIJ " << sigtrialIJ << " L " << L << " Lproj " << Lproj;
539  LOGPZ_DEBUG(loggerSML, sout.str())
540  }
541 #endif
542  } else {
543  Lproj = L;
544  }
545  }
546  // REAL LF1 = L;
547  // REAL LF2 = L;
548  // if(I1 < Lextern)
549  // {
550  // fIsonCap = false;
551  // // we can only project on the surface F2
552  // if (yield[1] > 0.) {
553  // // project the point on surface F2
554  // sigtrialIJF2 = sigtrialIJ;
555  // TPZTensor<REAL> sigtrialF2;
556  // NewtonF2L(ER, LF2, sigtrialIJF2);
557  // }
558  // sigtrial.Adjust(sigtrialIJF2, sigproj);
560  // sigtrialIJ = sigtrialIJF2;
561  // L = LF2;
562  // }
563  // else {
564  // // the point can project on F1 or F2 or can be projected on the cap
565  // if (yield[0] > 0.) {
566  // sigtrialIJF1 = sigtrialIJ;
567  // NewtonF1(ER, LF1, sigtrialIJF1);
568  //
569  // // verify if the projected point plastifies F2
570  // if (sigtrialIJF1[0] < LF1) {
571  // // the projected point is left of L
572  // // this means F2 must be active
573  // // the increase in L must be at the intersection of both surfaces this intersection point is L itself!
574  // // 3 K Depsp/DL (L-Lextern) = (I1(sigtrial)-L)
575  // TPZManVector<REAL> sigtrialIntersectIJ(sigtrialIJ);
576  // REAL LFIntersect = Lextern;
577  // ComputeLatIntersectionLeft(ER, LFIntersect, sigtrialIJ);
578  //
579  // }
580  // else {
581  // // verify if the projected point is within F2
582  // TPZManVector<REAL,2> yieldProj(2);
583  // TPZTensor<REAL> sigtrialF1;
584  // sigtrial.Adjust(sigtrialIJF1,sigtrialF1);
585  // Compute(sigtrialF1,LF1,yieldProj,0);
586  // if (yieldProj[1] > 0.) {
587  // // the projection on F1 is within F2
588  // // the increase in L is such that the projection point is at the intersection of F1 and F2 to the right
589  // // unlikely case!
590  // // 3 K Depsp/DL (L-Lextern) = (I1(sigtrial) - I1intersect(L) )
591  // TPZManVector<REAL> sigtrialIntersectIJ(sigtrialIJ);
592  // REAL LFIntersect = Lextern;
593  // ComputeLatIntersectionRight(ER, LFIntersect, sigtrialIJ);
594  // sigtrial.Adjust(sigtrialIJ, sigproj);
595  // L = LFIntersect;
596  // }
597  // else {
598  // L = LF1;
599  // sigtrialIJ = sigtrialIJF1;
600  // sigtrial.Adjust(sigtrialIJF1, sigproj);
601  // }
602  // }
603  // }
604  // else if(yield[1] > 0.)
605  // {
606  // sigtrialIJF2 = sigtrialIJ;
607  // LF2 = Lextern;
608  // NewtonF2(ER, LF2, sigtrialIJF2);
609  // TPZTensor<REAL> sigtrialF2;
610  // sigtrial.Adjust(sigtrialIJF2, sigtrialF2);
611  // TPZManVector<REAL,2> yieldproj(2,0.);
612  // Compute(sigtrialF2,LF2,yieldproj,0);
613  // if (yieldproj[0] > 0.) {
614  // // Don't know what to do??
615  // DebugStop();
616  // }
617  // else {
618  // L = LF2;
619  // sigtrialIJ = sigtrialIJF2;
620  // }
621  // }
622  // if (LF1 > LMax()) {
623  // fIsonCap = true;
624  // }
625  //
626  // }
627 
628  TPZManVector<TPZTensor<REAL>, 2> Ndir(2);
629  this->N(sigproj, Lproj, Ndir, 1);
630  TPZTensor<REAL> sigPlast(sigtrial), epsPlast;
631  sigPlast.Add(sigproj, -1.);
632  TPZManVector<REAL, 2> sigPlastIJ(2);
633  sigPlastIJ[0] = sigPlast.I1();
634  sigPlastIJ[1] = sqrt(sigPlast.J2());
635  ER.ComputeStrain(sigPlast, epsPlast);
636  TPZManVector<REAL, 2> epsplastIJ(2);
637  epsplastIJ[0] = epsPlast.I1();
638  epsplastIJ[1] = sqrt(epsPlast.J2());
639  REAL I1err = sigPlastIJ[0] - epsplastIJ[0]*3. * ER.K();
640  REAL J2err = sigPlastIJ[1] - epsplastIJ[1]*2. * ER.G();
641  if (fabs(I1err) > 1.e-10 || fabs(J2err) > 1.e-10) {
642  DebugStop();
643  }
644  if (fIsonCap) {
645  REAL lmax = LMax();
646  REAL F;
647  ComputeF(lmax, F);
648  REAL i1Ndir = Ndir[0].I1();
649  REAL sqj2Ndir = sqrt(Ndir[1].J2());
650  REAL i1epsplast = epsPlast.I1();
651  REAL sqj2epsplast = sqrt(epsPlast.J2());
652  if (I1 > lmax) {
653  delgamma[0] = i1epsplast / i1Ndir;
654  } else {
655  // there would be no reason to fall on the cap
656  DebugStop();
657  }
658  if (sqJ2 > F) {
659  delgamma[1] = sqj2epsplast / sqj2Ndir;
660  } else {
661  delgamma[1] = 0.;
662  }
663  } else {
664  if (surfaceprojected != 0 && surfaceprojected != 1 && surfaceprojected != 2) {
665  DebugStop();
666  }
667  if (surfaceprojected == 0 || surfaceprojected == 1) {
668  REAL i1Ndir = Ndir[surfaceprojected].I1();
669  REAL sqj2Ndir = sqrt(Ndir[surfaceprojected].J2());
670  REAL theta1 = atan2(sqj2Ndir, i1Ndir);
671  REAL theta2 = atan2(epsplastIJ[1], epsplastIJ[0]);
672  REAL difftheta = theta1 - theta2;
673  REAL sigplnorm = sigPlast.Norm();
674  if (fabs(difftheta) > 1.e-4 && sigplnorm > 1.e-10) {
675  std::cout << "difftheta " << difftheta << " theta1 " << theta1 << " theta2 " << theta2 << std::endl;
676  }
677  REAL theta = 0.;
678 
679  if (surfaceprojected == 1) {
680  REAL FL;
681  ComputeF(Lproj, FL);
682  REAL cst = i1Ndir * (FL * fR) / 6.;
683  REAL sst = sqj2Ndir*FL;
684  REAL check = 1. - cst * cst - sst*sst;
685  if (fabs(check) > 1.e-6) {
686  std::cout << "check = " << check << " cst " << cst << " sst " << sst << std::endl;
687  L = Lextern;
688  sigtrialIJ = sigtrialIJkeep;
689  NewtonF2L(ER, L, sigtrialIJ);
690  }
691  theta = atan2(sst, cst);
692 
693  REAL xdist = sigtrialIJ[0] - Lproj;
694  REAL ydist = sigtrialIJ[1];
695  REAL theta3 = atan2(ydist, xdist / fR);
696 
697  REAL thetadiff = theta - theta3;
698  if (fabs(thetadiff) > 1.e-6) {
699  std::cout << " thetadiff " << thetadiff << " theta " << theta << " theta3 " << theta3 << std::endl;
700  }
701  // verificar pelo angulo
702  REAL verify = FuncTheta2L(ER, theta, Lproj, sigtrialIJkeep);
703  if (fabs(verify) > 1.e-9) {
704  std::cout << "Validity of functheta " << verify << std::endl;
705  }
706  }
707  Lproj = L;
708  REAL scale = epsPlast.Norm() / Ndir[surfaceprojected].Norm();
709  for (int i = 0; i < 6; i++) {
710  REAL diff = fabs(scale * Ndir[surfaceprojected][i] - epsPlast[i]);
711  if (diff > 8.e-5) { //Nathan Trocou!!!!
712  std::cout << "Projection has a large error diff = " << diff << " scale = " << scale << std::endl;
713  }
714  }
715  delgamma[0] = 0.;
716  delgamma[1] = 0.;
717  delgamma[surfaceprojected] = scale;
718  } else {
719  STATE I1NDir0 = Ndir[0].I1();
720  STATE I1NDir1 = Ndir[1].I1();
721  if (fabs(I1NDir1) > 1.e-6) {
722  DebugStop();
723  }
724  delgamma[0] = epsplastIJ[0] / I1NDir0;
725  STATE sqj2 = sqrt(Ndir[0].J2());
726  STATE resj2 = epsplastIJ[1] - delgamma[0] * sqj2;
727  STATE sqj2Ndir1 = sqrt(Ndir[1].J2());
728  delgamma[1] = resj2 / sqj2Ndir1;
729  TPZTensor<STATE> delepsp(Ndir[0]);
730  delepsp *= delgamma[0];
731  delepsp.Add(Ndir[1], delgamma[1]);
732  for (int i = 0; i < 6; i++) {
733  STATE diff = delepsp[i] - epsPlast[i];
734  if (fabs(diff) > 1.e-8) {
735  DebugStop();
736  }
737  }
738  }
739  }
740  Compute(sigproj, Lproj, yield, 0);
741 #ifdef LOG4CXX
742  if (loggerSM->isDebugEnabled()) {
743  std::stringstream sout;
744  sout << "After projecting the point yield = " << yield;
745  sout << "\ndelgamma = " << delgamma;
746  LOGPZ_DEBUG(loggerSM, sout.str())
747  }
748 #endif
749  if (yield[0] > 1.e-8 && fIsonCap) {
750  DebugStop();
751  }
752  if (yield[1] > 1.e-6) {
753  DebugStop();
754  }
755 }
756 
758 
759 inline void TPZYCSandlerDimaggioL2::ProjectBorder(const TPZElasticResponse &ER, REAL &L, TPZVec<STATE> &sigtrialIJ) {
760  REAL residueL = 0.;
761  REAL K = ER.K();
762  STATE depspdl;
763  REAL resultL = L;
764  DEpspDL(resultL, depspdl);
765  residueL = 3. * K * depspdl * (resultL - L)-(sigtrialIJ[0] - resultL);
766  while (fabs(residueL) > 1.e-10) {
767  STATE d2epspdl2;
768  D2EpspDL2(resultL, d2epspdl2);
769  STATE dres = 3. * K * depspdl + 3. * K * (resultL - L) * d2epspdl2 + 1.;
770  resultL -= residueL / dres;
771  DEpspDL(resultL, depspdl);
772  residueL = 3. * K * depspdl * (resultL - L)-(sigtrialIJ[0] - resultL);
773  }
774  STATE F;
775  ComputeF(resultL, F);
776  sigtrialIJ[0] = resultL;
777  sigtrialIJ[1] = F;
778  L = resultL;
779 }
780 
781 
782 
783 
784 #endif //TPZYCSANDLERDIMAGGIO_H
TPZYCSandlerDimaggioL & operator=(const TPZYCSandlerDimaggioL &source)
TPZFlopCounter atan2(const TPZFlopCounter &val1, const TPZFlopCounter &val2)
Returns the arc tangent in radians and increments the counter of the Arc Tangent. ATAN2 returns the ...
Definition: pzreal.h:544
virtual int GetNYield() const override
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ fabs
Definition: tfadfunc.h:140
void Add(const TPZTensor< T1 > &tensor, const T2 &constant)
Definition: TPZTensor.h:757
T Norm() const
Definition: TPZTensor.h:854
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
Implements a vector class which allows to use external storage provided by the user. Utility.
Definition: pzquad.h:16
void ComputeX(const T &A, T &X) const
T I1() const
Definition: TPZTensor.h:903
void DEpspDL(const T &L, T &depspdL) const
std::underlying_type< Enumeration >::type as_integer(const Enumeration value)
Definition: pzreal.h:37
T & YY() const
Definition: TPZTensor.h:578
TPZYCSandlerDimaggioL2 & operator=(const TPZYCSandlerDimaggioL2 &source)
clarg::argBool h("-h", "help message", false)
This class implements a simple vector storage scheme for a templated class T. Utility.
Definition: pzgeopoint.h:19
#define LOGPZ_WARN(A, B)
Define log for warnings.
Definition: pzlog.h:91
int ClassId() const override
Define the class id associated with the class.
void Print(std::ostream &out) const override
void ComputeF(const T &L, T &F) const
void D2EpspDL2(const T &L, T &d2epspdL2) const
const char * Name() const
void H(const TPZTensor< T > &sigma, const T &A, TPZVec< T > &h, int checkForcedYield) const
void N(const TPZTensor< T > &sigma, const T &A, TPZVec< TPZTensor< T > > &Ndir, int checkForcedYield) const
T & YZ() const
Definition: TPZTensor.h:582
#define LOGPZ_INFO(A, B)
Define log for informations.
Definition: pzlog.h:89
void ProjectBorder(const TPZElasticResponse &ER, REAL &L, TPZVec< STATE > &sigtrialIJ)
project the point on the intersection of the F1 and F2 surface
void Compute(const TPZTensor< T > &sigma, const T &A, TPZVec< T > &res, int checkForcedYield) const
Calculo do criterio de plastificacao.
void ComputeStrain(const TPZTensor< T > &sigma, TPZTensor< T > &epsilon) const
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
Definition: tfadfunc.h:120
string res
Definition: test.py:151
T J2() const
Definition: TPZTensor.h:927
void Adjust(TPZVec< T > &sigIJ, TPZTensor< T > &result) const
adjust the tensor to the given values of I1 and sqj2
Definition: TPZTensor.h:490
void Print(std::ostream &out) const override
static REAL val(const int number)
Definition: pzextractval.h:21
void NewtonF2L(const TPZElasticResponse &ER, REAL &L, TPZVec< REAL > &sigtrialIJ)
static void McCormicRanchSand(TPZYCSandlerDimaggio &material)
#define FL(A)
Function for dynamic cast of the material based on map A (second data)
T & XX() const
Definition: TPZTensor.h:566
T & XY() const
Definition: TPZTensor.h:570
T & ZZ() const
Definition: TPZTensor.h:586
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ exp
Definition: tfadfunc.h:125
void NewtonF1(const TPZElasticResponse &ER, REAL &L, TPZVec< REAL > &sigtrialIJ)
Projeto o ponto sobre a superficie F1, atualiza o L.
T & XZ() const
Definition: TPZTensor.h:574
Contains the implementation of the CheckConvergence function.
void SolveL(const T &X, T &L, REAL relTol=1.e-10) const
REAL FuncTheta2L(const TPZElasticResponse &ER, REAL theta, REAL L, TPZVec< REAL > &sigtrialIJ) const
void S(TPZTensor< T > &s) const
Definition: TPZTensor.h:894
TPZYCSandlerDimaggioL2(const TPZYCSandlerDimaggioL2 &source)
void InitialGuess(const TPZElasticResponse &ER, REAL L, TPZTensor< REAL > &sigtrial, REAL &epspproj, TPZVec< REAL > &delgamma, TPZTensor< REAL > &sigproj)