Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions demo/demo_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@

mpm.set_gravity((0, -50, 0))

mpm.add_wind_field(
lower_bound=[0, 0, 0],
upper_bound=[3, 10, 10],
force=[200, 0, 0]
)

for frame in range(1500):
mpm.step(4e-3)
colors = np.array([0x068587, 0xED553B, 0xEEEEF0, 0xFFFF00],
Expand Down
20 changes: 20 additions & 0 deletions engine/mpm_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,26 @@ def set_gravity(self, g):
assert len(g) == self.dim
self.gravity[None] = g

def add_wind_field(self, lower_bound, upper_bound, force):
lower_bound = list(lower_bound)
upper_bound = list(upper_bound)
force = list(force)
assert len(lower_bound) == self.dim
assert len(upper_bound) == self.dim
assert len(force) == self.dim

@ti.kernel
def apply_wind(t: ti.f32, dt: ti.f32, grid_v: ti.template()):
for I in ti.grouped(grid_v):
grid_pos = I * self.dx
inside = True
for d in ti.static(range(self.dim)):
inside = inside and (lower_bound[d] <= grid_pos[d] < upper_bound[d])
if inside:
grid_v[I] += dt * ti.Vector(force)

self.grid_postprocess.append(apply_wind)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wind postprocessor overrides bounding box boundary conditions

Medium Severity

The wind postprocessor is appended to grid_postprocess after the bounding box (which is always the first element, added in __init__). During each substep, the bounding box runs first and zeroes out boundary-violating velocities, but then apply_wind adds velocity back, potentially in the outward direction. Unlike existing colliders which only reduce or project velocity, wind adds velocity, so it can override the bounding box constraint and allow particles to escape the simulation domain.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e333388. Configure here.


@ti.func
def sand_projection(self, sigma, p):
sigma_out = ti.Matrix.zero(ti.f32, self.dim, self.dim)
Expand Down