-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into plot-recipe
- Loading branch information
Showing
6 changed files
with
179 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Wrapper for any neighborhood search that forwards `for_particle_neighbor` to the wrapped | ||
# neighborhood search, but doesn't do anything in the update step. | ||
# This is used in the example tests to test for zero allocations in the `kick!` function. | ||
struct NoUpdateNeighborhoodSearch{NHS} | ||
nhs::NHS | ||
end | ||
|
||
# Copy a `Semidiscretization`, but wrap the neighborhood searches with | ||
# `NoUpdateNeighborhoodSearch`. | ||
function copy_semi_with_no_update_nhs(semi) | ||
neighborhood_searches = Tuple(Tuple(NoUpdateNeighborhoodSearch(nhs) | ||
for nhs in searches) | ||
for searches in semi.neighborhood_searches) | ||
|
||
return Semidiscretization(semi.systems, semi.ranges_u, semi.ranges_v, | ||
neighborhood_searches) | ||
end | ||
|
||
# Forward `for_particle_neighbor` to wrapped neighborhood search | ||
@inline function TrixiParticles.for_particle_neighbor(f, system_coords, neighbor_coords, | ||
neighborhood_search::NoUpdateNeighborhoodSearch; | ||
particles=axes(system_coords, 2), | ||
parallel=true) | ||
TrixiParticles.for_particle_neighbor(f, system_coords, neighbor_coords, | ||
neighborhood_search.nhs, | ||
particles=particles, parallel=parallel) | ||
end | ||
|
||
# No update | ||
@inline TrixiParticles.update!(search::NoUpdateNeighborhoodSearch, coords_fun) = search | ||
|
||
# Count allocations of one call to the right-hand side (`kick!` + `drift!`) | ||
function count_rhs_allocations(sol, semi) | ||
t = sol.t[end] | ||
v_ode, u_ode = sol.u[end].x | ||
dv_ode = similar(v_ode) | ||
du_ode = similar(u_ode) | ||
|
||
# Wrap neighborhood searches to avoid counting alloctations in the NHS update | ||
semi_no_nhs_update = copy_semi_with_no_update_nhs(semi) | ||
|
||
try | ||
# Disable timers, which cause extra allocations | ||
TrixiParticles.TimerOutputs.disable_debug_timings(TrixiParticles) | ||
|
||
# Disable multithreading, which causes extra allocations | ||
return disable_polyester_threads() do | ||
# We need `@invokelatest` here to ensure that the most recent method of | ||
# `TrixiParticles.timeit_debug_enabled()` is called, which is redefined in | ||
# `disable_debug_timings` above. | ||
return @invokelatest count_rhs_allocations_inner(dv_ode, du_ode, v_ode, u_ode, | ||
semi_no_nhs_update, t) | ||
end | ||
finally | ||
# Enable timers again | ||
@invokelatest TrixiParticles.TimerOutputs.enable_debug_timings(TrixiParticles) | ||
end | ||
end | ||
|
||
# Function barrier to avoid type instabilites with `semi_no_nhs_update`, which will | ||
# cause extra allocations. | ||
@inline function count_rhs_allocations_inner(dv_ode, du_ode, v_ode, u_ode, | ||
semi_no_nhs_update, t) | ||
# Run RHS once to avoid counting allocations from compilation | ||
TrixiParticles.kick!(dv_ode, v_ode, u_ode, semi_no_nhs_update, t) | ||
TrixiParticles.drift!(du_ode, v_ode, u_ode, semi_no_nhs_update, t) | ||
|
||
# Count allocations | ||
allocations_kick = @allocated TrixiParticles.kick!(dv_ode, v_ode, u_ode, | ||
semi_no_nhs_update, t) | ||
allocations_drift = @allocated TrixiParticles.drift!(du_ode, v_ode, u_ode, | ||
semi_no_nhs_update, t) | ||
|
||
return allocations_kick + allocations_drift | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Rectangular patch of particles, optionally with a perturbation in position and/or quantities | ||
function rectangular_patch(particle_spacing, size; density=1000.0, pressure=0.0, seed=1, | ||
perturbation_factor=1.0, perturbation_factor_position=1.0, | ||
set_function=nothing, offset=ntuple(_ -> 0.0, length(size))) | ||
# Fixed seed to ensure reproducibility | ||
Random.seed!(seed) | ||
|
||
# Center particle at the origin (assuming odd size) | ||
min_corner = -particle_spacing / 2 .* size | ||
ic = RectangularShape(particle_spacing, size, min_corner, | ||
density=density, pressure=pressure) | ||
|
||
perturb!(ic.coordinates, perturbation_factor_position * 0.5 * particle_spacing) | ||
|
||
# Don't perturb center particle position | ||
center_particle = ceil(Int, prod(size) / 2) | ||
ic.coordinates[:, center_particle] .= 0.0 | ||
|
||
for i in 1:Base.size(ic.coordinates, 2) | ||
ic.coordinates[:, i] .+= offset | ||
end | ||
|
||
if set_function !== nothing | ||
for i in 1:Base.size(ic.coordinates, 2) | ||
coord = ic.coordinates[:, i] | ||
ic.mass[i], ic.density[i], ic.pressure[i], ic.velocity[:, i] = set_function(coord) | ||
end | ||
end | ||
|
||
if perturbation_factor > eps() | ||
perturb!(ic.mass, perturbation_factor * 0.1 * ic.mass[1]) | ||
perturb!(ic.density, perturbation_factor * 0.1 * density) | ||
perturb!(ic.pressure, perturbation_factor * 2000) | ||
perturb!(ic.velocity, perturbation_factor * 0.5 * particle_spacing) | ||
end | ||
|
||
return ic | ||
end | ||
|
||
function perturb!(data, amplitude) | ||
for i in eachindex(data) | ||
# Perturbation in the interval (-amplitude, amplitude) | ||
data[i] += 2 * amplitude * rand() - amplitude | ||
end | ||
|
||
return data | ||
end |
Oops, something went wrong.