AdaptiveSubstepper.h
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------
2  * _
3  * _ __ ___ __ _ _ __ _ __ ___ ___ | |_
4  * | '_ ` _ \ / _` | '__| '_ ` _ \ / _ \| __|
5  * | | | | | | (_| | | | | | | | | (_) | |_
6  * |_| |_| |_|\__,_|_| |_| |_| |_|\___/ \__|
7  *
8  * Unit of Strength of Materials and Structural Analysis
9  * University of Innsbruck,
10  * 2020 - today
11  *
12  * festigkeitslehre@uibk.ac.at
13  *
14  * Matthias Neuner matthias.neuner@uibk.ac.at
15  *
16  * This file is part of the MAteRialMOdellingToolbox (marmot).
17  *
18  * This library is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU Lesser General Public
20  * License as published by the Free Software Foundation; either
21  * version 2.1 of the License, or (at your option) any later version.
22  *
23  * The full text of the license can be found in the file LICENSE.md at
24  * the top level directory of marmot.
25  * ---------------------------------------------------------------------
26  */
27 
28 #pragma once
29 #include "Marmot/MarmotJournal.h"
30 #include "Marmot/MarmotTypedefs.h"
31 
33 
34  template < size_t materialTangentSize, size_t nIntegrationDependentStateVars >
41  public:
43  typedef Eigen::Matrix< double, materialTangentSize, materialTangentSize > TangentSizedMatrix;
45  typedef Eigen::Matrix< double, nIntegrationDependentStateVars, 1 > IntegrationStateVector;
46 
48  double minimumStepSize,
49  double maxScaleUpFactor,
50  double scaleDownFactor,
53  const Matrix6d& Cel );
54 
56  void setConvergedProgress( const Marmot::Vector6d& stressOld, const IntegrationStateVector& stateVarsOld );
58  bool isFinished();
60  double getNextSubstep();
62  int getNumberOfSubsteps();
64  bool finishSubstep( const Marmot::Vector6d& resultStress,
65  const TangentSizedMatrix& dXdY,
66  const IntegrationStateVector& stateVars );
68  void finishElasticSubstep( const Marmot::Vector6d& resultStress );
70  bool discardSubstep();
72  bool repeatSubstep( double decrementationFactor );
73 
79  void getResults( Marmot::Vector6d& stress, Matrix6d& consistentTangent, IntegrationStateVector& stateVars );
80 
81  private:
83  const int nPassesToIncrease;
85 
90 
95 
96  // temporal storages, which are used until a cycle full/half/half has finished successfully
100 
102 
105 
107  bool splitCurrentSubstep();
108  };
109 } // namespace Marmot::NumericalAlgorithms
110 
111 namespace Marmot::NumericalAlgorithms {
112  template < size_t n, size_t nState >
114  double minimumStepSize,
115  double maxScaleUpFactor,
116  double scaleDownFactor,
117  double integrationErrorTolerance,
118  int nPassesToIncrease,
119  const Matrix6d& Cel )
120  : initialStepSize( initialStepSize ),
121  minimumStepSize( minimumStepSize ),
122  maxScaleUpFactor( maxScaleUpFactor ),
123  scaleDownFactor( scaleDownFactor ),
124  integrationErrorTolerance( integrationErrorTolerance ),
125  nPassesToIncrease( nPassesToIncrease ),
126  ignoreErrorToleranceOnMinimumStepSize( true ),
127  currentProgress( 0.0 ),
128  currentSubstepSize( initialStepSize ),
129  passedSubsteps( 0 ),
130  substepIndex( -1 )
131  {
132  elasticTangent = TangentSizedMatrix::Identity();
133  elasticTangent.topLeftCorner( 6, 6 ) = Cel;
134 
135  consistentTangentProgress = TangentSizedMatrix::Zero();
136  consistentTangentProgressFullTemp = TangentSizedMatrix::Zero();
137  consistentTangentProgressHalfTemp = TangentSizedMatrix::Zero();
138 
139  stressProgressHalfTemp.setZero();
140  stressProgressFullTemp.setZero();
141  stateProgressHalfTemp.setZero();
142  stateProgressFullTemp.setZero();
145 
147  }
148 
149  template < size_t n, size_t nState >
151  const IntegrationStateVector& stateVarsOld )
152  {
153  stressProgress = stressOld;
154  stateProgress = stateVarsOld;
155  }
156 
157  template < size_t n, size_t nState >
159  {
160  return ( ( 1.0 - currentProgress ) <= 2e-16 && currentState == FullStep );
161  }
162 
163  template < size_t n, size_t nState >
165  {
166  switch ( currentState ) {
167  case FullStep: {
168  const double remainingProgress = 1.0 - currentProgress;
169  if ( remainingProgress < currentSubstepSize )
170  currentSubstepSize = remainingProgress;
171  substepIndex++;
172  return currentSubstepSize;
173  break;
174  }
175  case FirstHalfStep: {
176  return 0.5 * currentSubstepSize;
177  break;
178  }
179  case SecondHalfStep: {
180  return 0.5 * currentSubstepSize;
181  break;
182  }
183  default: return -1.0;
184  }
185  }
186  template < size_t n, size_t nState >
188  IntegrationStateVector& stateVars )
189  {
190  switch ( currentState ) {
191  case FullStep: {
192  stress = stressProgress;
193  stateVars = stateProgress;
194  break;
195  }
196  case FirstHalfStep: {
197  stress = stressProgress;
198  stateVars = stateProgress;
199  break;
200  }
201  case SecondHalfStep: {
202  stress = stressProgressHalfTemp;
203  stateVars = stateProgressHalfTemp;
204  break;
205  }
206  }
207  }
208 
209  template < size_t n, size_t nState >
211  {
212  passedSubsteps = 0;
213  switch ( currentState ) {
214  case FullStep: {
215  currentSubstepSize *= scaleDownFactor; // we use the scale factor only here
216  break;
217  }
218  // these cases should actually never happen, as the full step has already converged!
219  case FirstHalfStep:
220  MarmotJournal::warningToMSG( "UMAT: warning, 1th half sub step has not converged after already "
221  "converged full step" );
222  return acceptSubstepWithFullStepOnly();
223 
224  case SecondHalfStep:
225  MarmotJournal::warningToMSG( "UMAT: warning, 2th half sub step has not converged after already "
226  "converged full step" );
227  return acceptSubstepWithFullStepOnly();
228  }
229 
230  currentState = FullStep;
231 
232  if ( currentSubstepSize < minimumStepSize )
233  return MarmotJournal::warningToMSG( "UMAT: Substepper: Minimal stepzsize reached" );
234  else
235  return true;
236  }
237 
238  template < size_t n, size_t nState >
240  {
241  currentState = FullStep;
242  passedSubsteps = 0;
243 
244  currentSubstepSize *= factorNew; // we use the scale factor only here
245 
246  if ( currentSubstepSize < minimumStepSize )
247  return MarmotJournal::warningToMSG( "UMAT: Substepper: Minimal stepzsize reached" );
248  else
249  return true;
250  }
251 
252  template < size_t n, size_t nState >
254  const TangentSizedMatrix& dXdY,
255  const IntegrationStateVector& stateVars )
256  {
257  if ( currentState == FullStep ) {
258  stressProgressFullTemp = resultStress;
259  stateProgressFullTemp = stateVars;
260  consistentTangentProgressFullTemp = consistentTangentProgress;
261  consistentTangentProgressFullTemp += currentSubstepSize * elasticTangent;
262  consistentTangentProgressFullTemp.applyOnTheLeft( dXdY );
263  currentState = FirstHalfStep;
264  return true;
265  }
266  else if ( currentState == FirstHalfStep ) {
267 
268  stressProgressHalfTemp = resultStress;
269  stateProgressHalfTemp = stateVars;
270  consistentTangentProgressHalfTemp = consistentTangentProgress;
271  consistentTangentProgressHalfTemp += 0.5 * currentSubstepSize * elasticTangent;
272  consistentTangentProgressHalfTemp.applyOnTheLeft( dXdY );
273  currentState = SecondHalfStep;
274  return true;
275  }
276 
277  else if ( currentState == SecondHalfStep ) {
278  // error Estimation
279 
280  currentState = FullStep;
281  const double error = ( resultStress - stressProgressFullTemp ).norm();
282  const double errorRatio = error / integrationErrorTolerance;
283  double scaleFactor = 1.0;
284  if ( errorRatio > 1e-10 )
285  scaleFactor = 0.9 * std::sqrt( 1. / errorRatio );
286 
287  // saturations
288  if ( scaleFactor < 1e-1 )
289  scaleFactor = 1e-1;
290  if ( scaleFactor * currentSubstepSize < minimumStepSize )
291  scaleFactor = minimumStepSize / currentSubstepSize;
292  if ( scaleFactor > maxScaleUpFactor )
293  scaleFactor = maxScaleUpFactor;
294  if ( scaleFactor > 10 )
295  scaleFactor = 10;
296 
297  // Error large than tolerance?
298  if ( error > integrationErrorTolerance ) {
299  passedSubsteps = 0;
300  if ( errorRatio < 2 ) {
301  return splitCurrentSubstep();
302  }
303  else {
304  return repeatSubstep( scaleFactor );
305  }
306  }
307  else {
308  stressProgressHalfTemp = resultStress;
309  stateProgressHalfTemp = stateVars;
310  consistentTangentProgressHalfTemp += 0.5 * currentSubstepSize * elasticTangent;
311  consistentTangentProgressHalfTemp.applyOnTheLeft( dXdY );
312 
313  consistentTangentProgress = 2 * consistentTangentProgressHalfTemp - consistentTangentProgressFullTemp;
314  stressProgress = 2 * stressProgressHalfTemp - stressProgressFullTemp;
315  stateProgress = 2 * stateProgressHalfTemp - stateProgressFullTemp;
316 
317  currentProgress += currentSubstepSize;
318 
319  passedSubsteps++;
320  currentSubstepSize *= scaleFactor;
321 
322  return true;
323  }
324  }
325  else
326  return false;
327  }
328 
329  template < size_t n, size_t nState >
331  {
332  switch ( currentState ) {
333  case FullStep: {
334  // this means, that the complete current cycle is already successfull,
335  // as the two half steps must also be elastic!
336  consistentTangentProgress += currentSubstepSize * elasticTangent;
337  stressProgress = newStress;
338  // no need for two half steps if full step was already elastic
339  currentProgress += currentSubstepSize;
340  currentState = FullStep;
341  passedSubsteps++;
342  break;
343  }
344 
345  case FirstHalfStep: {
346  consistentTangentProgressHalfTemp += 0.5 * currentSubstepSize * elasticTangent;
347  stressProgressHalfTemp = newStress;
348  currentState = SecondHalfStep;
349  break;
350  }
351  case SecondHalfStep: {
352  acceptSubstepWithFullStepOnly();
353  break;
354  }
355  }
356  }
357 
358  template < size_t n, size_t nState >
360  Matrix6d& consistentTangentOperator,
361  IntegrationStateVector& stateVars )
362  {
363  stress = stressProgress;
364  stateVars = stateProgress;
365  consistentTangentOperator = consistentTangentProgress.topLeftCorner( 6, 6 );
366  }
367 
368  template < size_t n, size_t nState >
370  {
371  consistentTangentProgress = consistentTangentProgressFullTemp;
372  stressProgress = stressProgressFullTemp;
373  stateProgress = stateProgressFullTemp;
374 
375  currentProgress += currentSubstepSize;
376  currentState = FullStep;
377 
378  return true;
379  }
380 
381  template < size_t n, size_t nState >
383  {
384  if ( currentSubstepSize < 2 * minimumStepSize ) {
385  if ( ignoreErrorToleranceOnMinimumStepSize )
386  return acceptSubstepWithFullStepOnly();
387  else
388  return false;
389  }
390 
391  consistentTangentProgressFullTemp = consistentTangentProgressHalfTemp;
392  stressProgressFullTemp = stressProgressHalfTemp;
393  stateProgressFullTemp = stateProgressHalfTemp;
394  currentSubstepSize *= 0.5;
395  currentState = FirstHalfStep;
396 
397  return true;
398  }
399  template < size_t n, size_t nState >
401  {
402  return substepIndex;
403  }
404 } // namespace Marmot::NumericalAlgorithms
Marmot::NumericalAlgorithms::AdaptiveSubstepper::currentSubstepSize
double currentSubstepSize
Definition: AdaptiveSubstepper.h:87
Marmot::NumericalAlgorithms::AdaptiveSubstepper::getResults
void getResults(Marmot::Vector6d &stress, Matrix6d &consistentTangent, IntegrationStateVector &stateVars)
Write the current results.
Definition: AdaptiveSubstepper.h:359
Marmot::NumericalAlgorithms::AdaptiveSubstepper::discardSubstep
bool discardSubstep()
discard the current subincrement
Definition: AdaptiveSubstepper.h:210
Marmot::NumericalAlgorithms::AdaptiveSubstepper::passedSubsteps
int passedSubsteps
Definition: AdaptiveSubstepper.h:88
Marmot::NumericalAlgorithms::AdaptiveSubstepper::ignoreErrorToleranceOnMinimumStepSize
const bool ignoreErrorToleranceOnMinimumStepSize
Definition: AdaptiveSubstepper.h:84
Marmot::NumericalAlgorithms
Definition: MarmotNumericalDifferentiation.h:34
Marmot::NumericalAlgorithms::AdaptiveSubstepper::TangentSizedMatrix
Eigen::Matrix< double, materialTangentSize, materialTangentSize > TangentSizedMatrix
Matrix for describing the nonlinear equation system of the return mapping algorithm.
Definition: AdaptiveSubstepper.h:43
Marmot::NumericalAlgorithms::AdaptiveSubstepper::splitCurrentSubstep
bool splitCurrentSubstep()
Definition: AdaptiveSubstepper.h:382
Marmot::NumericalAlgorithms::AdaptiveSubstepper::integrationErrorTolerance
const double integrationErrorTolerance
Definition: AdaptiveSubstepper.h:82
Marmot::NumericalAlgorithms::AdaptiveSubstepper::acceptSubstepWithFullStepOnly
bool acceptSubstepWithFullStepOnly()
Definition: AdaptiveSubstepper.h:369
MarmotJournal.h
Marmot::NumericalAlgorithms::AdaptiveSubstepper::setConvergedProgress
void setConvergedProgress(const Marmot::Vector6d &stressOld, const IntegrationStateVector &stateVarsOld)
Set the current converged state.
Definition: AdaptiveSubstepper.h:150
MarmotTypedefs.h
Marmot::Matrix6d
Eigen::Matrix< double, 6, 6 > Matrix6d
Definition: MarmotTypedefs.h:35
Marmot::NumericalAlgorithms::AdaptiveSubstepper::currentState
SubsteppingState currentState
Definition: AdaptiveSubstepper.h:104
Marmot::NumericalAlgorithms::AdaptiveSubstepper::finishSubstep
bool finishSubstep(const Marmot::Vector6d &resultStress, const TangentSizedMatrix &dXdY, const IntegrationStateVector &stateVars)
finish a subincrement with plasticity
Definition: AdaptiveSubstepper.h:253
Marmot::NumericalAlgorithms::AdaptiveSubstepper::FullStep
@ FullStep
Definition: AdaptiveSubstepper.h:103
Marmot::NumericalAlgorithms::AdaptiveSubstepper::stressProgressHalfTemp
Marmot::Vector6d stressProgressHalfTemp
Definition: AdaptiveSubstepper.h:97
Marmot::NumericalAlgorithms::AdaptiveSubstepper
Definition: AdaptiveSubstepper.h:35
Marmot::NumericalAlgorithms::AdaptiveSubstepper::repeatSubstep
bool repeatSubstep(double decrementationFactor)
repeat the current subincrement with a smaller step
Definition: AdaptiveSubstepper.h:239
Marmot::NumericalAlgorithms::AdaptiveSubstepper::FirstHalfStep
@ FirstHalfStep
Definition: AdaptiveSubstepper.h:103
Marmot::NumericalAlgorithms::AdaptiveSubstepper::finishElasticSubstep
void finishElasticSubstep(const Marmot::Vector6d &resultStress)
finish a subincrement with elasticity only
Definition: AdaptiveSubstepper.h:330
Marmot::NumericalAlgorithms::AdaptiveSubstepper::SubsteppingState
SubsteppingState
Definition: AdaptiveSubstepper.h:103
Marmot::NumericalAlgorithms::AdaptiveSubstepper::SecondHalfStep
@ SecondHalfStep
Definition: AdaptiveSubstepper.h:103
Marmot::NumericalAlgorithms::AdaptiveSubstepper::getCurrentTangentOperator
Matrix6d getCurrentTangentOperator()
get the algorithmic tangent for the current state
Marmot::NumericalAlgorithms::AdaptiveSubstepper::currentProgress
double currentProgress
Definition: AdaptiveSubstepper.h:86
Marmot::NumericalAlgorithms::AdaptiveSubstepper::maxScaleUpFactor
const double maxScaleUpFactor
Definition: AdaptiveSubstepper.h:82
Marmot::NumericalAlgorithms::AdaptiveSubstepper::getConvergedProgress
void getConvergedProgress(Marmot::Vector6d &stress, IntegrationStateVector &stateVars)
get the last converged state
Definition: AdaptiveSubstepper.h:187
Marmot::NumericalAlgorithms::AdaptiveSubstepper::substepIndex
int substepIndex
Definition: AdaptiveSubstepper.h:89
Marmot::NumericalAlgorithms::AdaptiveSubstepper::consistentTangentProgressHalfTemp
TangentSizedMatrix consistentTangentProgressHalfTemp
Definition: AdaptiveSubstepper.h:99
Marmot::NumericalAlgorithms::AdaptiveSubstepper::consistentTangentProgressFullTemp
TangentSizedMatrix consistentTangentProgressFullTemp
Definition: AdaptiveSubstepper.h:99
Marmot::Vector6d
Eigen::Matrix< double, 6, 1 > Vector6d
Definition: MarmotTypedefs.h:43
Marmot::NumericalAlgorithms::AdaptiveSubstepper::stateProgressFullTemp
IntegrationStateVector stateProgressFullTemp
Definition: AdaptiveSubstepper.h:98
Marmot::NumericalAlgorithms::AdaptiveSubstepper::stateProgress
IntegrationStateVector stateProgress
Definition: AdaptiveSubstepper.h:93
Marmot::NumericalAlgorithms::AdaptiveSubstepper::elasticTangent
TangentSizedMatrix elasticTangent
Definition: AdaptiveSubstepper.h:101
Marmot::NumericalAlgorithms::AdaptiveSubstepper::scaleDownFactor
const double scaleDownFactor
Definition: AdaptiveSubstepper.h:82
Marmot::NumericalAlgorithms::AdaptiveSubstepper::AdaptiveSubstepper
AdaptiveSubstepper(double initialStepSize, double minimumStepSize, double maxScaleUpFactor, double scaleDownFactor, double integrationErrorTolerance, int nPassesToIncrease, const Matrix6d &Cel)
Definition: AdaptiveSubstepper.h:113
Marmot::NumericalAlgorithms::AdaptiveSubstepper::consistentTangentProgress
TangentSizedMatrix consistentTangentProgress
Definition: AdaptiveSubstepper.h:94
Marmot::NumericalAlgorithms::AdaptiveSubstepper::stateProgressHalfTemp
IntegrationStateVector stateProgressHalfTemp
Definition: AdaptiveSubstepper.h:98
Marmot::NumericalAlgorithms::AdaptiveSubstepper::initialStepSize
const double initialStepSize
Definition: AdaptiveSubstepper.h:82
Marmot::NumericalAlgorithms::AdaptiveSubstepper::nPassesToIncrease
const int nPassesToIncrease
Definition: AdaptiveSubstepper.h:83
Marmot::NumericalAlgorithms::AdaptiveSubstepper::stressProgress
Marmot::Vector6d stressProgress
internal storages for the progress of the total increment
Definition: AdaptiveSubstepper.h:92
Marmot::NumericalAlgorithms::AdaptiveSubstepper::IntegrationStateVector
Eigen::Matrix< double, nIntegrationDependentStateVars, 1 > IntegrationStateVector
Vector to carry the internal state of a material.
Definition: AdaptiveSubstepper.h:45
Marmot::NumericalAlgorithms::AdaptiveSubstepper::getNextSubstep
double getNextSubstep()
get the next subincrement size
Definition: AdaptiveSubstepper.h:164
Marmot::NumericalAlgorithms::AdaptiveSubstepper::isFinished
bool isFinished()
Check if the subincrementation is finished.
Definition: AdaptiveSubstepper.h:158
Marmot::NumericalAlgorithms::AdaptiveSubstepper::stressProgressFullTemp
Marmot::Vector6d stressProgressFullTemp
Definition: AdaptiveSubstepper.h:97
MarmotJournal::warningToMSG
static bool warningToMSG(const std::string &message)
Marmot::NumericalAlgorithms::AdaptiveSubstepper::getNumberOfSubsteps
int getNumberOfSubsteps()
get the finished number of subincrements
Definition: AdaptiveSubstepper.h:400
Marmot::NumericalAlgorithms::AdaptiveSubstepper::minimumStepSize
const double minimumStepSize
Definition: AdaptiveSubstepper.h:82