[GeoMechanicsApplication] Fix bug in time step mechanism C++ workflow#14184
[GeoMechanicsApplication] Fix bug in time step mechanism C++ workflow#14184
Conversation
…TimeIncrementor interface
…d unit tests accordingly. Also made the moments of checking the delta time consistent with the python workflow.
…n but also added it to the constructor.
| mReductionFactor(ReductionFactor), | ||
| mIncreaseFactor(IncreaseFactor), | ||
| mUserMinDeltaTime(std::move(UserMinDeltaTime)), | ||
| mUserMinDeltaTime(UserMinDeltaTime), |
There was a problem hiding this comment.
Clang-tidy mentioned the move of a std::optional was not necessary
| KRATOS_ERROR_IF(MaxTimeStepFactor < 1.0) | ||
| << "Max_delta_time_factor must be greater than or equal to 1, but got " << MaxTimeStepFactor; | ||
|
|
||
| CorrectDeltaTimeToEndTime(StartTime); |
There was a problem hiding this comment.
This is the actual fix, we need to check at construction to make sure the first increment is correct
| return mUserMinDeltaTime.value_or(default_min_delta_time); | ||
| } | ||
|
|
||
| void AdaptiveTimeIncrementor::CorrectDeltaTimeToEndTime(double StartOfIncrement) |
There was a problem hiding this comment.
I'm struggling with the name of this function. What it does is if the deltatime would result in either a very small next step (difference smaller than min delta time) or if it would result in going beyond the end time, it corrects it to be the end time. If you have any suggestions for a better name, let me know
There was a problem hiding this comment.
CorrectDeltaTimeToReachEndTime or AdaptDeltaTimeToAvoidSmallNextIncrement
There was a problem hiding this comment.
These are both better than the current name, but they don't capture the 'preventing overshooting the end time' part of the function, so I'm still wondering if there's an even better name somewhere
There was a problem hiding this comment.
I agree that it's very hard to put the exact checks in words without ending up with extremely long function names. What about AdaptDeltaTimeIfNeeded? It doesn't spell out when it's needed, just that the time increment may or may not be modified after doing some checks.
There was a problem hiding this comment.
I think that's a good idea (since I don't see a way to capture both reasons in the function name). I did add a comment within the function to explain what it's doing. Hope that helps
| auto previous_state = TimeStepEndState{}; | ||
| previous_state.convergence_state = TimeStepEndState::ConvergenceState::converged; | ||
|
|
||
| time_incrementor.PostTimeStepExecution(previous_state); |
There was a problem hiding this comment.
Removing this line makes sure we don't do the correction that's in PostTimeStepExecution, to make sure a first step is also corrected
| KratosGeoMechanicsAvoidSmallTimeStepPythonRoute, | ||
| KratosGeoMechanicsAvoidSmallTimeStepCppRoute, |
There was a problem hiding this comment.
I find the SmallEndStep more descriptive than SmallTimeStep
| CheckMinimumDeltaTime(mDeltaTime); | ||
| } | ||
|
|
||
| void AdaptiveTimeIncrementor::CheckMinimumDeltaTime(double DeltaTime) const |
There was a problem hiding this comment.
As far as I can see, this member function is always called given the data member mDeltaTime. Since it has access to this data directly, we don't really need to pass it through the argument list. Since it's a private member function, client code won't be able to call it directly. Would it be cleaner to have an empty argument list and fetch the required data directly inside the function body?
| return mUserMinDeltaTime.value_or(default_min_delta_time); | ||
| } | ||
|
|
||
| void AdaptiveTimeIncrementor::CorrectDeltaTimeToEndTime(double StartOfIncrement) |
There was a problem hiding this comment.
I agree that it's very hard to put the exact checks in words without ending up with extremely long function names. What about AdaptDeltaTimeIfNeeded? It doesn't spell out when it's needed, just that the time increment may or may not be modified after doing some checks.
| auto previous_state = TimeStepEndState{}; | ||
| previous_state.convergence_state = TimeStepEndState::ConvergenceState::non_converged; | ||
| previous_state.time = 8.0; | ||
| previous_state.time = 0.0; |
avdg81
left a comment
There was a problem hiding this comment.
Thanks a lot for processing the review suggestions. To me, this PR looks good to go.
| // If the delta time would result in | ||
| // a. the next step exceeding the end time or | ||
| // b. having too small a remaining time step | ||
| // then the delta time is chosen such that the next step ends exactly at the end time. |
markelov208
left a comment
There was a problem hiding this comment.
Hi Richard, thank you for fixing this bug and adding unit and integration tests. The PR looks very good for me.
📝 Description
In the time stepping scheme in the C++ workflow, avoiding a small step was not done for the very first time-step, which resulted in an error for cases where the first increment of a stage would result in a very small subsequent step to get to the end-time.
This PR adds the same upscaling functionality that was there for subsequent steps also in the constructor, to check the very first step of a stage.
Changelog: