From f872a2fe84182a7f8bd565b22bc7a7fcd6ee1851 Mon Sep 17 00:00:00 2001 From: nhz2 Date: Tue, 11 Aug 2026 23:59:09 +0200 Subject: [PATCH] rename CollisionPolicy to CollidePolicy --- README.md | 8 +++---- benchmark/ring-neighbor-bench.jl | 2 +- src/SimplexCellLists.jl | 12 +++++------ src/collide-forces.jl | 22 +++++++++---------- src/neighbor-lists.jl | 36 ++++++++++++++++---------------- test/test-collide-forces.jl | 4 ++-- test/test-neighbor-lists.jl | 2 +- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index ad0bb70..30e5069 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,13 @@ end ## Collide forces -Neighbor lists and collide forces are configured with a `CollisionPolicy`. +Neighbor lists and collide forces are configured with a `CollidePolicy`. The policy decides which objects and pairs participate in the neighbor lists (`filter_object`, `filter_pair`), how per-object parameters combine into per-pair parameters (`mix_params`), and which force law applies to each edge (`nl_edge_forces!`). -`DefaultCollisionPolicy` stores a stiffness and collision layer masks per +`DefaultCollidePolicy` stores a stiffness and collision layer masks per object, and applies a soft repulsive potential `E = k/2 * (L - d)²` when two objects overlap, where `L` is the sum of the two radii and `d` is the closest distance between them. The pair stiffness `k` mixes the two per-object @@ -53,7 +53,7 @@ stiffnesses like springs in series, `k = k₁*k₂/(k₁ + k₂)`, so the two ```julia using SimplexCellLists, StaticArrays -policy = DefaultCollisionPolicy() +policy = DefaultCollidePolicy() # Two overlapping spheres: radius 0.5, centers 0.5 apart pos = [SA[0.0, 0.0, 0.0], SA[0.5, 0.0, 0.0]] @@ -77,7 +77,7 @@ 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. -A custom policy subtypes `CollisionPolicy{ObjectParams, PairParams}` with its +A custom policy subtypes `CollidePolicy{ObjectParams, PairParams}` with its own parameter types and methods for `filter_object`, `filter_pair`, and `mix_params`, and can define its own `nl_edge_forces!` methods to change the force law. diff --git a/benchmark/ring-neighbor-bench.jl b/benchmark/ring-neighbor-bench.jl index 538fc0a..b0c60a3 100644 --- a/benchmark/ring-neighbor-bench.jl +++ b/benchmark/ring-neighbor-bench.jl @@ -40,7 +40,7 @@ for k in 1:length(clines)-1 end end -policy = DefaultCollisionPolicy() +policy = DefaultCollidePolicy() inputs = NeighborListInputs(policy; clines, c_radius = fill(radius, length(clines)), diff --git a/src/SimplexCellLists.jl b/src/SimplexCellLists.jl index 5b3d899..071917e 100644 --- a/src/SimplexCellLists.jl +++ b/src/SimplexCellLists.jl @@ -99,13 +99,13 @@ export CollidePairs export N_COLLIDE_PAIRS export empty_no_collide_pairs export CollideObjectTypes -public CollisionPolicy +public CollidePolicy public filter_object public filter_pair public mix_params export DefaultObjectParams export DefaultPairParams -export DefaultCollisionPolicy +export DefaultCollidePolicy export NeighborListInputs export NeighborLists export is_neighbor_list_subset @@ -113,9 +113,9 @@ export setup_neighbors_naive! export setup_neighbors_sort_sweep! # Precompile the neighbor list builds for the default policy -precompile(NeighborLists, (DefaultCollisionPolicy,)) -let NL = NeighborLists{DefaultCollisionPolicy, DefaultPairParams}, - Inputs = NeighborListInputs{DefaultCollisionPolicy, DefaultObjectParams} +precompile(NeighborLists, (DefaultCollidePolicy,)) +let NL = NeighborLists{DefaultCollidePolicy, DefaultPairParams}, + Inputs = NeighborListInputs{DefaultCollidePolicy, DefaultObjectParams} for T in (Float32, Float64) for Pos in ( Vector{SVector{3, T}}, @@ -132,7 +132,7 @@ export collide_forces! public nl_edge_forces! # Precompile the collide forces for the default policy -let NL = NeighborLists{DefaultCollisionPolicy, DefaultPairParams} +let NL = NeighborLists{DefaultCollidePolicy, DefaultPairParams} for FE in (ForceEnergyFloat64, ForceEnergyFixedPoint{30, 30}, ForceNoEnergyFixedPoint{30}) for T in (Float32, Float64) for Pos in ( diff --git a/src/collide-forces.jl b/src/collide-forces.jl index efea2f3..008bcbe 100644 --- a/src/collide-forces.jl +++ b/src/collide-forces.jl @@ -1,14 +1,14 @@ """ - nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge, policy::CollisionPolicy, calc_type)::Nothing + nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge, policy::CollidePolicy, calc_type)::Nothing Add the collide force and energy of a single neighbor-list edge to `force_energy`. Methods dispatch on the index part types of `edge` and on `policy`, so a custom -`CollisionPolicy` with its own `PairParams` can define its own force laws. +`CollidePolicy` with its own `PairParams` can define its own force laws. """ function nl_edge_forces! end -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, PointIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, PointIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T x1 = pos[edge.a.i] x2 = pos[edge.b.i] d = map(calc_type, x1 - x2) @@ -27,7 +27,7 @@ Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos nothing end -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, CLineIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, CLineIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T x1 = pos[edge.a.i] y1 = pos[edge.b.i] y2 = pos[edge.b.i + UInt32(1)] @@ -51,7 +51,7 @@ Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos nothing end -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, LineIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, LineIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T x1 = pos[edge.a.i] y1 = pos[edge.b.i] y2 = pos[edge.b.j] @@ -196,7 +196,7 @@ Force on P0 can be computed as -(fp1+fq0+fq1) end end -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{CLineIdxPart, CLineIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{CLineIdxPart, CLineIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T P0 = pos[edge.a.i] P1 = pos[edge.a.i + UInt32(1)] Q0 = pos[edge.b.i] @@ -216,7 +216,7 @@ Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos nothing end -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{CLineIdxPart, LineIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{CLineIdxPart, LineIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T P0 = pos[edge.a.i] P1 = pos[edge.a.i + UInt32(1)] Q0 = pos[edge.b.i] @@ -236,7 +236,7 @@ Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos nothing end -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{LineIdxPart, LineIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{LineIdxPart, LineIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T P0 = pos[edge.a.i] P1 = pos[edge.a.j] Q0 = pos[edge.b.i] @@ -265,7 +265,7 @@ Based on https://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pd // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 6.0.2022.01.06 =# -Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, TriangleIdxPart, DefaultPairParams}, policy::DefaultCollisionPolicy, calc_type::T) where T +Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos, edge::NeighborListEdge{PointIdxPart, TriangleIdxPart, DefaultPairParams}, policy::DefaultCollidePolicy, calc_type::T) where T P = pos[edge.a.i] B = pos[edge.b.i] E0 = map(calc_type, pos[edge.b.j] - B) @@ -334,7 +334,7 @@ Base.@propagate_inbounds function nl_edge_forces!(force_energy::ForceEnergy, pos nothing end -function nl_forces!(force_energy::ForceEnergy, pos, nl, policy::CollisionPolicy, calc_type::T, chunk, nthreads) where T +function nl_forces!(force_energy::ForceEnergy, pos, nl, policy::CollidePolicy, calc_type::T, chunk, nthreads) where T # Split 1:length(nl) into nthreads contiguous chunks with sizes differing # by at most one; chunks past the end are empty. q, r = divrem(length(nl), nthreads) @@ -353,7 +353,7 @@ Add the collide forces and energy of every neighbor-list edge in `s` to `force_energy`, doing the calculations in the floating-point type `calc_type`. Each edge's contribution is computed by [`nl_edge_forces!`](@ref), so a custom -`CollisionPolicy` can change the force laws. +`CollidePolicy` can change the force laws. For multithreading, split the work into `nthreads` chunks: thread `t` calls `collide_forces!` with `chunk=t` and the same `nthreads`, accumulating into diff --git a/src/neighbor-lists.jl b/src/neighbor-lists.jl index 4ce2d1c..3224fa5 100644 --- a/src/neighbor-lists.jl +++ b/src/neighbor-lists.jl @@ -96,16 +96,16 @@ Dispatch token and global configuration for neighbor-list construction. `ObjectParams` is per-object. `PairParams` is per-pair. """ -abstract type CollisionPolicy{ObjectParams, PairParams} end +abstract type CollidePolicy{ObjectParams, PairParams} end -object_params_type(::Type{<:CollisionPolicy{O, P}}) where {O, P} = O -pair_params_type(::Type{<:CollisionPolicy{O, P}}) where {O, P} = P -object_params_type(policy::CollisionPolicy) = object_params_type(typeof(policy)) -pair_params_type(policy::CollisionPolicy) = pair_params_type(typeof(policy)) +object_params_type(::Type{<:CollidePolicy{O, P}}) where {O, P} = O +pair_params_type(::Type{<:CollidePolicy{O, P}}) where {O, P} = P +object_params_type(policy::CollidePolicy) = object_params_type(typeof(policy)) +pair_params_type(policy::CollidePolicy) = pair_params_type(typeof(policy)) """ filter_object( - policy::CollisionPolicy{ObjectParams, PairParams}, + policy::CollidePolicy{ObjectParams, PairParams}, object_params::ObjectParams, object_type::CollideObjectTypes, object_index::UInt32, @@ -121,7 +121,7 @@ function filter_object end """ filter_pair( - policy::CollisionPolicy{ObjectParams, PairParams}, + policy::CollidePolicy{ObjectParams, PairParams}, a::ObjectParams, b::ObjectParams, object_type_a::CollideObjectTypes, @@ -144,7 +144,7 @@ function filter_pair end """ mix_params( - policy::CollisionPolicy{ObjectParams, PairParams}, + policy::CollidePolicy{ObjectParams, PairParams}, a::ObjectParams, b::ObjectParams, object_type_a::CollideObjectTypes, @@ -169,7 +169,7 @@ struct DefaultPairParams k::Float32 end -Base.@kwdef struct DefaultCollisionPolicy <: CollisionPolicy{ +Base.@kwdef struct DefaultCollidePolicy <: CollidePolicy{ DefaultObjectParams, DefaultPairParams, } @@ -178,7 +178,7 @@ Base.@kwdef struct DefaultCollisionPolicy <: CollisionPolicy{ end @inline function filter_object( - ::DefaultCollisionPolicy, + ::DefaultCollidePolicy, params::DefaultObjectParams, object_type::CollideObjectTypes, object_index::UInt32, @@ -192,13 +192,13 @@ end Check if two objects can collide based on their collision layers and no-collide masks. -Each object has `collision_layers` (which layers it is on) and `no_collide_mask` +Each object has `layers` (which layers it is on) and `no_collide_mask` (which layers it will not collide with). Two objects cannot collide if either one has disabled collisions with the other's layer: no_collide = (A.layers & B.no_collide_mask) ≠ 0 OR (B.layers & A.no_collide_mask) ≠ 0 -Default `collision_layers = UInt32(1)` and `no_collide_mask = UInt32(0)` (collide with all layers), +Default `layers = UInt32(1)` and `no_collide_mask = UInt32(0)` (collide with all layers), so all objects collide by default. """ @inline function can_collide(layers_a::UInt32, no_collide_mask_a::UInt32, layers_b::UInt32, no_collide_mask_b::UInt32)::Bool @@ -206,7 +206,7 @@ so all objects collide by default. end @inline function filter_pair( - ::DefaultCollisionPolicy, + ::DefaultCollidePolicy, a::DefaultObjectParams, b::DefaultObjectParams, object_type_a::CollideObjectTypes, @@ -220,7 +220,7 @@ end end @inline function mix_params( - ::DefaultCollisionPolicy, + ::DefaultCollidePolicy, a::DefaultObjectParams, b::DefaultObjectParams, object_type_a::CollideObjectTypes, @@ -250,7 +250,7 @@ in the reverse order are silently ignored: `CollideLine_Line` excludes `line_index_a => line_index_b` where `line_index_a < line_index_b`. """ -Base.@kwdef mutable struct NeighborListInputs{Policy <: CollisionPolicy, ObjectParams} +Base.@kwdef mutable struct NeighborListInputs{Policy <: CollidePolicy, ObjectParams} policy::Policy points::Vector{PointIdxPart} = PointIdxPart[] @@ -287,7 +287,7 @@ Base.@kwdef mutable struct NeighborListInputs{Policy <: CollisionPolicy, ObjectP nthreads::Int = 1 end -function NeighborListInputs(policy::Policy; kwargs...) where {Policy <: CollisionPolicy} +function NeighborListInputs(policy::Policy; kwargs...) where {Policy <: CollidePolicy} ObjectParams = object_params_type(policy) NeighborListInputs{Policy, ObjectParams}(; policy, kwargs...) end @@ -343,7 +343,7 @@ function swap_remove_active!(a::ActiveSoA, k::Integer)::UInt32 moved end -mutable struct NeighborLists{Policy <: CollisionPolicy, PairParams} +mutable struct NeighborLists{Policy <: CollidePolicy, PairParams} policy::Policy PPNL::Vector{NeighborListEdge{PointIdxPart, PointIdxPart, PairParams}} PCNL::Vector{NeighborListEdge{PointIdxPart, CLineIdxPart, PairParams}} @@ -353,7 +353,7 @@ mutable struct NeighborLists{Policy <: CollisionPolicy, PairParams} CLNL::Vector{NeighborListEdge{CLineIdxPart, LineIdxPart, PairParams}} LLNL::Vector{NeighborListEdge{LineIdxPart, LineIdxPart, PairParams}} end -function NeighborLists(policy::Policy) where {Policy <: CollisionPolicy} +function NeighborLists(policy::Policy) where {Policy <: CollidePolicy} PairParams = pair_params_type(policy) NeighborLists{Policy, PairParams}( policy, diff --git a/test/test-collide-forces.jl b/test/test-collide-forces.jl index d7424c9..8516d89 100644 --- a/test/test-collide-forces.jl +++ b/test/test-collide-forces.jl @@ -11,7 +11,7 @@ Error if the collide force and energy violates a property `a` and `b` are vectors of three vectors """ function check_collide_props(a, b) - policy = DefaultCollisionPolicy() + policy = DefaultCollidePolicy() positions = SVector{3, Float64}[] a_i, b_i = map((a,b)) do y local idxs = UInt32[] @@ -178,7 +178,7 @@ end end @testset "collide_forces! integration" begin - policy = DefaultCollisionPolicy() + policy = DefaultCollidePolicy() # 3×3×4 grid, spacing 0.4: with radius 0.3 overlaps are guaranteed, but # no two objects touch exactly, so all forces stay finite positions = [0.4*SA[mod(i-1, 3), mod((i-1)÷3, 3), (i-1)÷9] for i in 1:30] diff --git a/test/test-neighbor-lists.jl b/test/test-neighbor-lists.jl index f76859b..cb93b2b 100644 --- a/test/test-neighbor-lists.jl +++ b/test/test-neighbor-lists.jl @@ -4,7 +4,7 @@ using StaticArrays using Random @testset "neighborlists" begin - policy = DefaultCollisionPolicy() + policy = DefaultCollidePolicy() @testset "Naive vs Sort-Sweep consistency" begin for trial in 1:2000