@@ -50,7 +50,7 @@ void Simulation::plasticity(unsigned int p, unsigned int & plastic_count, TM & F
5050 // If hardening law:
5151 // q_yield = f(q_max, hardening variable) ....
5252
53- T delta_gamma = hencky_deviatoric_norm - q_yield / e_mu_prefac; // this is eps_pl_dev_instant
53+ T delta_gamma = hencky_deviatoric_norm - q_yield / e_mu_prefac; // this is eps_pl_dev_inst
5454
5555 if (delta_gamma > 0 ){ // project to yield surface
5656 plastic_count++;
@@ -298,7 +298,12 @@ void Simulation::plasticity(unsigned int p, unsigned int & plastic_count, TM & F
298298 T delta_gamma;
299299
300300 if (perzyna_exp == 1 ){
301- delta_gamma = (q_trial-q_yield) / (f_mu_prefac + q_yield*perzyna_visc/dt);
301+ if (use_duvaut_lions_formulation){
302+ delta_gamma = (q_trial-q_yield) / (f_mu_prefac*(1 +perzyna_visc/dt));
303+ }
304+ else {
305+ delta_gamma = (q_trial-q_yield) / (f_mu_prefac + q_yield*perzyna_visc/dt);
306+ }
302307 if (delta_gamma < 0 ){
303308 debug (" DPVisc: FATAL negative delta_gamma = " , delta_gamma);
304309 exit = 1 ;
@@ -315,16 +320,30 @@ void Simulation::plasticity(unsigned int p, unsigned int & plastic_count, TM & F
315320 exit = 1 ;
316321 }
317322
318- T tm = perzyna_visc * delta_gamma + dt;
319- T tmp = dt / tm;
320- T tmp1 = std::pow (tmp, perzyna_exp);
323+ T residual;
324+ T residual_diff;
325+ if (use_duvaut_lions_formulation){
326+
327+ residual = q_trial - q_yield - f_mu_prefac * ( std::pow (perzyna_visc/dt*delta_gamma, perzyna_exp) + delta_gamma );
328+ if (std::abs (residual) < 1e-2 ) {
329+ break ;
330+ }
331+ residual_diff = -f_mu_prefac * ( std::pow (perzyna_visc/dt, perzyna_exp) * perzyna_exp * std::pow (delta_gamma, perzyna_exp-1 ) + 1 );
321332
322- T residual = (q_trial - f_mu_prefac * delta_gamma) * tmp1 - q_yield;
323- if (std::abs (residual) < 1e-2 ) {
324- break ;
325333 }
334+ else {
326335
327- T residual_diff = -f_mu_prefac * tmp1 + (q_trial - f_mu_prefac * delta_gamma) * perzyna_exp * std::pow (tmp, perzyna_exp - 1 ) * (-perzyna_visc * dt) / (tm * tm);
336+ T tm = perzyna_visc * delta_gamma + dt;
337+ T tmp = dt / tm;
338+ T tmp1 = std::pow (tmp, perzyna_exp);
339+
340+ residual = (q_trial - f_mu_prefac * delta_gamma) * tmp1 - q_yield;
341+ if (std::abs (residual) < 1e-2 ) {
342+ break ;
343+ }
344+ residual_diff = -f_mu_prefac * tmp1 + (q_trial - f_mu_prefac * delta_gamma) * perzyna_exp * std::pow (tmp, perzyna_exp - 1 ) * (-perzyna_visc * dt) / (tm * tm);
345+
346+ }
328347
329348 if (std::abs (residual_diff) < 1e-14 ){ // otherwise division by zero
330349 debug (" DPVisc: FATAL residual_diff too small in abs value = " , residual_diff);
@@ -510,10 +529,9 @@ void Simulation::plasticity(unsigned int p, unsigned int & plastic_count, TM & F
510529 T p_trial = p_stress;
511530 T q_trial = q_stress;
512531
513- if (plastic_model == PlasticModel::MCCVisc){
514- if (use_mibf)
515- particles.muI [p] = M;
516- }
532+ if (use_mibf)
533+ particles.muI [p] = M;
534+
517535
518536 bool perform_rma;
519537 T p_c;
@@ -543,98 +561,115 @@ void Simulation::plasticity(unsigned int p, unsigned int & plastic_count, TM & F
543561 exit = 1 ;
544562 }
545563
546-
547564 if (perform_rma) { // returns true if it performs a return mapping
548565 plastic_count++;
549566
550- T ep = p_stress / (K*dim);
551- T eps_pl_vol_inst = hencky_trace + dim * ep;
552- particles.eps_pl_vol [p] += eps_pl_vol_inst;
567+ T b = 1 ; // must be equal to one unless using duvaut lion formulation
553568
554- T delta_gamma;
555569 // //////////////////////////////////////////////////////////////
556570 if (plastic_model == PlasticModel::MCCVisc){
557-
558- T q_yield = q_stress;
559-
560- if (perzyna_exp == 1 ){
561- delta_gamma = (q_trial-q_yield) / (f_mu_prefac + q_yield*perzyna_visc/dt);
562- if (delta_gamma < 0 ){
563- if (delta_gamma > -1e-14 ){
564- delta_gamma = 0 ;
565- }
566- else {
567- debug (" MCCVisc: FATAL negative delta_gamma = " , delta_gamma);
568- exit = 1 ;
569- }
571+ if (use_duvaut_lions_formulation){
572+ b = 1.0 / (1.0 + perzyna_visc / dt); // b defined such that "stress = (1-b) * strain_trial + b * stress_yield"
573+ if (perzyna_exp != 1 ){
574+ debug (" MCCVisc: FATAL viscous exponent must be 1 when use_duvaut_lions_formulation = true" );
575+ exit = 1 ;
570576 }
571577 }
572- else { // persyna_exp is not one
578+ else { // perzyna
579+ T delta_gamma;
580+ T q_yield = q_stress;
581+
582+ if (perzyna_exp == 1 ){
583+ delta_gamma = (q_trial-q_yield) / (f_mu_prefac + q_yield*perzyna_visc/dt);
584+ if (delta_gamma < 0 ){
585+ if (delta_gamma > -1e-14 ){
586+ delta_gamma = 0 ;
587+ }
588+ else {
589+ debug (" MCCVisc: FATAL negative delta_gamma = " , delta_gamma);
590+ exit = 1 ;
591+ }
592+ }
593+ }
594+ else { // perzyna_exp is not one
573595
574- delta_gamma = 0.01 * (q_trial - q_yield) / f_mu_prefac; // initial guess
596+ delta_gamma = 0.01 * (q_trial - q_yield) / f_mu_prefac; // initial guess
575597
576- int max_iter = 60 ;
577- for (int iter = 0 ; iter < max_iter; iter++) {
578- if (iter == max_iter - 1 ){ // did not break loop
579- debug (" MCCVisc: FATAL did not exit loop at iter = " , iter);
580- exit = 1 ;
581- }
598+ int max_iter = 60 ;
599+ for (int iter = 0 ; iter < max_iter; iter++) {
600+ if (iter == max_iter - 1 ){ // did not break loop
601+ debug (" MCCVisc: FATAL did not exit loop at iter = " , iter);
602+ exit = 1 ;
603+ }
582604
583- T tm = perzyna_visc * delta_gamma + dt;
584- T tmp = dt / tm;
585- T tmp1 = std::pow (tmp, perzyna_exp);
605+ T tm = perzyna_visc * delta_gamma + dt;
606+ T tmp = dt / tm;
607+ T tmp1 = std::pow (tmp, perzyna_exp);
586608
587- T residual = (q_trial - f_mu_prefac * delta_gamma) * tmp1 - q_yield;
588- if (std::abs (residual) < 1e-2 ) {
589- break ;
590- }
609+ T residual = (q_trial - f_mu_prefac * delta_gamma) * tmp1 - q_yield;
610+ if (std::abs (residual) < 1e-2 ) {
611+ break ;
612+ }
591613
592- T residual_diff = -f_mu_prefac * tmp1 + (q_trial - f_mu_prefac * delta_gamma) * perzyna_exp * std::pow (tmp, perzyna_exp - 1 ) * (-perzyna_visc * dt) / (tm * tm);
614+ T residual_diff = -f_mu_prefac * tmp1 + (q_trial - f_mu_prefac * delta_gamma) * perzyna_exp * std::pow (tmp, perzyna_exp - 1 ) * (-perzyna_visc * dt) / (tm * tm);
593615
594- if (std::abs (residual_diff) < 1e-14 ){ // otherwise division by zero
595- debug (" MCCVisc: FATAL residual_diff too small in abs value = " , residual_diff);
596- exit = 1 ;
597- }
616+ if (std::abs (residual_diff) < 1e-14 ){ // otherwise division by zero
617+ debug (" MCCVisc: FATAL residual_diff too small in abs value = " , residual_diff);
618+ exit = 1 ;
619+ }
598620
599- delta_gamma -= residual / residual_diff;
621+ delta_gamma -= residual / residual_diff;
600622
601- if (delta_gamma < 0 ) // not possible and can also lead to division by zero
602- delta_gamma = 1e-10 ;
623+ if (delta_gamma < 0 ) // not possible and can also lead to division by zero
624+ delta_gamma = 1e-10 ;
603625
604- } // end N-R iterations
626+ } // end N-R iterations
605627
606- } // end if perzyna_exp == 1
628+ } // end if perzyna_exp == 1
607629
608- q_stress = std::max (q_yield, q_trial - f_mu_prefac * delta_gamma); // delta_gamma = dt * gamma_dot_S
630+ q_stress = std::max (q_yield, q_trial - f_mu_prefac * delta_gamma); // delta_gamma = dt * gamma_dot_S
609631
610- if (use_mibf){
611- if (hardening_law == HardeningLaw::ExpoImpl){
612- p_c = std::max (T (0 ), p0 * std::exp (-xi*particles.eps_pl_vol [p]));
613- }
614- else if (hardening_law == HardeningLaw::SinhImpl){
615- p_c = std::max (T (0 ), K * std::sinh (-xi*particles.eps_pl_vol [p] + std::asinh (p0/K)));
616- }
632+ } // end if use_duvaut_lions_formulation
633+
634+ } // end if MCCVisc
635+ // //////////////////////////////////////////////////////////////
636+
637+ T eps_pl_vol_inst = - b * (p_trial - p_stress) / K;
638+ T eps_pl_dev_inst = b * (q_trial - q_stress) / e_mu_prefac;
639+
640+ particles.eps_pl_vol [p] += eps_pl_vol_inst;
641+ particles.eps_pl_dev [p] += eps_pl_dev_inst;
617642
618- if ( (p_stress < -beta * p_c + stress_tolerance) || (p_stress > p_c - stress_tolerance) ){
619- particles.muI [p] = M;
643+ particles.delta_gamma [p] = d_prefac * eps_pl_dev_inst / dt;
644+
645+ T h_vol = - p_trial / K - eps_pl_vol_inst;
646+ T h_dev = q_trial / e_mu_prefac - eps_pl_dev_inst;
647+ hencky = h_dev * hencky_deviatoric + (h_vol/dim) * TV::Ones ();
648+ particles.F [p] = svd.matrixU () * hencky.array ().exp ().matrix ().asDiagonal () * svd.matrixV ().transpose ();
649+
650+ if (use_mibf){
651+ if (hardening_law == HardeningLaw::ExpoImpl){
652+ p_c = std::max (T (0 ), p0 * std::exp (-xi*particles.eps_pl_vol [p]));
653+ }
654+ else if (hardening_law == HardeningLaw::SinhImpl){
655+ p_c = std::max (T (0 ), K * std::sinh (-xi*particles.eps_pl_vol [p] + std::asinh (p0/K)));
656+ }
657+
658+ if ( (p_stress < -beta * p_c + stress_tolerance) || (p_stress > p_c - stress_tolerance) ){
659+ particles.muI [p] = M;
660+ }
661+ else {
662+ if (use_duvaut_lions_formulation){
663+ particles.muI [p] = ( (e_mu_prefac*h_dev-q_trial*(1 -b))/b ) / std::sqrt ((p_stress + beta * p_c) * (p_c - p_stress));
620664 }
621665 else {
622666 particles.muI [p] = q_stress / std::sqrt ((p_stress + beta * p_c) * (p_c - p_stress));
623667 }
624668 }
669+ } // end if use_mibf
625670
626- } // end if MCCVisc
627- // //////////////////////////////////////////////////////////////
628-
629-
630- delta_gamma = (q_trial - q_stress) / f_mu_prefac;
631- particles.eps_pl_dev [p] += (1.0 /d_prefac) * delta_gamma;
632- particles.delta_gamma [p] = delta_gamma / dt;
633-
634- hencky = q_stress / e_mu_prefac * hencky_deviatoric - ep*TV::Ones ();
635- particles.F [p] = svd.matrixU () * hencky.array ().exp ().matrix ().asDiagonal () * svd.matrixV ().transpose ();
636- } // if perform_rma
637- } // end MCC / MCCVisc
671+ } // end if perform_rma
672+ } // end MCC or MCCVisc
638673
639674 // Get new stress
640675 TM Fe = particles.F [p];
0 commit comments