Skip to content

[BUG] SolverVBD particles ignore per-world gravity #3692

Description

@pietis

Bug Description

SolverVBD applies the gravity of world 0 to every dynamic particle in a multi-world model.

On current main, two particles assigned to worlds 0 and 1 with Z gravity values of -1 and -5 m/s² receive the same velocity after one 0.1 s step:

particle_world: [0, 1]
gravity_z: [-1.0, -5.0]
velocity_z: [-0.1000000089, -0.1000000089]
position_z: [-0.0100000007, -0.0100000007]

The expected Z velocities are approximately [-0.1, -0.5], with positions [-0.01, -0.05].

The particle forward_step kernel reads gravity[0] and does not receive particle_world. Its launch site likewise does not pass model.particle_world.

This prevents replicated soft-body or particle environments from using different gravity values per world. The previous VBD particle path added in #1381 selected gravity using particle_world; the current forward path introduced in #1479 no longer does so.

Expected behavior: each world-local particle uses the gravity assigned to its own world. Global particles may continue using the existing world-0 fallback convention.

Reproduction Script

import newton
from newton.solvers import SolverVBD

builder = newton.ModelBuilder()
for x in (0.0, 1.0):
    builder.begin_world()
    builder.add_particle(
        pos=(x, 0.0, 0.0),
        vel=(0.0, 0.0, 0.0),
        mass=1.0,
    )
    builder.end_world()

builder.color()
model = builder.finalize(device="cpu")
model.set_gravity((0.0, 0.0, -1.0), world=0)
model.set_gravity((0.0, 0.0, -5.0), world=1)

state_in = model.state()
state_out = model.state()
solver = SolverVBD(model)
solver.step(state_in, state_out, model.control(), None, 0.1)

print("particle_world:", model.particle_world.numpy().tolist())
print("gravity_z:", model.gravity.numpy()[:, 2].tolist())
print("velocity_z:", state_out.particle_qd.numpy()[:, 2].tolist())
print("position_z:", state_out.particle_q.numpy()[:, 2].tolist())

System Information

  • Newton: main at 402d8eac02c42243a5c9ae7e4b8f223ca8bf0394
  • Warp: 1.16.0.dev20260716
  • Python: 3.12.13
  • Device: CPU

The issue was reproduced using Warp's CPU backend. CUDA execution was not tested; the failing kernel unconditionally indexes gravity[0] without a device-specific code path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions