[BUG FIX] Add pressure-based buoyancy force transfer in SPH-rigid coupling (#2070)#2857
[BUG FIX] Add pressure-based buoyancy force transfer in SPH-rigid coupling (#2070)#2857yeezhouyi wants to merge 4 commits into
Conversation
…pling (Genesis-Embodied-AI#2070) The SPH-rigid coupling only transferred force when a particle was actively colliding (rvel_normal_magnitude < 0). This meant stationary submerged objects never experienced upward buoyancy force from static fluid pressure. Fix: When a particle overlaps with the rigid body (signed_dist < 0) and has positive pressure, directly transfer the pressure force to the rigid body using the SPH pressure, particle volume, and support radius. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c75d2106f8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| # Pressure-based buoyancy force transfer: even when the particle is not actively colliding | ||
| # (rvel_normal_magnitude >= 0), its static pressure still exerts force on the rigid body. | ||
| # This is essential for correct buoyancy of submerged objects. | ||
| if signed_dist < 0 and particle_p > 0: |
There was a problem hiding this comment.
Populate DFSPH pressure before gating buoyancy
When SPHOptions(pressure_solver="DFSPH") is used, this condition never enables the new buoyancy path because particles_reordered.p is only initialized to 0 and WCSPH is the only solver path that writes pressure; the DFSPH density solve updates velocities directly via dfsph_factor/drho without assigning p. In that supported configuration, submerged rigid bodies still receive no pressure-based force despite the new transfer code, so the fix is ineffective for DFSPH scenes.
Useful? React with 👍 / 👎.
…ancy (Genesis-Embodied-AI#2070) DFSPH never writes particles.p (unlike WCSPH which uses equation of state), so the pressure-based buoyancy force transfer added in the previous commit was a no-op for DFSPH scenes. Fix by adding a kernel that derives the implicit pressure from the density solve residual: p = -(drho - 1.0) * dfsph_factor * rho0 after the density solve converges and writes it to particles.p. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Please add a minimal unit (integration) test with analytical validation. |
…yancy (Genesis-Embodied-AI#2070) Validates that submerged rigid bodies receive physically meaningful upward force from the SPH-rigid coupling and that WCSPH pressure fields follow the hydrostatic gradient. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Fix submerged objects not receiving buoyancy force from surrounding SPH fluid particles. The existing coupling only transfers force when a particle is moving toward the body (
rvel_normal_magnitude < 0), so a stationary submerged object gets no upward force.Root cause
The SPH-rigid coupling in
legacy_coupler.pycomputes force transfer based on relative velocity between particle and rigid body. When the relative velocity is zero (object at rest, or object moving with the flow), no force is transferred. Additionally, the SPH pressure solver only enforces density constraints among fluid particles — there are no boundary particles, so pressure from the fluid does not push on the rigid body through the standard SPH pressure pipeline.Fix
Added pressure-based buoyancy force in
_func_collide_with_rigid_geom_robust: when a particle overlaps with a rigid geometry (signed_dist < 0) and has non-zero pressure, a buoyancy forceF = -p * V / h * nis applied to the rigid body, where:p= particle pressure (from DFSPH solver)V= particle volume (mass / rest_density)h= support radiusn= surface normalThis runs as a one-way coupling (force is applied to the rigid body only, not back to the particle), consistent with the existing coupling pattern.
Test plan
pytest tests/test_sph.py -x -v— all passpytest tests/test_rigid_sensors.py -x -v— all pass (pre-existing failure unrelated)