34 template <
size_t materialTangentSize,
size_t nIntegrationDependentStateVars >
112 template <
size_t n,
size_t nState >
114 double minimumStepSize,
115 double maxScaleUpFactor,
116 double scaleDownFactor,
117 double integrationErrorTolerance,
118 int nPassesToIncrease,
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 ),
149 template <
size_t n,
size_t nState >
153 stressProgress = stressOld;
154 stateProgress = stateVarsOld;
157 template <
size_t n,
size_t nState >
160 return ( ( 1.0 - currentProgress ) <= 2e-16 && currentState == FullStep );
163 template <
size_t n,
size_t nState >
166 switch ( currentState ) {
168 const double remainingProgress = 1.0 - currentProgress;
169 if ( remainingProgress < currentSubstepSize )
170 currentSubstepSize = remainingProgress;
172 return currentSubstepSize;
175 case FirstHalfStep: {
176 return 0.5 * currentSubstepSize;
179 case SecondHalfStep: {
180 return 0.5 * currentSubstepSize;
183 default:
return -1.0;
186 template <
size_t n,
size_t nState >
190 switch ( currentState ) {
192 stress = stressProgress;
193 stateVars = stateProgress;
196 case FirstHalfStep: {
197 stress = stressProgress;
198 stateVars = stateProgress;
201 case SecondHalfStep: {
202 stress = stressProgressHalfTemp;
203 stateVars = stateProgressHalfTemp;
209 template <
size_t n,
size_t nState >
213 switch ( currentState ) {
215 currentSubstepSize *= scaleDownFactor;
221 "converged full step" );
222 return acceptSubstepWithFullStepOnly();
226 "converged full step" );
227 return acceptSubstepWithFullStepOnly();
230 currentState = FullStep;
232 if ( currentSubstepSize < minimumStepSize )
238 template <
size_t n,
size_t nState >
241 currentState = FullStep;
244 currentSubstepSize *= factorNew;
246 if ( currentSubstepSize < minimumStepSize )
252 template <
size_t n,
size_t nState >
257 if ( currentState == FullStep ) {
258 stressProgressFullTemp = resultStress;
259 stateProgressFullTemp = stateVars;
260 consistentTangentProgressFullTemp = consistentTangentProgress;
261 consistentTangentProgressFullTemp += currentSubstepSize * elasticTangent;
262 consistentTangentProgressFullTemp.applyOnTheLeft( dXdY );
263 currentState = FirstHalfStep;
266 else if ( currentState == FirstHalfStep ) {
268 stressProgressHalfTemp = resultStress;
269 stateProgressHalfTemp = stateVars;
270 consistentTangentProgressHalfTemp = consistentTangentProgress;
271 consistentTangentProgressHalfTemp += 0.5 * currentSubstepSize * elasticTangent;
272 consistentTangentProgressHalfTemp.applyOnTheLeft( dXdY );
273 currentState = SecondHalfStep;
277 else if ( currentState == SecondHalfStep ) {
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 );
288 if ( scaleFactor < 1e-1 )
290 if ( scaleFactor * currentSubstepSize < minimumStepSize )
291 scaleFactor = minimumStepSize / currentSubstepSize;
292 if ( scaleFactor > maxScaleUpFactor )
293 scaleFactor = maxScaleUpFactor;
294 if ( scaleFactor > 10 )
298 if ( error > integrationErrorTolerance ) {
300 if ( errorRatio < 2 ) {
301 return splitCurrentSubstep();
304 return repeatSubstep( scaleFactor );
308 stressProgressHalfTemp = resultStress;
309 stateProgressHalfTemp = stateVars;
310 consistentTangentProgressHalfTemp += 0.5 * currentSubstepSize * elasticTangent;
311 consistentTangentProgressHalfTemp.applyOnTheLeft( dXdY );
313 consistentTangentProgress = 2 * consistentTangentProgressHalfTemp - consistentTangentProgressFullTemp;
314 stressProgress = 2 * stressProgressHalfTemp - stressProgressFullTemp;
315 stateProgress = 2 * stateProgressHalfTemp - stateProgressFullTemp;
317 currentProgress += currentSubstepSize;
320 currentSubstepSize *= scaleFactor;
329 template <
size_t n,
size_t nState >
332 switch ( currentState ) {
336 consistentTangentProgress += currentSubstepSize * elasticTangent;
337 stressProgress = newStress;
339 currentProgress += currentSubstepSize;
340 currentState = FullStep;
345 case FirstHalfStep: {
346 consistentTangentProgressHalfTemp += 0.5 * currentSubstepSize * elasticTangent;
347 stressProgressHalfTemp = newStress;
348 currentState = SecondHalfStep;
351 case SecondHalfStep: {
352 acceptSubstepWithFullStepOnly();
358 template <
size_t n,
size_t nState >
360 Matrix6d& consistentTangentOperator,
363 stress = stressProgress;
364 stateVars = stateProgress;
365 consistentTangentOperator = consistentTangentProgress.topLeftCorner( 6, 6 );
368 template <
size_t n,
size_t nState >
371 consistentTangentProgress = consistentTangentProgressFullTemp;
372 stressProgress = stressProgressFullTemp;
373 stateProgress = stateProgressFullTemp;
375 currentProgress += currentSubstepSize;
376 currentState = FullStep;
381 template <
size_t n,
size_t nState >
384 if ( currentSubstepSize < 2 * minimumStepSize ) {
385 if ( ignoreErrorToleranceOnMinimumStepSize )
386 return acceptSubstepWithFullStepOnly();
391 consistentTangentProgressFullTemp = consistentTangentProgressHalfTemp;
392 stressProgressFullTemp = stressProgressHalfTemp;
393 stateProgressFullTemp = stateProgressHalfTemp;
394 currentSubstepSize *= 0.5;
395 currentState = FirstHalfStep;
399 template <
size_t n,
size_t nState >