After conducting dozens of coupling test runs using PreCICE v3.1.2, I observed that occasionally, an extremely small max-time-step-size issue arises, causing the simulation to hang indefinitely. This occurs because once the time step becomes excessively small, OpenFOAM gradually increases its allowed step size, leading to negligible progress in physical time—effectively stalling the simulation.
To mitigate this issue, I implemented a temporary variable (timestepBeforeTiny_) to store the normal OpenFOAM-determined time step (timestepSolverDetermined) just before the problem occurs. This allows me to force OpenFOAM to revert to the previously recorded stable step size, quickly restoring normal simulation progress.
I noticed that this problem happens more frequently when I use relatively large time-window-size and more participants. For instance, in the tests involving 4 participants, this problems happens every 3 out of 10 runs.
@Ya_Squall thank you for reporting this! There were a couple of related bugs in v3.1.2, which must have been fixed in v3.2.0. I strongly suggest that you upgrade. Read the announcement:
Regarding the change in the OpenFOAM adapter, feel free to open a pull request if you think this is something we should anyway add:
In some situations you may need to extend a substep to prevent a tiny final substep.
This is covered here:
In essence, you define a min timestep size and check if the remainder of the time window is larger than the desired time step plus the min time step size. If that is not the case, then you finish the time window.
I believe this is already implemented in the OpenFOAM adaptor, and also in my own code:
double tolerance = 1e-12;
if (precice_->getMaxTimeStepSize() - timestepSolverDetermined > tolerance)
{
timestepSolver_ = timestepSolverDetermined;
}
else if (timestepSolverDetermined - precice_->getMaxTimeStepSize() > tolerance)
{
timestepSolver_ = precice_->getMaxTimeStepSize();
}
else
{
adapterInfo("The solver's timestep is the same as the "
"coupling timestep.", "info");
timestepSolver_ = precice_->getMaxTimeStepSize();
}
if (precice_->getMaxTimeStepSize() <= tolerance)
{
//- Such a small value can happen if you use many substeps per time window over multiple time windows due to added-up differences of machine precision.
timestepBeforeTiny_ = timestepSolverDetermined;
tinyStepHappened_ = true;
}