@@ -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
322370end
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)
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.
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
376425end
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