Skip to content

Implement under-relaxation for the tight-coupling iterative solver#3300

Open
luwang00 wants to merge 33 commits intoOpenFAST:devfrom
luwang00:f/underrelaxation
Open

Implement under-relaxation for the tight-coupling iterative solver#3300
luwang00 wants to merge 33 commits intoOpenFAST:devfrom
luwang00:f/underrelaxation

Conversation

@luwang00
Copy link
Copy Markdown
Contributor

@luwang00 luwang00 commented Apr 8, 2026

This PR is not ready to be merged

Feature or improvement description
This PR adds under-relaxation for the tight-coupling iterative solver to address occasional solution divergence. Using an under-relaxation factor less than 1 can potentially improve the stability of numerically challenging models. It can also improve simulation time by avoiding oscillatory convergence and reducing the number of times the Jacobian needs to be updated.

Currently, a simple constant under-relaxation factor based on user input is implemented. Setting it to 1 removes under-relaxation and recovers the previous behavior. In the future, a default value such as 0.8 can be implemented. Alternatively, automatic under-relaxation based on the change in residual between successive iterations is also possible.

The under-relaxation is only applied to the input corrections and not the state corrections. This appears to be adequate.

Example results
The following example results are based on a very challenging model of a floating twin-rotor MHK turbine system with flexible blades (with added mass) and support structures and OLAF FVW model.

Without under-relaxation, the simulation diverges after about 22 s. In contrast, the simulation proceeds without issue with a constant under-relaxation factor of 0.3 (higher value not tested). Before the simulation diverges without under-relaxation, the two simulations give consistent results. See example output channels below:
imageimage

The numbers of iterations at each time step are compared below. Interestingly, simulating with under-relaxation requires comparable or fewer iterations, suggesting very poor convergence without. This is also obvious from the fact that when simulating without under-relaxation, OpenFAST needs to recompute the Jacobian frequently, as indicated by the spikes in the number of iterations in the figure below. In contrast, the simulation with under-relaxation does not require any Jacobian update after initialization.
image

Impacted areas of the software
Glue-code

Test results, if applicable
r-test input files need to be updated with the new under-relaxation factor input. Results should not change if the under-relaxation factor is set to 1.

  • r-test branch merging required

andrew-platt and others added 30 commits March 12, 2026 17:53
Update docs for 5.0.0 release, including missing api changes
MD: standardize input file header text to match docs
 * Previously, olaf wake propagation did not consider wave velocity.
 * A similar bug was found in the SetSectAvgInflow subroutine.
 * The optional BoxExceedAllow flag for IfW_FlowField_GetVelAcc was not passed correctly through the SeaState WaveField subroutine for AD.
Various bug fixes for AeroDyn when modeling MHK turbines
Temporary fix for HydroDyn rectangular member visualization
Previously, the self-weight of the reaction node(s) is missing. This is now added back along with any cable loads on the reaction node(s) just in case.
FVW: Fix notification about wake extent
andrew-platt and others added 2 commits April 7, 2026 13:03
OLAF FVW stability issue when simulating multiple rotors
@jjonkman
Copy link
Copy Markdown
Collaborator

jjonkman commented Apr 9, 2026

Dear @luwang00,

Thanks for this addition. Should it be that the relaxation factor reduces with each iteration of the nonlinear solve, and after convergence, the factor gets reset back to unity for the next time step? This is what we did within the nonlinear solve for the old quasi-static mooring module of FAST; I believe MAP++ does something similar. Perhaps with this method, the additional user input is not needed.

Best regards,

@andrew-platt
Copy link
Copy Markdown
Collaborator

Changing this to a dynamic relaxation factor could be really useful. Perhaps later.

if (Failed()) return

! Relax - Under-relaxation factor for the iterative solver (-) [>0 and <=1]
CALL ReadVar( UnIn, InputFile, p%Relax, "Relax", "Under-relaxation factor for the iterative solver (-) [>0 and <=1]", ErrStat2, ErrMsg2, UnEc)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we change this to a ReadVarWDefault and use a default value of 1.0?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a constant default should be around 0.8. Alternatively, we can make the default the adaptive option.

@andrew-platt andrew-platt changed the base branch from rc-5.0.1 to dev April 9, 2026 17:15
@luwang00
Copy link
Copy Markdown
Contributor Author

luwang00 commented Apr 9, 2026

Hi @jjonkman, thanks for the comment.

I think typically the relaxation factors should be smaller, i.e., take smaller steps, for the first few iterations when the solution is far from convergence and the correction step is large. This is where there is the greatest danger of overshooting and divergence. As we approach a converged solution, the corrections are smaller, and we can gradually increase the underrelaxation factor safely to some maximum value.

I want to see if I can implement a simple adaptive underrelaxation based on the change in residual, but even then, I think it would be nice to give the user some control over this (with default settings), like a fixed underrelaxation factor or a max and a min value for adaptive underrelaxation. Different models can have very different characteristics. For some models, proper under-relaxation can be critical, and it is hard to have some thing that is one size fit all.

I also added some example results in the PR message above.

@jjonkman
Copy link
Copy Markdown
Collaborator

jjonkman commented Apr 9, 2026

Thanks for the addition insight and example results, @luwang00.

I see your point about wanting to increase the relaxation factor with successive iterations. If I recall from past quasi-static mooring work, we chose the opposite because our starting point was the converged solution from the previous time step and only small changes are expected between time steps. So, divergence was not really a concern and reducing the relaxation factor with iteration helped ensure that convergence was reached for the few cases where the solution did start to diverge. I suspect the same is true for tight coupling solver.

Regardless, a bit more testing with different models will probably help identify the best solution.

Copy link
Copy Markdown
Collaborator

@andrew-platt andrew-platt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll be curious how much of a difference the auto-relax makes.

@andrew-platt
Copy link
Copy Markdown
Collaborator

Merge this to dev after cross-merging of rc-5.0.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants