@@ -126,9 +126,18 @@ MultiParameterPlasticityStressUpdate::MultiParameterPlasticityStressUpdate(
126126 _del_stress_params (num_sp ),
127127 _current_sp (num_sp ),
128128 _current_intnl (num_intnl ),
129+ _smoothed_q (yieldAndFlow (yieldAndFlow (num_sp , num_intnl ))),
129130 _dsp_scratch (num_sp ),
130131 _dsp_trial_scratch (num_sp ),
131132 _d2sp_scratch (num_sp ),
133+ _yfs_scratch (num_yf ),
134+ _sp_params_old_scratch (num_sp ),
135+ _delta_nr_params_scratch (num_sp + 1 ),
136+ _dintnl_scratch (num_intnl , std ::vector < Real > (num_sp )),
137+ _jac_scratch ((num_sp + 1 ) * (num_sp + 1 )),
138+ _ipiv_scratch (num_sp + 1 ),
139+ _all_q_scratch (num_yf , yieldAndFlow (num_sp , num_intnl )),
140+
132141 _smoother_function_type (
133142 parameters .get < MooseEnum > ("smoother_function_type" ).getEnum < SmootherFunctionType > ( ))
134143{
@@ -243,11 +252,8 @@ MultiParameterPlasticityStressUpdate::updateState(RankTwoTensor & strain_increme
243252 Real step_size = 1.0 ; // potentially can apply del_stress_params in substeps
244253 Real gaE_total = 0.0 ;
245254
246- // current values of the yield function, derivatives, etc
247- yieldAndFlow smoothed_q ;
248-
249255 // In the following sub-stepping procedure it is possible that
250- // the last step is an elastic step, and therefore smoothed_q won't
256+ // the last step is an elastic step, and therefore _smoothed_q won't
251257 // be computed on the last step, so we have to compute it.
252258 bool smoothed_q_calculated = false;
253259
@@ -287,16 +293,16 @@ MultiParameterPlasticityStressUpdate::updateState(RankTwoTensor & strain_increme
287293 // initialize current_sp, gaE and current_intnl based on the non-smoothed situation
288294 initializeVarsV (_trial_sp , _ok_intnl , _current_sp , gaE , _current_intnl );
289295 // and find the smoothed yield function, flow potential and derivatives
290- smoothed_q = smoothAllQuantities (_current_sp , _current_intnl );
296+ _smoothed_q = smoothAllQuantities (_current_sp , _current_intnl );
291297 smoothed_q_calculated = true;
292- calculateRHS (_trial_sp , _current_sp , gaE , smoothed_q , _rhs );
298+ calculateRHS (_trial_sp , _current_sp , gaE , _smoothed_q , _rhs );
293299 res2 = calculateRes2 (_rhs );
294300
295- // Perform a Newton-Raphson with linesearch to get current_sp, gaE, and also smoothed_q
301+ // Perform a Newton-Raphson with linesearch to get current_sp, gaE, and also _smoothed_q
296302 while (res2 > _f_tol2 && step_iter < _max_nr_its && nr_failure == 0 && ls_failure == 0 )
297303 {
298304 // solve the linear system and store the answer (the "updates") in rhs
299- nr_failure = nrStep (smoothed_q , _trial_sp , _current_sp , _current_intnl , gaE , _rhs );
305+ nr_failure = nrStep (_smoothed_q , _trial_sp , _current_sp , _current_intnl , gaE , _rhs );
300306 if (nr_failure != 0 )
301307 break ;
302308
@@ -315,12 +321,12 @@ MultiParameterPlasticityStressUpdate::updateState(RankTwoTensor & strain_increme
315321 break ;
316322 }
317323
318- // apply (parts of) the updates, re-calculate smoothed_q , and res2
324+ // apply (parts of) the updates, re-calculate _smoothed_q , and res2
319325 ls_failure = lineSearch (res2 ,
320326 _current_sp ,
321327 gaE ,
322328 _trial_sp ,
323- smoothed_q ,
329+ _smoothed_q ,
324330 _ok_intnl ,
325331 _current_intnl ,
326332 _rhs ,
@@ -343,7 +349,7 @@ MultiParameterPlasticityStressUpdate::updateState(RankTwoTensor & strain_increme
343349 _ok_sp ,
344350 gaE ,
345351 _ok_intnl ,
346- smoothed_q ,
352+ _smoothed_q ,
347353 step_size ,
348354 compute_full_tangent_operator ,
349355 _dvar_dtrial );
@@ -368,14 +374,14 @@ MultiParameterPlasticityStressUpdate::updateState(RankTwoTensor & strain_increme
368374 yieldFunctionValuesV (_ok_sp , _intnl [_qp ], _yf [_qp ]);
369375
370376 if (!smoothed_q_calculated )
371- smoothed_q = smoothAllQuantities (_ok_sp , _intnl [_qp ]);
377+ _smoothed_q = smoothAllQuantities (_ok_sp , _intnl [_qp ]);
372378
373379 setStressAfterReturnV (
374- _stress_trial , _ok_sp , gaE_total , _intnl [_qp ], smoothed_q , elasticity_tensor , stress_new );
380+ _stress_trial , _ok_sp , gaE_total , _intnl [_qp ], _smoothed_q , elasticity_tensor , stress_new );
375381
376382 setInelasticStrainIncrementAfterReturn (_stress_trial ,
377383 gaE_total ,
378- smoothed_q ,
384+ _smoothed_q ,
379385 elasticity_tensor ,
380386 stress_new ,
381387 inelastic_strain_increment );
@@ -390,7 +396,7 @@ MultiParameterPlasticityStressUpdate::updateState(RankTwoTensor & strain_increme
390396 stress_new ,
391397 _ok_sp ,
392398 gaE_total ,
393- smoothed_q ,
399+ _smoothed_q ,
394400 elasticity_tensor ,
395401 compute_full_tangent_operator ,
396402 _dvar_dtrial ,
@@ -401,8 +407,11 @@ MultiParameterPlasticityStressUpdate::yieldAndFlow
401407MultiParameterPlasticityStressUpdate ::smoothAllQuantities (const std ::vector < Real > & stress_params ,
402408 const std ::vector < Real > & intnl ) const
403409{
404- std ::vector < yieldAndFlow > all_q (_num_yf , yieldAndFlow (_num_sp , _num_intnl ));
405- computeAllQV (stress_params , intnl , all_q );
410+ mooseAssert (_all_q_scratch .size () == _num_yf ,
411+ "_all_q_scratch incorrectly sized in smoothAllQuantities" );
412+ for (auto & q : _all_q_scratch )
413+ q .reset ();
414+ computeAllQV (stress_params , intnl , _all_q_scratch );
406415
407416 /* This routine holds the key to my smoothing strategy. It
408417 * may be proved that this smoothing strategy produces a
@@ -430,55 +439,61 @@ MultiParameterPlasticityStressUpdate::smoothAllQuantities(const std::vector<Real
430439 // res_f is the index that contains the smoothed yieldAndFlow
431440 std ::size_t res_f = 0 ;
432441
433- for (std ::size_t a = 1 ; a < all_q .size (); ++ a )
442+ for (std ::size_t a = 1 ; a < _all_q_scratch .size (); ++ a )
434443 {
435- if (all_q [res_f ].f >= all_q [a ].f + _smoothing_tol )
444+ if (_all_q_scratch [res_f ].f >= _all_q_scratch [a ].f + _smoothing_tol )
436445 // no smoothing is needed: res_f is already indexes the largest yield function
437446 continue ;
438- else if (all_q [a ].f >= all_q [res_f ].f + _smoothing_tol )
447+ else if (_all_q_scratch [a ].f >= _all_q_scratch [res_f ].f + _smoothing_tol )
439448 {
440- // no smoothing is needed, and res_f needs to index to all_q [a]
449+ // no smoothing is needed, and res_f needs to index to _all_q_scratch [a]
441450 res_f = a ;
442451 continue ;
443452 }
444453 else
445454 {
446455 // smoothing is required
447- const Real f_diff = all_q [res_f ].f - all_q [a ].f ;
456+ const Real f_diff = _all_q_scratch [res_f ].f - _all_q_scratch [a ].f ;
448457 const Real ism = ismoother (f_diff );
449458 const Real sm = smoother (f_diff );
450459 const Real dsm = dsmoother (f_diff );
451- // we want: all_q [res_f].f = 0.5 * all_q [res_f].f + all_q [a].f + _smoothing_tol) + ism,
452- // but we have to do the derivatives first
460+ // we want: _all_q_scratch [res_f].f = 0.5 * _all_q_scratch [res_f].f + _all_q_scratch [a].f +
461+ // _smoothing_tol) + ism, but we have to do the derivatives first
453462 for (unsigned i = 0 ; i < _num_sp ; ++ i )
454463 {
455464 for (unsigned j = 0 ; j < _num_sp ; ++ j )
456- all_q [res_f ].d2g [i ][j ] =
457- 0.5 * (all_q [res_f ].d2g [i ][j ] + all_q [a ].d2g [i ][j ]) +
458- dsm * (all_q [res_f ].df [j ] - all_q [a ].df [j ]) * (all_q [res_f ].dg [i ] - all_q [a ].dg [i ]) +
459- sm * (all_q [res_f ].d2g [i ][j ] - all_q [a ].d2g [i ][j ]);
465+ _all_q_scratch [res_f ].d2g [i ][j ] =
466+ 0.5 * (_all_q_scratch [res_f ].d2g [i ][j ] + _all_q_scratch [a ].d2g [i ][j ]) +
467+ dsm * (_all_q_scratch [res_f ].df [j ] - _all_q_scratch [a ].df [j ]) *
468+ (_all_q_scratch [res_f ].dg [i ] - _all_q_scratch [a ].dg [i ]) +
469+ sm * (_all_q_scratch [res_f ].d2g [i ][j ] - _all_q_scratch [a ].d2g [i ][j ]);
460470 for (unsigned j = 0 ; j < _num_intnl ; ++ j )
461- all_q [res_f ].d2g_di [i ][j ] = 0.5 * (all_q [res_f ].d2g_di [i ][j ] + all_q [a ].d2g_di [i ][j ]) +
462- dsm * (all_q [res_f ].df_di [j ] - all_q [a ].df_di [j ]) *
463- (all_q [res_f ].dg [i ] - all_q [a ].dg [i ]) +
464- sm * (all_q [res_f ].d2g_di [i ][j ] - all_q [a ].d2g_di [i ][j ]);
471+ _all_q_scratch [res_f ].d2g_di [i ][j ] =
472+ 0.5 * (_all_q_scratch [res_f ].d2g_di [i ][j ] + _all_q_scratch [a ].d2g_di [i ][j ]) +
473+ dsm * (_all_q_scratch [res_f ].df_di [j ] - _all_q_scratch [a ].df_di [j ]) *
474+ (_all_q_scratch [res_f ].dg [i ] - _all_q_scratch [a ].dg [i ]) +
475+ sm * (_all_q_scratch [res_f ].d2g_di [i ][j ] - _all_q_scratch [a ].d2g_di [i ][j ]);
465476 }
466477 for (unsigned i = 0 ; i < _num_sp ; ++ i )
467478 {
468- all_q [res_f ].df [i ] = 0.5 * (all_q [res_f ].df [i ] + all_q [a ].df [i ]) +
469- sm * (all_q [res_f ].df [i ] - all_q [a ].df [i ]);
479+ _all_q_scratch [res_f ].df [i ] =
480+ 0.5 * (_all_q_scratch [res_f ].df [i ] + _all_q_scratch [a ].df [i ]) +
481+ sm * (_all_q_scratch [res_f ].df [i ] - _all_q_scratch [a ].df [i ]);
470482 // whether the following (smoothing g with f's smoother) is a good strategy remains to be
471483 // seen...
472- all_q [res_f ].dg [i ] = 0.5 * (all_q [res_f ].dg [i ] + all_q [a ].dg [i ]) +
473- sm * (all_q [res_f ].dg [i ] - all_q [a ].dg [i ]);
484+ _all_q_scratch [res_f ].dg [i ] =
485+ 0.5 * (_all_q_scratch [res_f ].dg [i ] + _all_q_scratch [a ].dg [i ]) +
486+ sm * (_all_q_scratch [res_f ].dg [i ] - _all_q_scratch [a ].dg [i ]);
474487 }
475488 for (unsigned i = 0 ; i < _num_intnl ; ++ i )
476- all_q [res_f ].df_di [i ] = 0.5 * (all_q [res_f ].df_di [i ] + all_q [a ].df_di [i ]) +
477- sm * (all_q [res_f ].df_di [i ] - all_q [a ].df_di [i ]);
478- all_q [res_f ].f = 0.5 * (all_q [res_f ].f + all_q [a ].f + _smoothing_tol ) + ism ;
489+ _all_q_scratch [res_f ].df_di [i ] =
490+ 0.5 * (_all_q_scratch [res_f ].df_di [i ] + _all_q_scratch [a ].df_di [i ]) +
491+ sm * (_all_q_scratch [res_f ].df_di [i ] - _all_q_scratch [a ].df_di [i ]);
492+ _all_q_scratch [res_f ].f =
493+ 0.5 * (_all_q_scratch [res_f ].f + _all_q_scratch [a ].f + _smoothing_tol ) + ism ;
479494 }
480495 }
481- return all_q [res_f ];
496+ return _all_q_scratch [res_f ];
482497}
483498
484499Real
@@ -559,12 +574,16 @@ MultiParameterPlasticityStressUpdate::lineSearch(Real & res2,
559574 const std ::vector < Real > & intnl_ok ,
560575 std ::vector < Real > & intnl ,
561576 std ::vector < Real > & rhs ,
562- Real & linesearch_needed ) const
577+ Real & linesearch_needed )
563578{
564579 const Real res2_old = res2 ;
565- const std ::vector < Real > sp_params_old = stress_params ;
580+ mooseAssert (_sp_params_old_scratch .size () == _num_sp ,
581+ "_sp_params_old_scratch incorrectly sized in lineSearch" );
582+ _sp_params_old_scratch = stress_params ;
566583 const Real gaE_old = gaE ;
567- const std ::vector < Real > delta_nr_params = rhs ;
584+ mooseAssert (_delta_nr_params_scratch .size () == rhs .size (),
585+ "_delta_nr_params_scratch incorrectly sized in lineSearch" );
586+ _delta_nr_params_scratch = rhs ;
568587
569588 Real lam = 1.0 ; // line-search parameter
570589 const Real lam_min = 1E-10 ; // minimum value of lam allowed
@@ -579,8 +598,8 @@ MultiParameterPlasticityStressUpdate::lineSearch(Real & res2,
579598 {
580599 // update variables using the current line-search parameter
581600 for (unsigned i = 0 ; i < _num_sp ; ++ i )
582- stress_params [i ] = sp_params_old [i ] + lam * delta_nr_params [i ];
583- gaE = gaE_old + lam * delta_nr_params [_num_sp ];
601+ stress_params [i ] = _sp_params_old_scratch [i ] + lam * _delta_nr_params_scratch [i ];
602+ gaE = gaE_old + lam * _delta_nr_params_scratch [_num_sp ];
584603
585604 // and internal parameters
586605 setIntnlValuesV (trial_stress_params , stress_params , intnl_ok , intnl );
@@ -642,19 +661,26 @@ MultiParameterPlasticityStressUpdate::nrStep(const yieldAndFlow & smoothed_q,
642661 Real gaE ,
643662 std ::vector < Real > & rhs ) const
644663{
645- std :: vector < std :: vector < Real >> dintnl ( _num_intnl , std :: vector < Real > ( _num_sp ) );
646- setIntnlDerivativesV (trial_stress_params , stress_params , intnl , dintnl );
664+ mooseAssert ( _dintnl_scratch . size () == _num_intnl , "_dintnl_scratch incorrectly sized in nrStep" );
665+ setIntnlDerivativesV (trial_stress_params , stress_params , intnl , _dintnl_scratch );
647666
648- std ::vector < double > jac ((_num_sp + 1 ) * (_num_sp + 1 ));
649- dnRHSdVar (smoothed_q , dintnl , stress_params , gaE , jac );
667+ mooseAssert (_jac_scratch .size () == (_num_sp + 1 ) * (_num_sp + 1 ),
668+ "_jac_scratch incorrectly sized in nrStep" );
669+ dnRHSdVar (smoothed_q , _dintnl_scratch , stress_params , gaE , _jac_scratch );
650670
651671 // use LAPACK to solve the linear system
652672 const PetscBLASInt nrhs = 1 ;
653- std :: vector < PetscBLASInt > ipiv ( _num_sp + 1 );
673+ mooseAssert ( _ipiv_scratch . size () == _num_sp + 1 , "_ipiv_scratch incorrectly sized in nrStep" );
654674 PetscBLASInt info ;
655675 const PetscBLASInt gesv_num_rhs = _num_sp + 1 ;
656- LAPACKgesv_ (
657- & gesv_num_rhs , & nrhs , & jac [0 ], & gesv_num_rhs , & ipiv [0 ], & rhs [0 ], & gesv_num_rhs , & info );
676+ LAPACKgesv_ (& gesv_num_rhs ,
677+ & nrhs ,
678+ & _jac_scratch [0 ],
679+ & gesv_num_rhs ,
680+ & _ipiv_scratch [0 ],
681+ & rhs [0 ],
682+ & gesv_num_rhs ,
683+ & info );
658684 return info ;
659685}
660686
689715MultiParameterPlasticityStressUpdate ::yieldF (const std ::vector < Real > & stress_params ,
690716 const std ::vector < Real > & intnl ) const
691717{
692- std :: vector < Real > yfs ( _num_yf );
693- yieldFunctionValuesV (stress_params , intnl , yfs );
694- return yieldF (yfs );
718+ mooseAssert ( _yfs_scratch . size () == _num_yf , "_yfs_scratch incorrectly sized in yieldF" );
719+ yieldFunctionValuesV (stress_params , intnl , _yfs_scratch );
720+ return yieldF (_yfs_scratch );
695721}
696722
697723Real
@@ -939,6 +965,9 @@ MultiParameterPlasticityStressUpdate::dVardTrial(bool elastic_only,
939965
940966 const Real ga = gaE / _En ;
941967
968+ // the following uses heap allocations in the belief that the compute time spent on alloc/dealloc
969+ // will be dwarfed by other aspects of implicit time stepping
970+
942971 std ::vector < std ::vector < Real >> dintnl (_num_intnl , std ::vector < Real > (_num_sp ));
943972 setIntnlDerivativesV (trial_stress_params , stress_params , intnl , dintnl );
944973
0 commit comments