newton.solvers.SolverVBD#

class newton.solvers.SolverVBD(model, iterations=10, friction_epsilon=1e-2, integrate_with_external_rigid_solver=False, particle_enable_self_contact=False, particle_self_contact_radius=0.2, particle_self_contact_margin=0.2, particle_conservative_bound_relaxation=0.42, particle_vertex_contact_buffer_size=32, particle_edge_contact_buffer_size=64, particle_collision_detection_interval=0, particle_edge_parallel_epsilon=1e-5, particle_enable_tile_solve=True, particle_topological_contact_filter_threshold=2, particle_rest_shape_contact_exclusion_radius=0.0, particle_external_vertex_contact_filtering_map=None, particle_external_edge_contact_filtering_map=None, rigid_avbd_beta=1.0e5, rigid_avbd_gamma=0.99, rigid_contact_k_start=1.0e2, rigid_joint_linear_k_start=1.0e4, rigid_joint_angular_k_start=1.0e1, rigid_body_contact_buffer_size=64, rigid_body_particle_contact_buffer_size=256, rigid_enable_dahl_friction=False, rigid_dahl_eps_max=0.5, rigid_dahl_tau=1.0)[source]#

Bases: SolverBase

An implicit solver using Vertex Block Descent (VBD) for particles and Augmented VBD (AVBD) for rigid bodies.

This unified solver supports:
  • Particle simulation (cloth, soft bodies) using the VBD algorithm

  • Rigid body simulation (joints, contacts) using the AVBD algorithm

  • Coupled particle-rigid body systems

For rigid bodies, the AVBD algorithm uses soft constraints with adaptive penalty parameters for joints and contacts. Hard constraints are not currently enforced.

References

  • Anka He Chen, Ziheng Liu, Yin Yang, and Cem Yuksel. 2024. Vertex Block Descent. ACM Trans. Graph. 43, 4, Article 116 (July 2024), 16 pages. https://doi.org/10.1145/3658179

Note

SolverVBD requires coloring information for both particles and rigid bodies:

Call newton.ModelBuilder.color() to automatically color both particles and rigid bodies.

Example

# Automatically color both particles and rigid bodies
builder.color()

model = builder.finalize()

solver = newton.solvers.SolverVBD(model)

# Initialize states and contacts
state_in = model.state()
state_out = model.state()
control = model.control()
contacts = model.collide(state_in)

# Simulation loop
for i in range(100):
    contacts = model.collide(state_in)  # Update contacts
    solver.step(state_in, state_out, control, contacts, dt)
    state_in, state_out = state_out, state_in
__init__(model, iterations=10, friction_epsilon=1e-2, integrate_with_external_rigid_solver=False, particle_enable_self_contact=False, particle_self_contact_radius=0.2, particle_self_contact_margin=0.2, particle_conservative_bound_relaxation=0.42, particle_vertex_contact_buffer_size=32, particle_edge_contact_buffer_size=64, particle_collision_detection_interval=0, particle_edge_parallel_epsilon=1e-5, particle_enable_tile_solve=True, particle_topological_contact_filter_threshold=2, particle_rest_shape_contact_exclusion_radius=0.0, particle_external_vertex_contact_filtering_map=None, particle_external_edge_contact_filtering_map=None, rigid_avbd_beta=1.0e5, rigid_avbd_gamma=0.99, rigid_contact_k_start=1.0e2, rigid_joint_linear_k_start=1.0e4, rigid_joint_angular_k_start=1.0e1, rigid_body_contact_buffer_size=64, rigid_body_particle_contact_buffer_size=256, rigid_enable_dahl_friction=False, rigid_dahl_eps_max=0.5, rigid_dahl_tau=1.0)#
Parameters:
  • model (Model) – The Model object used to initialize the integrator. Must be identical to the Model object passed to the step function.

  • parameters (Rigid body)

  • iterations (int) – Number of VBD iterations per step.

  • friction_epsilon (float) – Threshold to smooth small relative velocities in friction computation (used for both particle and rigid body contacts).

  • parameters

  • particle_enable_self_contact (bool) – Whether to enable self-contact detection for particles.

  • particle_self_contact_radius (float) – The radius used for self-contact detection. This is the distance at which vertex-triangle pairs and edge-edge pairs will start to interact with each other.

  • particle_self_contact_margin (float) – The margin used for self-contact detection. This is the distance at which vertex-triangle pairs and edge-edge will be considered in contact generation. It should be larger than particle_self_contact_radius to avoid missing contacts.

  • integrate_with_external_rigid_solver (bool) – Indicator for coupled rigid body-cloth simulation. When set to True, the solver assumes rigid bodies are integrated by an external solver (one-way coupling).

  • particle_conservative_bound_relaxation (float) – Relaxation factor for conservative penetration-free projection.

  • particle_vertex_contact_buffer_size (int) – Preallocation size for each vertex’s vertex-triangle collision buffer.

  • particle_edge_contact_buffer_size (int) – Preallocation size for edge’s edge-edge collision buffer.

  • particle_collision_detection_interval (int) – Controls how frequently particle self-contact detection is applied during the simulation. If set to a value < 0, collision detection is only performed once before the initialization step. If set to 0, collision detection is applied twice: once before and once immediately after initialization. If set to a value n >= 1, collision detection is applied before every n VBD iterations.

  • particle_edge_parallel_epsilon (float) – Threshold to detect near-parallel edges in edge-edge collision handling.

  • particle_enable_tile_solve (bool) – Whether to accelerate the particle solver using tile API.

  • particle_topological_contact_filter_threshold (int) – Maximum topological distance (measured in rings) under which candidate self-contacts are discarded. Set to a higher value to tolerate contacts between more closely connected mesh elements. Only used when particle_enable_self_contact is True. Note that setting this to a value larger than 3 will result in a significant increase in computation time.

  • particle_rest_shape_contact_exclusion_radius (float) – Additional world-space distance threshold for filtering topologically close primitives. Candidate contacts with a rest separation shorter than this value are ignored. The distance is evaluated in the rest configuration conveyed by model.particle_q. Only used when particle_enable_self_contact is True.

  • particle_external_vertex_contact_filtering_map (dict | None) – Optional dictionary used to exclude additional vertex-triangle pairs during contact generation. Keys must be vertex primitive ids (integers), and each value must be a list or set containing the triangle primitives to be filtered out. Only used when particle_enable_self_contact is True.

  • particle_external_edge_contact_filtering_map (dict | None) – Optional dictionary used to exclude additional edge-edge pairs during contact generation. Keys must be edge primitive ids (integers), and each value must be a list or set containing the edges to be filtered out. Only used when particle_enable_self_contact is True.

  • parameters

  • rigid_avbd_beta (float) – Penalty ramp rate for rigid body constraints (how fast k grows with constraint violation).

  • rigid_avbd_gamma (float) – Warmstart decay for penalty k (cross-step decay factor for rigid body constraints).

  • rigid_contact_k_start (float) – Initial penalty stiffness for all body contact constraints, including both body-body (rigid-rigid) and body-particle (rigid-particle) contacts (AVBD).

  • rigid_joint_linear_k_start (float) – Initial penalty seed for linear joint DOFs (e.g., cable stretch). Used to seed the per-DOF adaptive penalties for all linear joint constraints.

  • rigid_joint_angular_k_start (float) – Initial penalty seed for angular joint DOFs (e.g., cable bend). Used to seed the per-DOF adaptive penalties for all angular joint constraints.

  • rigid_body_contact_buffer_size (int) – Max body-body (rigid-rigid) contacts per rigid body for per-body contact lists (tune based on expected body-body contact density).

  • rigid_body_particle_contact_buffer_size (int) – Max body-particle (rigid-particle) contacts per rigid body for per-body soft-contact lists (tune based on expected body-particle contact density).

  • rigid_enable_dahl_friction (bool) – Enable Dahl hysteresis friction model for cable bending (default: False).

  • rigid_dahl_eps_max (float | array) – Maximum persistent strain (curvature) [rad] for Dahl friction model. Can be: - float: Same value for all joints - array: Per-joint values for heterogeneous cables

  • rigid_dahl_tau (float | array) – Memory decay length [rad] for Dahl friction model. Controls plasticity. Can be: - float: Same value for all joints - array: Per-joint values

Note

  • The integrate_with_external_rigid_solver argument enables one-way coupling between rigid body and soft body solvers. If set to True, the rigid states should be integrated externally, with state_in passed to step representing the previous rigid state and state_out representing the current one. Frictional forces are computed accordingly.

  • particle_vertex_contact_buffer_size, particle_edge_contact_buffer_size, rigid_body_contact_buffer_size, and rigid_body_particle_contact_buffer_size are fixed and will not be dynamically resized during runtime. Setting them too small may result in undetected collisions (particles) or contact overflow (rigid body contacts). Setting them excessively large may increase memory usage and degrade performance.

compute_rigid_force_element_adjacency(model)#

Build CSR adjacency between rigid bodies and joints.

Returns an instance of RigidForceElementAdjacencyInfo with:
  • body_adj_joints: flattened joint ids

  • body_adj_joints_offsets: CSR offsets of size body_count + 1

Notes

  • Runs on CPU to avoid GPU atomics; kernels iterate serially over joints (dim=1).

  • When there are no joints, offsets are an all-zero array of length body_count + 1.

finalize_particles(state_out, dt)#

Finalize particle velocities after VBD iterations.

finalize_rigid_bodies(state_out, dt)#

Finalize rigid body velocities and Dahl friction state after AVBD iterations (post-iteration phase).

Updates rigid body velocities using BDF1 and updates Dahl hysteresis state for cable bending.

initialize_particles(state_in, dt)#

Initialize particle positions for the VBD iteration.

initialize_rigid_bodies(state_in, contacts, dt, update_rigid_history)#

Initialize rigid body states for AVBD solver (pre-iteration phase).

Performs forward integration, builds contact lists, and warmstarts AVBD penalty parameters.

rebuild_bvh(state)#

This function will rebuild the BVHs used for detecting self-contacts using the input state.

When the simulated object deforms significantly, simply refitting the BVH can lead to deterioration of the BVH’s quality. In these cases, rebuilding the entire tree is necessary to achieve better querying efficiency.

Parameters:

state (newton.State) – The state whose particle positions (State.particle_q) will be used for rebuilding the BVHs.

set_rigid_history_update(update)#

Set whether the next step() should update rigid solver history (warmstarts).

This setting applies only to the next call to step() and is then reset to True. This is useful for substepping, where history update frequency might differ from the simulation step frequency (e.g. updating only on the first substep).

Parameters:

update (bool) – If True, update rigid warmstart state. If False, reuse previous.

solve_particle_iteration(state_in, state_out, contacts, dt, iter_num)#

Solve one VBD iteration for particles.

solve_rigid_body_iteration(state_in, state_out, contacts, dt)#

Solve one AVBD iteration for rigid bodies (per-iteration phase).

Accumulates contact and joint forces/hessians, solves 6x6 rigid body systems per color, and updates AVBD penalty parameters (dual update).

step(state_in, state_out, control, contacts, dt)#

Execute one simulation timestep using VBD (particles) and AVBD (rigid bodies).

The solver follows a 3-phase structure: 1. Initialize: Forward integrate particles and rigid bodies, detect collisions, warmstart penalties 2. Iterate: Interleave particle VBD iterations and rigid body AVBD iterations 3. Finalize: Update velocities and persistent state (Dahl friction)

To control rigid substepping behavior (warmstart history), call set_rigid_history_update() before calling this method. It defaults to True and is reset to True after each call.

Parameters:
  • state_in (State) – Input state.

  • state_out (State) – Output state.

  • control (Control) – Control inputs.

  • contacts (Contacts) – Collision contacts.

  • dt (float) – Time step size.