Skip to content

Commit 1de092a

Browse files
author
LasNikas
committed
works on CPU but not on GPU
1 parent 63b60a1 commit 1de092a

File tree

3 files changed

+86
-46
lines changed

3 files changed

+86
-46
lines changed

src/general/buffer.jl

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1-
struct SystemBuffer{AP, APC, EP}
2-
active_particle :: AP # Vector{Bool}
3-
active_particle_count :: APC
4-
eachparticle :: EP # Vector{Int}
1+
struct SystemBuffer{VB, RI, VI}
2+
active_particle :: VB # Vector{Bool}
3+
active_particle_count :: RI # Ref{Int}
4+
candidates :: VI # Vector{Int}
5+
particle_outside :: VB # Vector{Bool}
6+
available_particles :: VI # Vector{Int}
7+
next_particle :: VI # Vector{Int}
8+
eachparticle :: VI # Vector{Int}
59
buffer_size :: Int
610
end
711

812
function SystemBuffer(active_size, buffer_size::Integer)
913
# We cannot use a `BitVector` here, as writing to a `BitVector` is not thread-safe
1014
active_particle = vcat(fill(true, active_size), fill(false, buffer_size))
15+
candidates = collect(eachindex(active_particle))
16+
particle_outside = vcat(fill(false, active_size), fill(true, buffer_size))
17+
available_particles = collect(eachindex(active_particle))
1118
eachparticle = collect(eachindex(active_particle))
1219

13-
return SystemBuffer(active_particle, Ref(active_size), eachparticle, buffer_size)
20+
return SystemBuffer(active_particle, Ref(active_size), candidates, particle_outside,
21+
available_particles, Int[1], eachparticle, buffer_size)
1422
end
1523

1624
allocate_buffer(initial_condition, ::Nothing) = initial_condition
@@ -42,7 +50,6 @@ end
4250
@inline function update_system_buffer!(buffer::SystemBuffer, semi)
4351
(; active_particle) = buffer
4452

45-
4653
buffer.active_particle_count[] = count(active_particle)
4754
buffer.eachparticle .= -1
4855

@@ -62,31 +69,15 @@ end
6269
return buffer
6370
end
6471

65-
@inline each_moving_particle(system, buffer) = view(buffer.eachparticle,
66-
1:buffer.active_particle_count[])
72+
@inline each_moving_particle(system,
73+
buffer) = view(buffer.eachparticle,
74+
1:buffer.active_particle_count[])
6775

6876
@inline active_coordinates(u, system, buffer) = view(u, :, buffer.active_particle)
6977

70-
@inline active_particles(system, buffer) = view(buffer.eachparticle,
71-
1:buffer.active_particle_count[])
72-
73-
@inline function activate_next_particle(system)
74-
(; active_particle) = system.buffer
75-
76-
for particle in eachindex(active_particle)
77-
if !active_particle[particle]
78-
# Activate this particle. The return value is the old value.
79-
# If this is `true`, the particle was active before and we need to continue.
80-
# This happens because a particle might have been activated by another thread
81-
# between the condition and the line below.
82-
was_active = PointNeighbors.Atomix.@atomicswap active_particle[particle] = true
83-
84-
!was_active && return particle
85-
end
86-
end
87-
88-
error("No buffer particles available")
89-
end
78+
@inline active_particles(system,
79+
buffer) = view(buffer.eachparticle,
80+
1:buffer.active_particle_count[])
9081

9182
@inline function deactivate_particle!(system, particle, u)
9283
(; active_particle) = system.buffer

src/schemes/boundary/open_boundary/method_of_characteristics.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ end
2525
@inline function update_boundary_quantities!(system, boundary_model::BoundaryModelLastiwka,
2626
v, u, v_ode, u_ode, semi, t)
2727
(; density, pressure, cache, boundary_zone,
28-
reference_velocity, reference_pressure, reference_density) = system
28+
reference_velocity, reference_pressure, reference_density) = system
2929
(; flow_direction) = boundary_zone
3030

3131
fluid_system = corresponding_fluid_system(system, semi)
@@ -155,7 +155,7 @@ end
155155
function evaluate_characteristics!(system, neighbor_system::FluidSystem,
156156
v, u, v_ode, u_ode, semi, t)
157157
(; volume, cache, boundary_zone, density, pressure,
158-
reference_velocity, reference_pressure, reference_density) = system
158+
reference_velocity, reference_pressure, reference_density) = system
159159
(; flow_direction) = boundary_zone
160160
(; characteristics) = cache
161161

src/schemes/boundary/open_boundary/system.jl

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -281,31 +281,79 @@ function check_domain!(system, v, u, v_ode, u_ode, semi)
281281
u_fluid = wrap_u(u_ode, fluid_system, semi)
282282
v_fluid = wrap_v(v_ode, fluid_system, semi)
283283

284+
function map_sort!(a, b) # (a::Vector{Int}, b::Vector{Bool})
285+
map!((true_value, idx) -> true_value ? -1 : idx, a, b, eachindex(b))
286+
287+
sort!(a, rev=true)
288+
289+
return a # [idx_1, idx_2, ..., -1, -1]
290+
end
291+
292+
system.buffer.particle_outside .= false
293+
284294
# Check the boundary particles whether they're leaving the boundary zone
285295
@threaded semi for particle in each_moving_particle(system)
286296
particle_coords = current_coords(u, system, particle)
287297

288298
# Check if boundary particle is outside the boundary zone
289299
if !is_in_boundary_zone(boundary_zone, particle_coords)
290-
convert_particle!(system, fluid_system, boundary_zone, particle,
291-
v, u, v_fluid, u_fluid)
300+
system.buffer.particle_outside[particle] = true
292301
end
293302
end
294303

304+
# Basically: # candidates = [candidate_1, candidate_2, ..., -1, -1]
305+
map_sort!(system.buffer.candidates, .!(system.buffer.particle_outside))
306+
307+
# Basically: `available_particles = [inactive_1, inactive_2, ..., -1, -1]`
308+
map_sort!(fluid_system.buffer.available_particles, fluid_system.buffer.active_particle)
309+
310+
fluid_system.buffer.next_particle[1] = 0
311+
312+
# Copy buffer particle information to the fluid system
313+
@threaded semi for buffer_id in 1:count(system.buffer.particle_outside)
314+
particle = system.buffer.candidates[buffer_id]
315+
316+
fluid_id = PointNeighbors.Atomix.@atomic fluid_system.buffer.next_particle[1] += 1
317+
new_particle = fluid_system.buffer.available_particles[fluid_id]
318+
319+
convert_particle!(system, fluid_system, boundary_zone, particle, new_particle,
320+
v, u, v_fluid, u_fluid)
321+
end
322+
295323
update_system_buffer!(system.buffer, semi)
296324
update_system_buffer!(fluid_system.buffer, semi)
297325

326+
fluid_system.buffer.particle_outside .= false
327+
298328
# Check the fluid particles whether they're entering the boundary zone
299329
@threaded semi for fluid_particle in each_moving_particle(fluid_system)
300330
fluid_coords = current_coords(u_fluid, fluid_system, fluid_particle)
301331

302332
# Check if fluid particle is in boundary zone
303333
if is_in_boundary_zone(boundary_zone, fluid_coords)
304-
convert_particle!(fluid_system, system, boundary_zone, fluid_particle,
305-
v, u, v_fluid, u_fluid)
334+
fluid_system.buffer.particle_outside[fluid_particle] = true
306335
end
307336
end
308337

338+
# Basically: # candidates = [candidate_1, candidate_2, ..., -1, -1]
339+
map_sort!(fluid_system.buffer.candidates, .!(fluid_system.buffer.particle_outside))
340+
341+
# Basically: `available_particles = [inactive_1, inactive_2, ..., -1, -1]`
342+
map_sort!(system.buffer.available_particles, system.buffer.active_particle)
343+
344+
system.buffer.next_particle[1] = 0
345+
346+
# Copy fluid particle information to the buffer
347+
@threaded semi for fluid_id in 1:count(fluid_system.buffer.particle_outside)
348+
particle = fluid_system.buffer.candidates[fluid_id]
349+
350+
buffer_id = PointNeighbors.Atomix.@atomic system.buffer.next_particle[1] += 1
351+
new_particle = system.buffer.available_particles[buffer_id]
352+
353+
convert_particle!(fluid_system, system, boundary_zone, particle, new_particle,
354+
v, u, v_fluid, u_fluid)
355+
end
356+
309357
update_system_buffer!(system.buffer, semi)
310358
update_system_buffer!(fluid_system.buffer, semi)
311359

@@ -314,21 +362,21 @@ end
314362

315363
# Outflow particle is outside the boundary zone
316364
@inline function convert_particle!(system::OpenBoundarySPHSystem, fluid_system,
317-
boundary_zone::BoundaryZone{OutFlow}, particle, v, u,
318-
v_fluid, u_fluid)
365+
boundary_zone::BoundaryZone{OutFlow},
366+
particle, new_partcile, v, u, v_fluid, u_fluid)
319367
deactivate_particle!(system, particle, u)
320368

321369
return system
322370
end
323371

324372
# Inflow particle is outside the boundary zone
325373
@inline function convert_particle!(system::OpenBoundarySPHSystem, fluid_system,
326-
boundary_zone::BoundaryZone{InFlow}, particle, v, u,
327-
v_fluid, u_fluid)
374+
boundary_zone::BoundaryZone{InFlow},
375+
particle, new_partcile, v, u, v_fluid, u_fluid)
328376
(; spanning_set) = boundary_zone
329377

330378
# Activate a new particle in simulation domain
331-
transfer_particle!(fluid_system, system, particle, v_fluid, u_fluid, v, u)
379+
transfer_particle!(fluid_system, system, particle, new_partcile, v_fluid, u_fluid, v, u)
332380

333381
# Reset position of boundary particle
334382
for dim in 1:ndims(system)
@@ -340,8 +388,8 @@ end
340388

341389
# Buffer particle is outside the boundary zone
342390
@inline function convert_particle!(system::OpenBoundarySPHSystem, fluid_system,
343-
boundary_zone::BoundaryZone{BidirectionalFlow}, particle,
344-
v, u, v_fluid, u_fluid)
391+
boundary_zone::BoundaryZone{BidirectionalFlow},
392+
particle, new_particle, v, u, v_fluid, u_fluid)
345393
relative_position = current_coords(u, system, particle) - boundary_zone.zone_origin
346394

347395
# Check if particle is in- or outside the fluid domain.
@@ -353,7 +401,7 @@ end
353401
end
354402

355403
# Activate a new particle in simulation domain
356-
transfer_particle!(fluid_system, system, particle, v_fluid, u_fluid, v, u)
404+
transfer_particle!(fluid_system, system, particle, new_particle, v_fluid, u_fluid, v, u)
357405

358406
# Reset position of boundary particle
359407
for dim in 1:ndims(system)
@@ -365,19 +413,20 @@ end
365413

366414
# Fluid particle is in boundary zone
367415
@inline function convert_particle!(fluid_system::FluidSystem, system,
368-
boundary_zone, particle, v, u, v_fluid, u_fluid)
416+
boundary_zone,
417+
particle, new_particle, v, u, v_fluid, u_fluid)
369418
# Activate particle in boundary zone
370-
transfer_particle!(system, fluid_system, particle, v, u, v_fluid, u_fluid)
419+
transfer_particle!(system, fluid_system, particle, new_particle, v, u, v_fluid, u_fluid)
371420

372421
# Deactivate particle in interior domain
373422
deactivate_particle!(fluid_system, particle, u_fluid)
374423

375424
return fluid_system
376425
end
377426

378-
@inline function transfer_particle!(system_new, system_old, particle_old,
427+
@inline function transfer_particle!(system_new, system_old, particle_old, particle_new,
379428
v_new, u_new, v_old, u_old)
380-
particle_new = activate_next_particle(system_new)
429+
system_new.buffer.active_particle[particle_new] = true
381430

382431
# Transfer densities
383432
density = current_density(v_old, system_old, particle_old)

0 commit comments

Comments
 (0)