Skip to content

fix: Auto-compute optimal SOR omega from grid dimensions (#173)#173

Merged
shaia merged 3 commits into
masterfrom
fix/optimal-sor-omega
Mar 7, 2026
Merged

fix: Auto-compute optimal SOR omega from grid dimensions (#173)#173
shaia merged 3 commits into
masterfrom
fix/optimal-sor-omega

Conversation

@shaia
Copy link
Copy Markdown
Owner

@shaia shaia commented Mar 7, 2026

Hard-coded omega=1.5 was suboptimal for larger grids, causing Red-Black SOR to fail convergence on 33x33 grids within 1000 iterations. The optimal omega depends on the Jacobi spectral radius which varies with grid size (e.g., ~1.83 for 33x33 vs ~1.67 for 17x17).

All SOR/Red-Black SOR solvers now auto-compute optimal omega using ω = 2/(1+√(1-ρ_J²)) when the default omega=0.0 is used. Users can still override by setting params.omega > 0. Projection backends remain on CG (grid-size-independent convergence).

Hard-coded omega=1.5 was suboptimal for larger grids, causing Red-Black
SOR to fail convergence on 33x33 grids within 1000 iterations. The
optimal omega depends on the Jacobi spectral radius which varies with
grid size (e.g., ~1.83 for 33x33 vs ~1.67 for 17x17).

All SOR/Red-Black SOR solvers now auto-compute optimal omega using
ω = 2/(1+√(1-ρ_J²)) when the default omega=0.0 is used. Users can
still override by setting params.omega > 0. Projection backends remain
on CG (grid-size-independent convergence).
@shaia shaia requested a review from Copilot March 7, 2026 06:03
@shaia shaia self-assigned this Mar 7, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a convergence issue where Red-Black SOR solvers failed on 33×33 grids due to a hard-coded omega=1.5 that was suboptimal for larger grids. The solution auto-computes the optimal SOR relaxation parameter using Young's formula based on the Jacobi spectral radius, while preserving backward compatibility by allowing users to override with an explicit positive omega value.

Changes:

  • Default omega changed from 1.5 to 0.0 (sentinel for auto-compute), with poisson_solver_compute_optimal_omega() computing ω = 2/(1+√(1-ρ_J²)) from grid dimensions
  • All 6 SOR/Red-Black SOR solver backends (scalar, AVX2, NEON, OMP) updated to use poisson_solver_resolve_omega() consistently
  • New test suite (test_optimal_omega.c) validating convergence on multiple grid sizes and the explicit override mechanism

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lib/src/solvers/linear/linear_solver_internal.h Adds poisson_solver_compute_optimal_omega() and poisson_solver_resolve_omega() inline helpers
lib/src/solvers/linear/linear_solver.c Changes default omega from 1.5 to 0.0
lib/include/cfd/solvers/poisson_solver.h Updates omega field documentation and default param docstring
lib/src/solvers/linear/cpu/linear_solver_sor.c Uses poisson_solver_resolve_omega()
lib/src/solvers/linear/cpu/linear_solver_redblack.c Uses poisson_solver_resolve_omega()
lib/src/solvers/linear/avx2/linear_solver_sor_avx2.c Uses poisson_solver_resolve_omega()
lib/src/solvers/linear/avx2/linear_solver_redblack_avx2.c Uses poisson_solver_resolve_omega()
lib/src/solvers/linear/neon/linear_solver_sor_neon.c Uses poisson_solver_resolve_omega()
lib/src/solvers/linear/neon/linear_solver_redblack_neon.c Uses poisson_solver_resolve_omega()
lib/src/solvers/linear/omp/linear_solver_redblack_omp.c Uses poisson_solver_resolve_omega()
tests/math/test_optimal_omega.c New test file for auto-omega convergence and explicit override
tests/solvers/test_linear_solver.c Updates default omega assertion to 0.0
tests/math/test_omp_consistency.c Removes "known-fragile" comments, reduces max_iterations to 1000
CMakeLists.txt Registers new test executable and CTest target
ROADMAP.md Marks OMP Red-Black SOR bug as resolved with explanation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread ROADMAP.md Outdated
Comment thread lib/src/solvers/linear/linear_solver_internal.h Outdated
shaia added 2 commits March 7, 2026 08:13
The annotation said "residual history logging" but the test verifies
convergence via iteration counts, not residual logging.
When nz > 1 and dz > 0, include the z-component in the Jacobi spectral
radius formula. For 2D grids (nz <= 1 or dz <= 0) behavior is unchanged.
Previously a 3D user relying on auto-omega (omega=0.0) would get a
suboptimal 2D-only value.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@shaia shaia merged commit 0e05a35 into master Mar 7, 2026
22 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.

2 participants