# cleanRats Removes rattlers (unstable particles) from a packing by iterative contact counting. In each pass it recomputes the wall lists and the per-particle coordination number `Zn` (number of overlapping neighbors, with periodic minimum-image distances), drops every particle below the isostatic coordination threshold, and repeats until the set is stable. Removal threshold (`Zn` must be **greater than** it to survive): | Case | Keep | |---|---| | 2D, frictionless | `Zn > 2` | | 3D (any friction) | `Zn > 3` | | Frictional (`mu > 0`) | `Zn > 1` | Physics (Maxwell counting, 2D disks): frictionless isostatic `z_iso = 4`, frictional `z_iso = 3`. A particle with `Zn <= 1` cannot satisfy force–torque balance in this gravity-free isotropic packing, so it is a rattler even with friction; the frictional variant therefore keeps `Zn >= 2` backbone grains and removes floaters plus one-contact rattlers. ## Default Syntax ```matlab % 2D, PBC in y only, frictionless [positions, radii] = cleanRats(positions, radii, Ly, Lx) % 3D, PBC in y and z, frictionless [positions, radii] = cleanRats(positions, radii, Ly, Lx, Lz) ``` ## Full Argument List ```matlab [positions, radii] = cleanRats(positions, radii, Ly, Lx, Lz, boolFullyPeriodic, mu) ``` | Arg | Type | Meaning | |---|---|---| | `positions` | `[N x 2]` or `[N x 3]` | Particle positions (x, y[, z]) | | `radii` | `[N x 1]` | Particle radii | | `Ly` | double | Box extent in y (PBC applied in y always) | | `Lx` | double | Box extent in x | | `Lz` | double or `[]` | Box extent in z; pass `[]` for a 2D call | | `boolFullyPeriodic` | logical | 3D only: apply PBC in x as well as y/z. 2D: ignored (no x-PBC). Defaults false when omitted | | `mu` | double | Friction coefficient; `> 0` switches to the frictional threshold (`Zn > 1`). Defaults 0 | All existing callers omit `mu` (so the frictionless behavior is unchanged). The returned `positions`/`radii` contain only the surviving backbone particles. ## Examples ```matlab % 2D packing, periodic in y only positions = [x; y]'; % N x 2 radii = Dn / 2; [positions, radii] = cleanRats(positions, radii, Ly, Lx); % 2D packing, fully periodic in x and y [positions, radii] = cleanRats(positions, radii, Ly, Lx, [], true); % 3D packing, fully periodic [positions, radii] = cleanRats(positions, radii, Ly, Lx, Lz, true); % Frictional 2D (mu > 0) — keeps Zn >= 2, removes floaters + 1-contact rattlers [positions, radii] = cleanRats(positions, radii, Ly, Lx, [], false, 0.5); ``` `pack` and `processEigenModesDampedPara` call this internally; you normally do not call it directly unless cleaning a packing you generated elsewhere.