@@ -398,10 +398,9 @@ def g2p(
398398 geoms_info : array_class .GeomsInfo ,
399399 links_state : array_class .LinksState ,
400400 rigid_global_info : array_class .RigidGlobalInfo ,
401- ) -> ti .i32 :
402- is_success = True
401+ ):
403402 for i_p , i_b in ti .ndrange (self ._n_particles , self ._B ):
404- if is_success and self .particles_ng [f , i_p , i_b ].active :
403+ if self .particles_ng [f , i_p , i_b ].active :
405404 base = ti .floor (self .particles [f , i_p , i_b ].pos * self ._inv_dx - 0.5 ).cast (gs .ti_int )
406405 fx = self .particles [f , i_p , i_b ].pos * self ._inv_dx - base .cast (gs .ti_float )
407406 w = [0.5 * (1.5 - fx ) ** 2 , 0.75 - (fx - 1.0 ) ** 2 , 0.5 * (fx - 0.5 ) ** 2 ]
@@ -433,19 +432,16 @@ def g2p(
433432 new_vel += weight * grid_vel
434433 new_C += 4 * self ._inv_dx * weight * grid_vel .outer_product (dpos )
435434
436- if not ti .math .isnan (new_vel ).any ():
437- # compute actual new_pos with new_vel
438- new_pos = self .particles [f , i_p , i_b ].pos + self .substep_dt * new_vel
435+ # compute actual new_pos with new_vel
436+ new_pos = self .particles [f , i_p , i_b ].pos + self .substep_dt * new_vel
439437
440- # impose boundary for safety, in case simulation explodes and tries to access illegal cell address
441- new_pos , new_vel = self .boundary .impose_pos_vel (new_pos , new_vel )
438+ # impose boundary for safety, in case simulation explodes and tries to access illegal cell address
439+ new_pos , new_vel = self .boundary .impose_pos_vel (new_pos , new_vel )
442440
443- # advect to next frame
444- self .particles [f + 1 , i_p , i_b ].vel = new_vel
445- self .particles [f + 1 , i_p , i_b ].C = new_C
446- self .particles [f + 1 , i_p , i_b ].pos = new_pos
447- else :
448- is_success = False
441+ # advect to next frame
442+ self .particles [f + 1 , i_p , i_b ].vel = new_vel
443+ self .particles [f + 1 , i_p , i_b ].C = new_C
444+ self .particles [f + 1 , i_p , i_b ].pos = new_pos
449445 else :
450446 self .particles [f + 1 , i_p , i_b ].vel = self .particles [f , i_p , i_b ].vel
451447 self .particles [f + 1 , i_p , i_b ].pos = self .particles [f , i_p , i_b ].pos
@@ -455,6 +451,12 @@ def g2p(
455451
456452 self .particles_ng [f + 1 , i_p , i_b ].active = self .particles_ng [f , i_p , i_b ].active
457453
454+ @ti .kernel
455+ def _is_state_valid (self , f : ti .i32 ) -> ti .i32 :
456+ is_success = True
457+ for i_p , i_b in ti .ndrange (self ._n_particles , self ._B ):
458+ if ti .math .isnan (self .particles [f , i_p , i_b ].pos ).any ():
459+ is_success = False
458460 return is_success
459461
460462 # ------------------------------------------------------------------------------------
@@ -497,13 +499,13 @@ def substep_pre_coupling_grad(self, f):
497499 self .compute_F_tmp .grad (f )
498500
499501 def substep_post_coupling (self , f ):
500- is_success = self .g2p (
502+ self .g2p (
501503 f ,
502504 self .sim .coupler .rigid_solver .geoms_info ,
503505 self .sim .coupler .rigid_solver .links_state ,
504506 self .sim .coupler .rigid_solver ._rigid_global_info ,
505507 )
506- if not is_success :
508+ if not self . _is_state_valid ( f ) :
507509 gs .raise_exception (
508510 "NaN detected in MPM states. Try reducing the time step size or adjusting simulation parameters."
509511 )
0 commit comments