-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: minimum interval for time-step increase after time-step cut #3338
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3338 +/- ##
========================================
Coverage 56.32% 56.32%
========================================
Files 1065 1065
Lines 90210 90230 +20
========================================
+ Hits 50807 50823 +16
- Misses 39403 39407 +4 ☔ View full report in Codecov by Sentry. |
@@ -401,14 +426,14 @@ real64 SolverBase::setNextDtBasedOnNewtonIter( real64 const & currentDt ) | |||
if( newtonIter < iterIncreaseLimit ) | |||
{ | |||
// Easy convergence, let's increase the time-step. | |||
nextDt = currentDt * m_nonlinearSolverParameters.timeStepIncreaseFactor(); | |||
nextDt = round( currentDt * m_nonlinearSolverParameters.timeStepIncreaseFactor() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is experimental, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's not the main purpose of this PR. If the time-steps are larger than O(10) rounding shouldn't be an issue, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about < 0.5 ? or i am missing something...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, then this doesn't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, we should not use round here. For some cases we need very tiny time steps.
* */ | ||
if( dt < m_nextDt ) | ||
{ | ||
m_lastDtCut = -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the logic only works with current "execute", no transfer to next cycle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this because the current execute might decrease the time-step to meet a exact time target for the event. Then, suppose you come from a recent time-step cut, If I didn't reset m_lastDtCut
, the code would not be able to increase the time step again (after having decreased not because of a noncoverged Newton, but because it had to meet a target time). Hope this explanation is not too confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's ok, just might be confusing that logic is not applied across cycles
let's say we set minTimeStepIncreaseInterval=5
and it does a cut inside one cycle, then does let's say 2 succesful subtimesteps and goes into another cycle - then that 5-2 counter is lost?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, in this scenario, the cut information is lost for the next subEvent and I agree it shouldn't.
Maybe it's possible to improve the logic here. If you have some ideas, feel free to implement!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PS: in your scenario, if the time-step is not decreased to meet a exact target time, then the cut information is not lost in the next subEvent
I think that if we wanted to follow proper grammatical rules, it should be |
Why not simply |
@@ -1008,6 +1011,9 @@ class SolverBase : public ExecutableGroup | |||
/// timestep of the next cycle | |||
real64 m_nextDt; | |||
|
|||
/// Number of cycles since last timestep cut | |||
integer m_lastDtCut; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
integer m_lastDtCut; | |
integer m_numTimestepsSinceLastDtCut; |
The Oxford dictionary does not have the entry as a single word but it would really simplify our life. Spellcheckers don't recognize it though. |
Talking about the actual goal of the PR... The logic is a bit clunky but we certainly need to include some more info about past convergence when selecting the new dt so this could be a start. I don't think we can have all those GEOS/src/coreComponents/common/Units.hpp Line 215 in 14a21b5
|
Updated the variable name and removed Let me know what you guys think! I suggest voting for deciding wheter to use |
please also merge https://github.com/GEOS-DEV/SPE11/tree/paludettomag1/spe11c once this PR is done |
It seems we'll need to rebaseline given the new logic and default value for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When increasing tilmestep, wouldn't it be appropriate to modify the time-step increase size based on the number of newton iterations the current step took to converge? So instead of: "if numNewtonIter < 8 then nextDt = dt * factor" we have the factor
be dependent on numNewtonIter
?
registerWrapper( viewKeysStruct::minTimeStepIncreaseIntervalString(), &m_minTimeStepIncreaseInterval ). | ||
setApplyDefaultValue( 10 ). | ||
setInputFlag( InputFlags::OPTIONAL ). | ||
setDescription( "Value of the minimum interval, since the last time-step cut, for increasing the time-step." ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does "minimum interval" mean? It is hard to tell from this description. is it "minimum number of time steps"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, it's minimum number of time steps. Let me update the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the comment below very clear:
GEOS_LOG_LEVEL_RANK_0( 1, GEOS_FMT( "{}: time-step size will be kept the same since it's been {} cycles since last cut.",
getName(), m_numTimestepsSinceLastDtCut ) );
What about renaming m_minNumCyclesFixedTimeStepAfterCut
. It's a bit wordy but a probably clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better m_minFixedTimeStepNumCyclesAfterCut
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am fine with all options presented
|
||
registerWrapper( viewKeysStruct::timeStepDecreaseFactorString(), &m_timeStepDecreaseFactor ). | ||
setApplyDefaultValue( 0.5 ). | ||
setInputFlag( InputFlags::OPTIONAL ). | ||
setDescription( "Factor by which the time step is decreased when the number of Newton iterations is large." ); | ||
setDescription( "Factor by which the time-step is decreased when the number of Newton iterations is large." ); | ||
|
||
registerWrapper( viewKeysStruct::timeStepIncreaseFactorString(), &m_timeStepIncreaseFactor ). | ||
setApplyDefaultValue( 2.0 ). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this default should be 2.0
....should it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the default could be a little more conservative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, but this is not the variable I'm adding in this PR (m_timeStepIncreaseFactor
). Should we make the change here or in another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, not in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except for the suggestion on rewording (optional), looks good to me. Thank you!
Co-authored-by: Nicola Castelletto <38361926+castelletto1@users.noreply.github.com>
Let's postpone the renaming to a future PR and consistently apply the change everywhere in GEOS. With all due respect to the Oxford Dictionary, my preference is to use |
This PR addresses an issue where the simulation oscillates between time-step increases and cuts due to Newton loop stagnation.
For example, in one simulation, the time-step gradually increases up to a point leading to Newton loop stagnation. Then, the time-step was subsequently reduced, allowing the Newton loop to converge, but it quickly tried to revert back to the original large time-step, causing the same stagnation. This cycle would repeat for many cycles in the simulation.
This PR introduces a parameter to enforce a minimum interval before the time-step can increase again after a reduction occurs, thus preventing the repeated back-and-forth time-step adjustments and avoiding Newton iteration failures in both parts of the simulation.
Side question: we have places where we use "time step" and "time-step". Should we choose one format and use it consistently?