Skip to content

Commit feeef01

Browse files
authored
Merge pull request #33 from trixi-framework/dev
Merge breaking changes from `dev`
2 parents 591827b + 5d52dfd commit feeef01

File tree

12 files changed

+400
-362
lines changed

12 files changed

+400
-362
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PointNeighbors"
22
uuid = "1c4d5385-0a27-49de-8e2c-43b175c8985c"
33
authors = ["Erik Faulhaber <[email protected]>"]
4-
version = "0.2.4-dev"
4+
version = "0.3.0"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

src/PointNeighbors.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ include("neighborhood_search.jl")
1111
include("nhs_trivial.jl")
1212
include("cell_lists/cell_lists.jl")
1313
include("nhs_grid.jl")
14-
include("nhs_neighbor_lists.jl")
14+
include("nhs_precomputed.jl")
1515

16-
export for_particle_neighbor, foreach_neighbor
16+
export foreach_point_neighbor, foreach_neighbor
1717
export TrivialNeighborhoodSearch, GridNeighborhoodSearch, PrecomputedNeighborhoodSearch
1818
export initialize!, update!, initialize_grid!, update_grid!
19+
export PeriodicBox, copy_neighborhood_search
1920

2021
end # module PointNeighbors

src/cell_lists/dictionary.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ function Base.empty!(cell_list::DictionaryCellList)
1616
return cell_list
1717
end
1818

19-
function push_cell!(cell_list::DictionaryCellList, cell, particle)
19+
function push_cell!(cell_list::DictionaryCellList, cell, point)
2020
(; hashtable) = cell_list
2121

2222
if haskey(hashtable, cell)
23-
append!(hashtable[cell], particle)
23+
append!(hashtable[cell], point)
2424
else
25-
hashtable[cell] = [particle]
25+
hashtable[cell] = [point]
2626
end
2727

2828
return cell_list

src/neighborhood_search.jl

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ See also [`update!`](@ref).
1515
@inline initialize!(search::AbstractNeighborhoodSearch, x, y) = search
1616

1717
"""
18-
update!(search::AbstractNeighborhoodSearch, x, y; particles_moving = (true, true))
18+
update!(search::AbstractNeighborhoodSearch, x, y; points_moving = (true, true))
1919
2020
Update an already initialized neighborhood search with the two coordinate arrays `x` and `y`.
2121
@@ -29,70 +29,112 @@ If incremental updates are not possible for an implementation, `update!` will fa
2929
to a regular `initialize!`.
3030
3131
Some neighborhood searches might not need to update when only `x` changed since the last
32-
`update!` or `initialize!` and `y` did not change. Pass `particles_moving = (true, false)`
32+
`update!` or `initialize!` and `y` did not change. Pass `points_moving = (true, false)`
3333
in this case to avoid unnecessary updates.
34-
The first flag in `particles_moving` indicates if points in `x` are moving.
34+
The first flag in `points_moving` indicates if points in `x` are moving.
3535
The second flag indicates if points in `y` are moving.
3636
3737
See also [`initialize!`](@ref).
3838
"""
3939
@inline function update!(search::AbstractNeighborhoodSearch, x, y;
40-
particles_moving = (true, true))
40+
points_moving = (true, true))
4141
return search
4242
end
4343

44+
"""
45+
copy_neighborhood_search(search::AbstractNeighborhoodSearch, search_radius, n_points;
46+
eachpoint = 1:n_points)
47+
48+
Create a new **uninitialized** neighborhood search of the same type and with the same
49+
configuration options as `search`, but with a different search radius and number of points.
50+
51+
The [`TrivialNeighborhoodSearch`](@ref) also requires an iterator `eachpoint`, which most
52+
of the time will be `1:n_points`. If the `TrivialNeighborhoodSearch` is never going to be
53+
used, the keyword argument `eachpoint` can be ignored.
54+
55+
This is useful when a simulation code requires multiple neighborhood searches of the same
56+
kind. One can then just pass an empty neighborhood search as a template and use
57+
this function inside the simulation code to generate similar neighborhood searches with
58+
different search radii and different numbers of points.
59+
```jldoctest; filter = r"GridNeighborhoodSearch{2,.*"
60+
# Template
61+
nhs = GridNeighborhoodSearch{2}()
62+
63+
# Inside the simulation code, generate similar neighborhood searches
64+
nhs1 = copy_neighborhood_search(nhs, 1.0, 100)
65+
66+
# output
67+
GridNeighborhoodSearch{2, Float64, ...}(...)
68+
```
69+
"""
70+
@inline function copy_neighborhood_search(search::AbstractNeighborhoodSearch,
71+
search_radius, n_points; eachpoint = 1:n_points)
72+
return nothing
73+
end
74+
75+
"""
76+
PeriodicBox(; min_corner, max_corner)
77+
78+
Define a rectangular periodic domain.
79+
80+
# Keywords
81+
- `min_corner`: Coordinates of the domain corner in negative coordinate directions.
82+
- `max_corner`: Coordinates of the domain corner in positive coordinate directions.
83+
"""
4484
struct PeriodicBox{NDIMS, ELTYPE}
4585
min_corner :: SVector{NDIMS, ELTYPE}
4686
max_corner :: SVector{NDIMS, ELTYPE}
4787
size :: SVector{NDIMS, ELTYPE}
4888

49-
function PeriodicBox(min_corner, max_corner)
50-
new{length(min_corner), eltype(min_corner)}(min_corner, max_corner,
51-
max_corner - min_corner)
89+
function PeriodicBox(; min_corner, max_corner)
90+
min_corner_ = SVector(Tuple(min_corner))
91+
max_corner_ = SVector(Tuple(max_corner))
92+
93+
new{length(min_corner), eltype(min_corner)}(min_corner_, max_corner_,
94+
max_corner_ - min_corner_)
5295
end
5396
end
5497

5598
# The type annotation is to make Julia specialize on the type of the function.
5699
# Otherwise, unspecialized code will cause a lot of allocations
57100
# and heavily impact performance.
58101
# See https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing
59-
function for_particle_neighbor(f::T, system_coords, neighbor_coords, neighborhood_search;
60-
particles = axes(system_coords, 2),
61-
parallel = true) where {T}
62-
for_particle_neighbor(f, system_coords, neighbor_coords, neighborhood_search, particles,
63-
Val(parallel))
102+
function foreach_point_neighbor(f::T, system_coords, neighbor_coords, neighborhood_search;
103+
points = axes(system_coords, 2),
104+
parallel = true) where {T}
105+
foreach_point_neighbor(f, system_coords, neighbor_coords, neighborhood_search, points,
106+
Val(parallel))
64107
end
65108

66-
@inline function for_particle_neighbor(f, system_coords, neighbor_coords,
67-
neighborhood_search, particles, parallel::Val{true})
68-
@threaded for particle in particles
69-
foreach_neighbor(f, system_coords, neighbor_coords, neighborhood_search, particle)
109+
@inline function foreach_point_neighbor(f, system_coords, neighbor_coords,
110+
neighborhood_search, points, parallel::Val{true})
111+
@threaded for point in points
112+
foreach_neighbor(f, system_coords, neighbor_coords, neighborhood_search, point)
70113
end
71114

72115
return nothing
73116
end
74117

75-
@inline function for_particle_neighbor(f, system_coords, neighbor_coords,
76-
neighborhood_search, particles, parallel::Val{false})
77-
for particle in particles
78-
foreach_neighbor(f, system_coords, neighbor_coords, neighborhood_search, particle)
118+
@inline function foreach_point_neighbor(f, system_coords, neighbor_coords,
119+
neighborhood_search, points, parallel::Val{false})
120+
for point in points
121+
foreach_neighbor(f, system_coords, neighbor_coords, neighborhood_search, point)
79122
end
80123

81124
return nothing
82125
end
83126

84127
@inline function foreach_neighbor(f, system_coords, neighbor_system_coords,
85-
neighborhood_search, particle;
128+
neighborhood_search, point;
86129
search_radius = neighborhood_search.search_radius)
87130
(; periodic_box) = neighborhood_search
88131

89-
particle_coords = extract_svector(system_coords, Val(ndims(neighborhood_search)),
90-
particle)
91-
for neighbor in eachneighbor(particle_coords, neighborhood_search)
132+
point_coords = extract_svector(system_coords, Val(ndims(neighborhood_search)), point)
133+
for neighbor in eachneighbor(point_coords, neighborhood_search)
92134
neighbor_coords = extract_svector(neighbor_system_coords,
93135
Val(ndims(neighborhood_search)), neighbor)
94136

95-
pos_diff = particle_coords - neighbor_coords
137+
pos_diff = point_coords - neighbor_coords
96138
distance2 = dot(pos_diff, pos_diff)
97139

98140
pos_diff, distance2 = compute_periodic_distance(pos_diff, distance2, search_radius,
@@ -102,8 +144,8 @@ end
102144
distance = sqrt(distance2)
103145

104146
# Inline to avoid loss of performance
105-
# compared to not using `for_particle_neighbor`.
106-
@inline f(particle, neighbor, pos_diff, distance)
147+
# compared to not using `foreach_point_neighbor`.
148+
@inline f(point, neighbor, pos_diff, distance)
107149
end
108150
end
109151
end
@@ -113,8 +155,7 @@ end
113155
return pos_diff, distance2
114156
end
115157

116-
@inline function compute_periodic_distance(pos_diff, distance2, search_radius,
117-
periodic_box)
158+
@inline function compute_periodic_distance(pos_diff, distance2, search_radius, periodic_box)
118159
if distance2 > search_radius^2
119160
# Use periodic `pos_diff`
120161
pos_diff -= periodic_box.size .* round.(pos_diff ./ periodic_box.size)

0 commit comments

Comments
 (0)