Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "SimplexCellLists"
uuid = "fbe69cd6-f244-4ce4-a90b-8979d86c9ea4"
version = "0.3.0-dev"
version = "0.3.0"
authors = ["Nathan Zimmerberg"]

[workspace]
Expand Down
59 changes: 54 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,25 @@ This Julia package contains data structures and algorithms for doing computation
It provides:

- Cell lists for points ([`PointCellList`](src/pointcelllist.jl)) and line segments ([`LineSegCellList`](src/linesegcelllist.jl)) with fast nearby-neighbor mapping.
- Squared-distance functions (`dist_sqr`) for all pairs of points, line segments, and triangles.
- Neighbor list construction ([`neighbor-lists.jl`](src/neighbor-lists.jl)) with a sort and sweep broad phase.
- Soft-sphere collide forces and energy ([`collide-forces.jl`](src/collide-forces.jl)) computed from the neighbor lists.
- Squared-distance functions ([`dist_sqr`, `dist_sqr_r_s_t`](src/distances.jl)) for all pairs of points, line segments, and triangles.
- Neighbor list construction with two broad phases: a multi-level grid ([`setup_neighbors_grid!`](src/neighbor-lists-grid.jl)) and sort and sweep ([`setup_neighbors_sort_sweep!`](src/neighbor-lists.jl)).
- Soft-sphere collide forces and energy ([`collide_forces!`](src/collide-forces.jl)) computed from the neighbor lists.

This package is largely inspired by [CellListMap.jl](https://github.com/m3g/CellListMap.jl).

However, there is no support for periodic boundary conditions or 2D systems.

See [CellListMap.jl](https://github.com/m3g/CellListMap.jl) if you want these features.

## Installation

SimplexCellLists requires Julia 1.12 or later.

```julia
using Pkg
Pkg.add("SimplexCellLists")
```

## Quickstart

```julia
Expand All @@ -35,6 +44,28 @@ end

`LineSegCellList`, `cell_line_seg_add!`, and `map_nearby_line_segs` are the line segment analogs, and `cell_points_clear!`/`cell_line_segs_clear!` reset a list for reuse.

## Distances

`dist_sqr(x, y)` returns the minimum squared distance between two simplexes,
each an `SVector` of 1, 2, or 3 vertices (a point, line segment, or
triangle). `dist_sqr_r_s_t(x, y)` also returns the separation vector and the
barycentric coordinates of the closest points.

```julia
using SimplexCellLists, StaticArrays

seg = SA[SA[0.0, 0.0, 1.0], SA[1.0, 0.0, 1.0]]
tri = SA[SA[0.0, 0.0, 0.0], SA[1.0, 0.0, 0.0], SA[0.0, 1.0, 0.0]]
dist_sqr(seg, tri) # 1.0
```

The results are accurate in both `Float32` and `Float64`: with `ℓ` the
largest absolute coordinate, `√d²` is within `64*eps(T)*ℓ + floatmin(T)^(1/4)`
of the exact minimum distance, for coordinates below `floatmax(T)^(1/4)/4`
(1e9 for `Float32`). See the `dist_sqr_r_s_t` docstring for the full
contract. This bound was proven in Lean 4 by AI in
[line-segment-triangle-distance-AI-proofs](https://github.com/nhz2/line-segment-triangle-distance-AI-proofs).

## Collide forces

Neighbor lists and collide forces are configured with a `CollidePolicy`.
Expand Down Expand Up @@ -74,8 +105,26 @@ get_force(force_energy) # [-2.5, 0.0, 0.0], [2.5, 0.0, 0.0]

`NeighborListInputs` also accepts line segments (`clines`/`lines`) and
triangles, `no_collide_pairs` exclusions, and a `skin` distance so lists can be
reused across steps. `setup_neighbors_naive!` is a reference implementation of
`setup_neighbors_sort_sweep!` useful for testing.
reused across steps.

There are three ways to build the neighbor lists, which all produce the same
set of edges:

- `setup_neighbors_grid!` uses a multi-level grid. Larger objects are stored
at coarser levels and smaller objects at finer levels, so a mix of sizes
works well. The grid is sized to the number of objects, so memory use
scales with the number of objects, not the size of the system.
- `setup_neighbors_sort_sweep!` sorts the bounding boxes along the widest
axis of the system and sweeps over them.
- `setup_neighbors_naive!` checks every pair. It is a reference
implementation, useful for testing.

The last argument of `collide_forces!` is the floating-point type the forces
are computed in. Positions can be stored in `Float64` and the forces computed
in `Float32`: relative positions are subtracted in the position type before
they are converted. For multithreading, pass the `chunk` and `nthreads`
keywords and merge the per-thread results with `combine_force_energy!`, see
the `collide_forces!` docstring.

A custom policy subtypes `CollidePolicy{ObjectParams, PairParams}` with its
own parameter types and methods for `filter_object`, `filter_pair`, and
Expand Down
Loading