Skip to content

Make find_steady_state! for KPS3 find a real equilibrium - #331

Merged
ufechner7 merged 3 commits into
mainfrom
kps3-steady-state
Oct 10, 2026
Merged

ufechner7 merged 3 commits into
mainfrom
kps3-steady-state

Conversation

@ufechner7

Copy link
Copy Markdown
Member

Problem

The steady-state solver of KPS3 almost never found an equilibrium. nlsolve reported "converged" only because its steps became tiny (x_converged). The accelerations of the tether particles were still about 25 m/s², and the tether stayed nearly straight. On some machines (e.g. the GitHub runners) one of the two passes ran into the 1000-iteration limit and printed:

Warning: find_steady_state!: solver did not converge! (f_converged=false, x_converged=false, iterations=1000)

Causes:

  • Bad conditioning: the unknowns were Cartesian offsets of the particle positions. The Jacobian had 6 large singular values (~1e5, stretching the segments) and 6 tiny ones (0.1–1, rotating them), so plain Newton steps diverged.
  • Kink at the start: the solver started from the unstretched tether, exactly at the kink of the spring force between tension and compression.
  • Over-determined kite: the kite can only be fully balanced at its natural elevation, which can be far from set.elevation.

Change

  • New unknowns: the angles of the tether segments relative to the elevation angle and their relative stretches. They are converted to the offsets that init uses.
  • Start point: the solver starts from a straight tether stretched by 0.1%.
  • Prescribed elevation (as for KPS4 in 0.11.18): the elevation of the kite is prescribed instead of its vertical force balance. The tether particles (x and z) and the horizontal balance of the kite are solved to ftol = 1e-6, and calc_elevation(s) returns set.elevation.
  • Independent of upwind_dir: the horizontal residuals and positions are taken in the plane of the tether.
  • Fallback: if the pass with reduced stiffness fails, the full-stiffness pass starts again from the straight tether. A warning is printed only if the final pass fails.
  • CHANGELOG entry under 0.11.19 (still unreleased).

The initial state changes. For the 392 m case in test-kps3.jl the kite now starts at 70.0° instead of its natural elevation of 64.3°, so the expected tether length, forces and lift/drag are updated.

Tests

  • test_find_steady_state now checks that no warning is logged, the elevation, and that the tether particles and the kite's horizontal balance are in equilibrium. It no longer skips failures on CI. With the old solver, 6 of its tests fail.
  • Full suite locally (Julia 1.13): 651 passed, 11 broken (existing @test_broken).
  • The solver converges, with the elevation exactly as configured, for: system.yaml; the 392 m case; upwind_dir 0°, 45°, 180°; v_wind 3, 6.5, 12, 20 m/s; elevation 20°, 45°, 85°; 12 segments. Before, elevation 20°/45° and v_wind 20 m/s did not converge.
  • A 20 s simulation with system.yaml and with the parking_1p settings of KiteControllers.jl behaves like before.

🤖 Generated with Claude Code

nlsolve usually stopped because its steps became tiny, with the
accelerations of the tether particles still at about 25 m/s^2, and on some
machines it printed 'solver did not converge'. The Cartesian offsets made
the system badly conditioned (stiff stretching modes, soft rotation
modes), the start at zero stretch sat on the kink of the spring force, and
the kite can only be fully balanced at its natural elevation.

Now the unknowns are the angles and relative stretches of the segments,
the solver starts from a slightly stretched tether, and, as for KPS4, the
elevation of the kite is prescribed instead of its vertical force balance.
The horizontal residuals are taken in the plane of the tether, so the
result does not depend on upwind_dir. If the pass with reduced stiffness
fails, the full-stiffness pass starts again from the straight tether.

The test of find_steady_state! now checks the equilibrium, the elevation
and that no warning is printed, and no longer skips failures on CI.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The advertised direction-independent equilibrium behavior lacks automated coverage for non-default wind directions.

1 open finding
What changed in this PR

Improves KPS3 steady-state initialization by using better-conditioned segment angles and stretches while prescribing kite elevation.

Changes:

  • Reworks equilibrium variables, convergence handling, and fallback behavior.
  • Updates KPS3 equilibrium assertions and expected initial-state values.
  • Documents the corrected initialization behavior.
File Description
src/​KPS3.jl Implements the revised steady-state solver.
test/​test-kps3.jl Updates equilibrium tests and expected values.
CHANGELOG.md Describes the solver correction.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/test-kps3.jl
ufechner7 and others added 2 commits October 10, 2026 17:30
Checks the equilibrium in the plane of the tether for upwind_dir = -π/2,
0, π/4 and π, so that a sign error in the coordinate transform of
find_steady_state_inner is detected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
https://doi.org/10.5281/zenodo.13310253 redirects to zenodo.org, which
takes about 20 s to answer, the default timeout of lychee, so the link
checker failed with a timeout on most runs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ufechner7
ufechner7 merged commit 8d4aa9b into main Oct 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants