📡 Log Channels#

Named log streams emitted by the solver (SimpleLog / logging.push / logging.mark in the C++/Rust sources). Pull a channel out of a finished session with session.get.log.numbers(name) for (x, y) pairs or session.get.log.number(name) for the latest scalar; session.get.log.stdout() / stderr() return the raw text streams. See frontend.SessionGet.

SL-rod-toi#

Format

list[(time, ratio)]

Name

SL-rod-toi

Safety

the buffer outlives the call and names rods floats.

Description

Fraction in (0, 1] of the rescaled search direction the ROD strain limiter allows, reported separately from the shell limiter’s because a rod-only scene never marks that one. The docstring above is what makes the channel askable by name: a value that only reaches stdout ties every caller to the exact phrasing of a printed line.

SL-toi#

Format

list[(time, ratio)]

Name

Strain-Limit Time of Impact

Safety

the buffer outlives the call and names faces floats.

a limit

the barrier above raises the cost of stretching and this

question from the accepted toi below

this one says whether

Description

Fraction in (0, 1] of the rescaled search direction that can be taken without violating the configured shell or rod strain limits, as returned by the strain-limiting line search. A value of 1.0 means strain limits never bound the step, smaller values mean the strain limiter clamped it.

asm-contact#

Format

list[(time, ms)]

Name

Assembly

STEP B15a. The constraint layer

geometry outside the solved

incidental

every friction term anchors itself on the

Description

Diagnostic sub-timer of “matrix assembly”: wall-clock ms for the self-contact / collision-mesh Hessian + force assembly (the CSR fill path, including the dynamic-matrix rebuild).

asm-copy#

Format

list[(time, ms)]

Name

Assembly

snapshot boundary is where it is for a reason

moving it would change

Description

Diagnostic sub-timer of “matrix assembly”: wall-clock ms to snapshot the elastic fixed matrix into tmp_fixed (the contact-stiffness reference read by the contact assembly).

asm-elastic#

Format

list[(time, ms)]

Name

Assembly

Description

Diagnostic sub-timer of “matrix assembly”: wall-clock ms spent assembling the elastic (membrane / bending / solid) Hessian and force into the fixed matrix.

asm-strainlimit#

Format

list[(time, ms)]

Name

Assembly

go back to the state afterwards. Nothing allocates

adopt_from_dataset

Description

Diagnostic sub-timer of “matrix assembly”: wall-clock ms for the strain-limiting Hessian / force contributions.

clock#

Format

list[(time, MHz)]

Name

GPU SM Clock Speed

Description

GPU streaming-multiprocessor clock speed in MHz, sampled from nvidia-smi once per simulation step. Useful for correlating slow steps with thermal or power-related clock throttling on the device.

dt#

Format

list[(time, seconds)]

Name

Target Step Size

Description

Target integration step size in seconds at the start of this simulation step, computed as the configured dt scaled by the current playback rate. The actually advanced step size can be smaller (see the Final Step Size channel) if the line search reduces it.

final-dt#

Format

list[(time, seconds)]

Name

Final Step Size

Description

Step size in seconds that was actually integrated this simulation step. In easy cases this matches the target dt, but it is reduced by the advanced TOI fraction when contacts or strain limits shorten the step, and can also be reduced when enable_retry is on and the PCG solve fails.

frame-to-time#

Format

list[(frame, seconds)]

Name

Video Frame to Simulation Time Map

Description

Pairs of (video frame index, simulation time in seconds) emitted once per output frame. Lets you look up which simulation time each output frame corresponds to, which is useful when the playback rate varies over time.

initial-check-intersection#

Format

list[(time, ms)]

Name

Initial Intersection Check Time

Description

Wall-clock time in milliseconds spent scanning the previous and current vertex positions for self-intersections at the start of the simulation. Only a single record is expected. Useful for diagnosing geometry that begins the simulation already tangled.

initial-lbvh-build#

AGAINST THEM

rebuild_trees below fits every BVH to vertex.curr,

Format

list[(time, ms)]

Name

Initial LBVH Build Time

Safety

both CVec`s hold `vertices position triples, and the device

THE ANALYTIC COLLIDER LAYER, allocated on every scene

a sphere and a

The masks are not applied here

the collision window table may not

gate REFUSES a scene

tightening it here declines scenes that are

Description

Wall-clock time in milliseconds to build the initial LBVH (Linear Bounding Volume Hierarchy) over faces, edges, and vertices at the start of the simulation, including the collision-mesh BVH. Only a single record is expected.

initialize#

Format

list[(time, ms)]

Name

Initialization Time

Description

Total wall-clock time in milliseconds spent inside the one-time solver initialization (buffer allocation, contact setup, initial LBVH build, initial intersection check). Only a single record is expected, written when the initialize scope exits. The leading time column is the simulation time at the moment of recording, which is 0 for initialization.

lbvh-build#

Format

list[(time, ms)]

Name

LBVH Build Time

pose, not merely refreshed

the Morton order is recomputed, so the tree’s

Description

Wall-clock time in milliseconds to rebuild the LBVH (Linear Bounding Volume Hierarchy) over faces, edges, and vertices at the start of each simulation step. This BVH underpins broad-phase contact detection, so this cost tracks mesh size and how often primitives are deactivated by collision windows.

matrix-assembly#

Format

list[(time, ms)]

Name

Matrix Assembly Time

Description

Wall-clock time in milliseconds spent assembling the global system matrix and right-hand side for the Newton linear solve, including inertia, elastic, stitch, strain-limiting, and contact contributions. One entry per Newton iteration. CLOSED AFTER num_contact AND NOT BEFORE IT, which is what puts > matrix_assembly below * num_contact in the stream.

max-search-dir#

Format

list[(time, meters)]

Name

Max Search Direction Magnitude

Safety

the buffer outlives the call and names vertices floats.

Description

Maximum per-vertex magnitude (L2 norm) of the Newton search direction returned by the linear solve for this Newton iteration, in meters. Compared against the max_dx parameter to decide whether the search direction must be rescaled before the line search.

max-sigma#

Format

list[(time, ratio)]

Name

Max Stretch Ratio

Safety

both buffers outlive the calls and name their counts.

the start-of-step pose. Telemetry rather than a term of the solve

nothing

Description

Maximum stretch ratio among all shell faces and rod edges in the scene, measured at the start of the step before the Newton loop. For shells this is the largest singular value of the deformation gradient (scaled by the shrink factor), for rods it is the current edge length divided by its rest length. A value of 1.02 means a 2 percent stretch. Useful for diagnosing strain-limit tightness.

max-velocity#

Format

list[(time, m/s)]

LEAVING THE DOMAIN IS NOT CAUGHT ANYWHERE ELSE

the overflow guards

Name

Max Vertex Velocity

Safety

both buffers outlive the calls and name vertices floats.

Description

Maximum speed (in meters per second) among all non-pinned vertices, measured from the previous to the current positions at the start of the step. Pinned (fixed) vertices are excluded. Useful for spotting explosions or abrupt motion in the simulation.

newton-steps#

Format

list[(time, iterations)]

Name

Newton Iteration Count

Description

Number of Newton iterations consumed in this simulation step (before the trailing error-reduction iteration). Values above the configured min_newton_steps indicate the solver needed extra iterations to reach the target advanced step size.

num-contact#

Format

list[(time, count)]

Name

Total Contact Count

the advance here, and the report is a HOST CONTRACT

the kind

Description

Total number of active contact and constraint pairs assembled into the system matrix for this Newton iteration, summed across self-contact, collision-mesh contact, and analytic constraints (sphere, floor). A useful proxy for how crowded the collision scene is at this iteration.

pcg-iter#

Format

list[(time, iterations)]

Name

Linear Solve Iteration Count

Description

Number of preconditioned conjugate gradient (PCG) iterations consumed during the linear solve for this Newton iteration. High values indicate an ill-conditioned system or a tight tolerance and often correlate with long linear-solve times.

pcg-linsolve#

Format

list[(time, ms)]

Name

Linear Solve Time

Description

Wall-clock time in milliseconds spent in the preconditioned conjugate gradient (PCG) linear solve for the Newton step direction. One entry per Newton iteration. Typically the dominant per-iteration cost. RECORDED BEFORE THE VERDICT IS READ, because the scope closes before the outcome is tested: a solve that ran to the iteration cap still spent the time it spent, and dropping the row there would leave the stream shortest exactly where it is most worth reading. A ? inside a branch above escapes without this row, and that path is a Fatal that ends the run rather than a failed step.

pcg-resid#

Format

list[(time, ratio)]

Name

Linear Solve Relative Residual

Description

Final relative residual reached by the PCG linear solve for this Newton iteration. When this stays well below the configured tolerance, the solve converged cleanly, values close to the tolerance indicate the iteration cap was hit. In a scene with rigid (PDRD) bodies the reduced solve measures each degree-of-freedom group against its own initial residual, and this reports the worst group, so a body and the cloth cannot mask each other.

playback#

Format

list[(time, ratio)]

Name

Playback Speed

Description

Playback rate applied this step, as a multiplier on the configured dt. A value of 1.0 means real-time playback, below 1.0 slows motion down, and above 1.0 speeds it up. The value can change between steps when the scene scripts playback over time.

schwarz-fallback#

Format

list[(time, count)]

Name

Schwarz Block-Jacobi Fallback

Description

1 if the solver fell back from the Schwarz preconditioner to the SPD-safe block-Jacobi base for this Newton iteration’s PCG solve, else 0. Always 0 under the block-jacobi preconditioner; a nonzero entry is worth reviewing. Recorded every iteration but only printed when nonzero so the common 0 case does not clutter the log. A STRUCTURAL ZERO HERE, NOT AN UNMEASURED ONE, which is why it is quiet rather than a number whose print is decided per iteration. Two things could raise it and this driver has neither: there is no memory guard that degrades Schwarz to block-Jacobi, and schwarz.rs builds its aggregate term so the rz <= 0 breakdown cannot arise. The channel is recorded so a reader asking for it by name gets an answer, and the day a degrade path is added this becomes a Number and starts printing.

time-per-frame#

/ interpolated

see pin_at_frame below.

Format

list[(frame, ms)]

Name

Time Per Video Frame

Description

Wall-clock time in milliseconds elapsed between producing the previous output video frame and this one. Because each simulation step can advance less than one frame’s worth of time, this aggregates however many solver steps were needed to cross the frame boundary.

time-per-step#

Format

list[(time, ms)]

Name

Time Per Simulation Step

Description

Wall-clock time in milliseconds spent inside a single advance call (one simulation step). Note that a step does not advance by a fixed dt: the actual step size is reduced by the accumulated time of impact found during the inner Newton loop, so these values also reflect how hard the solver had to work to progress the step.

toi#

Format

list[(time, ratio)]

Name

Line Search Time of Impact

Description

Fraction in (0, 1] of the rescaled Newton search direction that can be taken without causing a collision or violating strain limits, as the minimum of the contact CCD result and the strain-limit TOI. A value of 1.0 means the full Newton step was accepted, smaller values mean the line search cut it short.

toi-advanced#

Format

list[(time, ratio)]

Name

Advanced Fractional Step Size

Description

Fraction in (0, 1] of the target step size that the Newton loop actually advanced, accumulated across all its iterations. The final Final Step Size equals this fraction times the target dt. A value of 1.0 means the full target step completed, smaller values mean contacts or strain limits forced a partial step.

toi-recale#

Format

list[(time, ratio)]

Name

Search Direction Rescale Factor

Description

Scalar in (0, 1] applied to the Newton search direction before the line search, so that no per-vertex displacement exceeds the configured max_dx. A value of 1.0 means the direction was already within budget, smaller values clamp an over-eager step.