Skip to content

LOOP converges on the relaxed step, so rtol is 33x looser than it reads #284

Description

@1-Bort-1

LOOP tests convergence on the relaxed step, not on the residual, so rtol is effectively rtol / relaxation_factor.

gamma_loop!'s LOOP branch forms gamma_new = (1 - relaxation_factor) * gamma + relaxation_factor * F(gamma) and then converges on max|gamma_new - gamma| / ref < rtol. That difference is relaxation_factor * (F(gamma) - gamma), so with the defaults rtol = 1e-5 and relaxation_factor = 0.03 the loop stops at a relative fixed-point residual of rtol / relaxation_factor = 3.3e-4 — 33x looser than rtol reads.

Measured on the wing test/solver/solver_test_wing.yaml builds (alpha=5.0, beta=0.0, wind_speed=10.0, 4 panels), by evaluating one unrelaxed step F(gamma) from each converged answer:

aoa LOOP max|F(g) - g| relative to max|g|
0.0° 7.69e-4 2.96e-4
5.7° 1.20e-3 3.04e-4
11.3° 1.56e-3 2.96e-4
16.7° 2.00e-3 3.07e-4
26.6° 2.82e-3 3.10e-4

The ratio is flat across the sweep, as the algebra says it should be. NONLIN, whose test is on the Newton step, lands at 1e-12 or better at all five points, and at 26.6° the two answers differ by 1.6e-4 in peak circulation (9.1063 against 9.1078) — LOOP's own error, 16x its stated rtol.

solve_base! widens it again on the retry path: a LOOP solve that misses the tolerances is re-run at relaxation_factor / 2, which halves the effective residual tolerance a second time, so the retry accepts an answer twice as loose as the attempt that "failed".

The fix is to divide the measured step by relaxation_factor before comparing it to rtol (or to converge on F(gamma) - gamma directly), which makes rtol mean what it says and makes the retry neutral. That tightens every LOOP solve in the suite by ~33x in residual, so it will move reference numbers and iteration counts and wants its own PR with the reference data re-checked — not a rider on a NONLIN fix.

Found while fixing #283; that PR changes only the NONLIN branch and leaves this alone.

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions