diff --git a/docs/literate/src/tut_rigid_body_fsi.jl b/docs/literate/src/tut_rigid_body_fsi.jl index 6175439484..ef78d44c26 100644 --- a/docs/literate/src/tut_rigid_body_fsi.jl +++ b/docs/literate/src/tut_rigid_body_fsi.jl @@ -165,12 +165,8 @@ nothing # hide # See [the docs on dummy particles](@ref boundary_models) for a definition for these terms. boundary_density_calculator = AdamiPressureExtrapolation() -tank_boundary_model = BoundaryModelDummyParticles(tank.boundary.density, - tank.boundary.mass, - boundary_density_calculator, - fluid_smoothing_kernel, - fluid_smoothing_length; - state_equation) +tank_boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, + boundary_density_calculator) boundary_system = WallBoundarySystem(tank.boundary, tank_boundary_model) nothing # hide diff --git a/docs/literate/src/tut_setup.jl b/docs/literate/src/tut_setup.jl index b546c5eb89..ef0af41cea 100644 --- a/docs/literate/src/tut_setup.jl +++ b/docs/literate/src/tut_setup.jl @@ -131,14 +131,11 @@ nothing # hide # To model the boundary, we use particle-based boundary conditions, in which particles # are sampled in the boundary that interact with the fluid particles to avoid penetration. -# In order to define a boundary system, we first have to choose a boundary model, -# which defines how the fluid interacts with boundary particles. -# We will use the [`BoundaryModelDummyParticles`](@ref) with [`AdamiPressureExtrapolation`](@ref). -# See [here](@ref boundary_models) for a comprehensive overview over boundary models. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, - AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length; - state_equation) +# Here, we explicitly choose the dummy-particle boundary model and use its high-level +# builder to infer kernel and equation-of-state-related settings from the adjacent +# fluid system. See [here](@ref boundary_models) for a comprehensive overview over +# boundary models. +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) nothing # hide diff --git a/examples/fluid/dam_break_2d.jl b/examples/fluid/dam_break_2d.jl index c14119cb60..9af15a87d2 100644 --- a/examples/fluid/dam_break_2d.jl +++ b/examples/fluid/dam_break_2d.jl @@ -80,12 +80,8 @@ viscosity_wall = nothing # viscosity_wall = viscosity_fluid # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, - correction=nothing, - reference_particle_spacing=0, viscosity=viscosity_wall, clip_negative_pressure=true) diff --git a/examples/fluid/dam_break_3d.jl b/examples/fluid/dam_break_3d.jl index ae9b580960..0e5438ac53 100644 --- a/examples/fluid/dam_break_3d.jl +++ b/examples/fluid/dam_break_3d.jl @@ -57,10 +57,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothi boundary_density_calculator = AdamiPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fluid/falling_water_column_2d.jl b/examples/fluid/falling_water_column_2d.jl index 694c13ab76..c9c4b00fa5 100644 --- a/examples/fluid/falling_water_column_2d.jl +++ b/examples/fluid/falling_water_column_2d.jl @@ -55,10 +55,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothi boundary_density_calculator = AdamiPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fluid/falling_water_spheres_2d.jl b/examples/fluid/falling_water_spheres_2d.jl index 1f0016ac6d..657f496a48 100644 --- a/examples/fluid/falling_water_spheres_2d.jl +++ b/examples/fluid/falling_water_spheres_2d.jl @@ -82,12 +82,11 @@ boundary_density_calculator = AdamiPressureExtrapolation() wall_viscosity = nu # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; + fluid_system=sphere_surface_tension, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length; state_equation, viscosity=ViscosityAdami(nu=wall_viscosity), - reference_particle_spacing=fluid_particle_spacing, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model; diff --git a/examples/fluid/hydrostatic_water_column_2d.jl b/examples/fluid/hydrostatic_water_column_2d.jl index 58b381c0c0..93e6665c8f 100644 --- a/examples/fluid/hydrostatic_water_column_2d.jl +++ b/examples/fluid/hydrostatic_water_column_2d.jl @@ -60,10 +60,8 @@ boundary_density_calculator = AdamiPressureExtrapolation() # This is to set wall viscosity with `trixi_include` viscosity_wall = nothing -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, viscosity=viscosity_wall) boundary_system = WallBoundarySystem(tank.boundary, boundary_model, prescribed_motion=nothing) diff --git a/examples/fluid/lid_driven_cavity_2d.jl b/examples/fluid/lid_driven_cavity_2d.jl index c1aa4ae2a8..747caf2763 100644 --- a/examples/fluid/lid_driven_cavity_2d.jl +++ b/examples/fluid/lid_driven_cavity_2d.jl @@ -84,20 +84,14 @@ is_moving(t) = true lid_movement = PrescribedMotion(lid_movement_function, is_moving) -boundary_model_cavity = BoundaryModelDummyParticles(cavity.boundary.density, - cavity.boundary.mass, - AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length; - viscosity, state_equation) - -boundary_model_lid = BoundaryModelDummyParticles(lid.density, lid.mass, - AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length; - viscosity, state_equation) - -boundary_system_cavity = WallBoundarySystem(cavity.boundary, boundary_model_cavity) - -boundary_system_lid = WallBoundarySystem(lid, boundary_model_lid, +cavity_boundary_model = BoundaryModelDummyParticles(cavity.boundary; + fluid_system=fluid_system, + viscosity=viscosity) +boundary_system_cavity = WallBoundarySystem(cavity.boundary, cavity_boundary_model) + +lid_boundary_model = BoundaryModelDummyParticles(lid; fluid_system=fluid_system, + viscosity=viscosity) +boundary_system_lid = WallBoundarySystem(lid, lid_boundary_model, prescribed_motion=lid_movement) # ========================================================================================== diff --git a/examples/fluid/moving_wall_2d.jl b/examples/fluid/moving_wall_2d.jl index 6e0b0f9dfe..253386981c 100644 --- a/examples/fluid/moving_wall_2d.jl +++ b/examples/fluid/moving_wall_2d.jl @@ -59,10 +59,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothi # ========================================================================================== # ==== Boundary boundary_density_calculator = AdamiPressureExtrapolation() -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, - boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation) +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, + boundary_density_calculator) boundary_system = WallBoundarySystem(tank.boundary, boundary_model, prescribed_motion=boundary_movement) diff --git a/examples/fluid/periodic_array_of_cylinders_2d.jl b/examples/fluid/periodic_array_of_cylinders_2d.jl index 84d2ae140f..5d10c542dd 100644 --- a/examples/fluid/periodic_array_of_cylinders_2d.jl +++ b/examples/fluid/periodic_array_of_cylinders_2d.jl @@ -73,10 +73,8 @@ fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, smoothing_le # ========================================================================================== # ==== Boundary -boundary_model = BoundaryModelDummyParticles(boundary.density, boundary.mass, - AdamiPressureExtrapolation(), smoothing_kernel, - smoothing_length; - viscosity=ViscosityAdami(; nu), state_equation) +boundary_model = BoundaryModelDummyParticles(boundary; fluid_system=fluid_system, + viscosity=ViscosityAdami(; nu)) boundary_system = WallBoundarySystem(boundary, boundary_model) diff --git a/examples/fluid/periodic_channel_2d.jl b/examples/fluid/periodic_channel_2d.jl index 3dbd9f3bab..92b2255ab2 100644 --- a/examples/fluid/periodic_channel_2d.jl +++ b/examples/fluid/periodic_channel_2d.jl @@ -59,10 +59,8 @@ viscosity_wall = nothing # Activate to switch to no-slip walls #viscosity_wall = ViscosityAdami(nu=0.0025 * smoothing_length * sound_speed / 8) -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, viscosity=viscosity_wall) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fluid/pipe_flow_2d.jl b/examples/fluid/pipe_flow_2d.jl index 6022b980e4..1539d9c0f0 100644 --- a/examples/fluid/pipe_flow_2d.jl +++ b/examples/fluid/pipe_flow_2d.jl @@ -136,16 +136,13 @@ outflow = BoundaryZone(; boundary_face=face_out, face_normal=(-flow_direction), initial_condition=outlet.fluid, boundary_type=boundary_type_out) open_boundary = OpenBoundarySystem(inflow, outflow; fluid_system, - boundary_model=open_boundary_model, - buffer_size=n_buffer_particles) + boundary_model=open_boundary_model) # ========================================================================================== # ==== Boundary wall = union(pipe.boundary, inlet.boundary, outlet.boundary) viscosity_boundary = viscosity -boundary_model = BoundaryModelDummyParticles(wall.density, wall.mass, - AdamiPressureExtrapolation(), smoothing_kernel, - smoothing_length; state_equation, +boundary_model = BoundaryModelDummyParticles(wall; fluid_system=fluid_system, viscosity=viscosity_boundary) boundary_system = WallBoundarySystem(wall, boundary_model) diff --git a/examples/fluid/poiseuille_flow_2d.jl b/examples/fluid/poiseuille_flow_2d.jl index ba36a2f471..175571a8f2 100644 --- a/examples/fluid/poiseuille_flow_2d.jl +++ b/examples/fluid/poiseuille_flow_2d.jl @@ -145,16 +145,14 @@ outlet_boundary_zone = BoundaryZone(; boundary_face=outlet_face, open_boundary = OpenBoundarySystem(inlet_boundary_zone, outlet_boundary_zone; fluid_system, boundary_model=open_boundary_model, - calculate_flow_rate=true, - buffer_size=n_buffer_particles) + calculate_flow_rate=true) # ========================================================================================== # ==== Boundary wall_boundary = union(channel.boundary) -boundary_model = BoundaryModelDummyParticles(wall_boundary.density, wall_boundary.mass, - AdamiPressureExtrapolation(), smoothing_kernel, - smoothing_length; state_equation, viscosity) +boundary_model = BoundaryModelDummyParticles(wall_boundary; fluid_system=fluid_system, + viscosity) boundary_system = WallBoundarySystem(wall_boundary, boundary_model) diff --git a/examples/fluid/poiseuille_flow_3d.jl b/examples/fluid/poiseuille_flow_3d.jl index 4459df0648..7d76cc8ffb 100644 --- a/examples/fluid/poiseuille_flow_3d.jl +++ b/examples/fluid/poiseuille_flow_3d.jl @@ -162,14 +162,12 @@ outlet_zone = BoundaryZone(; boundary_face=outlet_face, boundary_type=outlet_boundary_type) open_boundary = OpenBoundarySystem(inlet_zone, outlet_zone; fluid_system, - boundary_model=open_boundary_model, - buffer_size=n_buffer_particles) + boundary_model=open_boundary_model) # ========================================================================================== # ==== Boundary -boundary_model = BoundaryModelDummyParticles(wall_boundary.density, wall_boundary.mass, - AdamiPressureExtrapolation(), smoothing_kernel, - smoothing_length; state_equation, viscosity) +boundary_model = BoundaryModelDummyParticles(wall_boundary; fluid_system=fluid_system, + viscosity) boundary_system = WallBoundarySystem(wall_boundary, boundary_model) diff --git a/examples/fsi/dam_break_gate_2d.jl b/examples/fsi/dam_break_gate_2d.jl index 49d72f2aee..9cc9e66271 100644 --- a/examples/fsi/dam_break_gate_2d.jl +++ b/examples/fsi/dam_break_gate_2d.jl @@ -120,20 +120,15 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothi boundary_density_calculator = AdamiPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model_tank = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +tank_boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, clip_negative_pressure=true) - -boundary_model_gate = BoundaryModelDummyParticles(gate.density, gate.mass, +gate_boundary_model = BoundaryModelDummyParticles(gate; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, clip_negative_pressure=true) -boundary_system_tank = WallBoundarySystem(tank.boundary, boundary_model_tank) -boundary_system_gate = WallBoundarySystem(gate, boundary_model_gate, +boundary_system_tank = WallBoundarySystem(tank.boundary, tank_boundary_model) +boundary_system_gate = WallBoundarySystem(gate, gate_boundary_model, prescribed_motion=gate_movement) # ========================================================================================== diff --git a/examples/fsi/dam_break_plate_2d.jl b/examples/fsi/dam_break_plate_2d.jl index 3f6ff7bba0..ad4a018235 100644 --- a/examples/fsi/dam_break_plate_2d.jl +++ b/examples/fsi/dam_break_plate_2d.jl @@ -90,10 +90,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothi boundary_density_calculator = AdamiPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length; - state_equation, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fsi/falling_rigid_spheres_2d.jl b/examples/fsi/falling_rigid_spheres_2d.jl index 7eaa2b4dcb..59c05ce448 100644 --- a/examples/fsi/falling_rigid_spheres_2d.jl +++ b/examples/fsi/falling_rigid_spheres_2d.jl @@ -70,10 +70,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; boundary_density_calculator = AdamiPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length; - state_equation, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fsi/falling_rotating_rigid_squares_2d.jl b/examples/fsi/falling_rotating_rigid_squares_2d.jl index b4758e39db..3e0a1f60c4 100644 --- a/examples/fsi/falling_rotating_rigid_squares_2d.jl +++ b/examples/fsi/falling_rotating_rigid_squares_2d.jl @@ -86,10 +86,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; boundary_density_calculator = AdamiPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length; - state_equation, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fsi/falling_spheres_2d.jl b/examples/fsi/falling_spheres_2d.jl index 035f9ad3da..136161624f 100644 --- a/examples/fsi/falling_spheres_2d.jl +++ b/examples/fsi/falling_spheres_2d.jl @@ -74,10 +74,8 @@ fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; boundary_density_calculator = BernoulliPressureExtrapolation() # Clip negative boundary pressure values to avoid sticking artifacts at the boundary. -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length; - state_equation, clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fsi/hydrostatic_water_column_2d.jl b/examples/fsi/hydrostatic_water_column_2d.jl index 9fd7e15a36..3815a28d68 100644 --- a/examples/fsi/hydrostatic_water_column_2d.jl +++ b/examples/fsi/hydrostatic_water_column_2d.jl @@ -113,9 +113,8 @@ else damping_coefficient=0.05)) end -boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, +boundary_model = BoundaryModelDummyParticles(tank.boundary; fluid_system=fluid_system, boundary_density_calculator, - smoothing_kernel, smoothing_length_fluid; state_equation) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) boundary_model_structure = BoundaryModelDummyParticles(hydrodynamic_densities, diff --git a/src/schemes/boundary/open_boundary/system.jl b/src/schemes/boundary/open_boundary/system.jl index 3e4754d4ad..1603f37b33 100644 --- a/src/schemes/boundary/open_boundary/system.jl +++ b/src/schemes/boundary/open_boundary/system.jl @@ -1,7 +1,9 @@ @doc raw""" OpenBoundarySystem(boundary_zone::BoundaryZone; - fluid_system::AbstractFluidSystem, buffer_size::Integer, - boundary_model, calculate_flow_rate=false) + fluid_system::AbstractFluidSystem, + buffer_size=default_open_boundary_buffer_size(fluid_system), + boundary_model=BoundaryModelMirroringTafuni(), + calculate_flow_rate=false) Open boundary system for in- and outflow particles. @@ -10,7 +12,10 @@ Open boundary system for in- and outflow particles. # Keywords - `fluid_system`: The corresponding fluid system -- `boundary_model`: Boundary model (see [Open Boundary Models](@ref open_boundary_models)) +- `buffer_size`: Number of buffer particles for the boundary system. + Defaults to the buffer size of `fluid_system`. +- `boundary_model`: Boundary model (see [Open Boundary Models](@ref open_boundary_models)). + Defaults to [`BoundaryModelMirroringTafuni`](@ref). - `calculate_flow_rate=false`: Set to `true` to calculate the volumetric flow rate through each boundary zone. This value is automatically enabled when using [`RCRWindkesselModel`](@ref). Otherwise, it is useful only for postprocessing. @@ -49,6 +54,18 @@ struct OpenBoundarySystem{BM, ELTYPE, NDIMS, IC, FS, FSI, K, ARRAY1D, BC, FC, BZ cache :: C end +function default_open_boundary_buffer_size(fluid_system) + fluid_buffer = buffer(fluid_system) + + if fluid_buffer isa SystemBuffer + return fluid_buffer.buffer_size + end + + throw(ArgumentError("`buffer_size` could not be inferred for `OpenBoundarySystem` " * + "because `fluid_system` has no buffer. Pass `buffer_size=...` " * + "explicitly or construct `fluid_system` with `buffer_size=...`.")) +end + function OpenBoundarySystem(boundary_model, initial_condition, fluid_system, fluid_system_index, smoothing_kernel, smoothing_length, mass, volume, boundary_candidates, fluid_candidates, @@ -70,8 +87,10 @@ function OpenBoundarySystem(boundary_model, initial_condition, fluid_system, end function OpenBoundarySystem(boundary_zones::Union{BoundaryZone, Nothing}...; - fluid_system::AbstractFluidSystem, buffer_size::Integer, - boundary_model, calculate_flow_rate=false, + fluid_system::AbstractFluidSystem, + buffer_size=default_open_boundary_buffer_size(fluid_system), + boundary_model=BoundaryModelMirroringTafuni(), + calculate_flow_rate=false, pressure_acceleration=fluid_system.pressure_acceleration_formulation, shifting_technique=boundary_model isa BoundaryModelDynamicalPressureZhang ? diff --git a/src/schemes/boundary/wall_boundary/dummy_particles.jl b/src/schemes/boundary/wall_boundary/dummy_particles.jl index 6453fc0c2a..faec7ffd19 100644 --- a/src/schemes/boundary/wall_boundary/dummy_particles.jl +++ b/src/schemes/boundary/wall_boundary/dummy_particles.jl @@ -76,6 +76,46 @@ struct BoundaryModelDummyParticles{DC, SE, CLIP, ELTYPE <: Real, VECTOR, K, V, C end end +@doc raw""" + BoundaryModelDummyParticles(initial_condition; + fluid_system::AbstractFluidSystem, + initial_density=initial_condition.density, + hydrodynamic_mass=initial_condition.mass, + boundary_density_calculator=AdamiPressureExtrapolation(), + smoothing_kernel=system_smoothing_kernel(fluid_system), + smoothing_length=initial_smoothing_length(fluid_system), + viscosity=nothing, + state_equation=system_state_equation(fluid_system), + correction=system_correction(fluid_system), + clip_negative_pressure=false, + reference_particle_spacing=default_reference_particle_spacing(fluid_system)) + +High-level convenience constructor for dummy-particle wall models that infers the kernel, +smoothing length, correction, and equation-of-state-related settings from the adjacent +`fluid_system`. +""" +function BoundaryModelDummyParticles(initial_condition; + fluid_system::AbstractFluidSystem, + initial_density=initial_condition.density, + hydrodynamic_mass=initial_condition.mass, + boundary_density_calculator=AdamiPressureExtrapolation(), + smoothing_kernel=system_smoothing_kernel(fluid_system), + smoothing_length=initial_smoothing_length(fluid_system), + viscosity=nothing, + state_equation=system_state_equation(fluid_system), + correction=system_correction(fluid_system), + clip_negative_pressure=false, + reference_particle_spacing=default_reference_particle_spacing(fluid_system)) + return BoundaryModelDummyParticles(initial_density, hydrodynamic_mass, + boundary_density_calculator, smoothing_kernel, + smoothing_length; + viscosity, state_equation, correction, + clip_negative_pressure, + reference_particle_spacing) +end + +# The default constructor needs to be accessible for Adapt.jl to work with this struct. +# See the comments in general/gpu.jl for more details. function BoundaryModelDummyParticles(initial_density, hydrodynamic_mass, density_calculator, smoothing_kernel, smoothing_length; viscosity=nothing, @@ -109,6 +149,15 @@ function BoundaryModelDummyParticles(initial_density, hydrodynamic_mass, clip_negative_pressure) end +@inline function default_reference_particle_spacing(fluid_system) + if hasproperty(fluid_system, :cache) && + hasproperty(fluid_system.cache, :reference_particle_spacing) + return fluid_system.cache.reference_particle_spacing + end + + return zero(eltype(fluid_system)) +end + @inline function Base.ndims(boundary_model::BoundaryModelDummyParticles) return ndims(boundary_model.smoothing_kernel) end diff --git a/src/schemes/fluid/implicit_incompressible_sph/system.jl b/src/schemes/fluid/implicit_incompressible_sph/system.jl index 6e54ce7b66..e12ffbd283 100644 --- a/src/schemes/fluid/implicit_incompressible_sph/system.jl +++ b/src/schemes/fluid/implicit_incompressible_sph/system.jl @@ -199,6 +199,8 @@ end return system.density end +@inline system_state_equation(system::ImplicitIncompressibleSPHSystem) = nothing + # TODO: What do we do with the sound speed? This is needed for the viscosity. @inline system_sound_speed(system::ImplicitIncompressibleSPHSystem) = system.artificial_sound_speed diff --git a/test/systems/boundary_system.jl b/test/systems/boundary_system.jl index bcf9b82098..8ce39b479e 100644 --- a/test/systems/boundary_system.jl +++ b/test/systems/boundary_system.jl @@ -28,6 +28,55 @@ end end + @testset verbose=true "High-level Dummy-Particle Builder" begin + boundary_coordinates = [1.0 2.0 + 1.0 2.0] + fluid_coordinates = [0.0 0.5 + 0.0 0.0] + + boundary_ic = InitialCondition(; coordinates=boundary_coordinates, mass, density) + fluid_ic = InitialCondition(; coordinates=fluid_coordinates, mass, density) + + smoothing_kernel = SchoenbergCubicSplineKernel{2}() + smoothing_length = 0.8 + state_equation = StateEquationCole(; sound_speed=15.0, reference_density=1000.0, + exponent=1) + viscosity = ViscosityAdami(nu=1e-6) + + fluid_system = WeaklyCompressibleSPHSystem(fluid_ic; + density_calculator=ContinuityDensity(), + state_equation, smoothing_kernel, + smoothing_length, + correction=KernelCorrection(), + reference_particle_spacing=0.1) + + boundary_model = BoundaryModelDummyParticles(boundary_ic; + fluid_system=fluid_system, + viscosity=viscosity) + system = WallBoundarySystem(boundary_ic, boundary_model, + adhesion_coefficient=0.3, + color_value=2) + + @test system isa WallBoundarySystem + @test system.boundary_model isa BoundaryModelDummyParticles + @test system.boundary_model.hydrodynamic_mass == boundary_ic.mass + @test system.boundary_model.density_calculator isa AdamiPressureExtrapolation + @test system.boundary_model.smoothing_kernel === smoothing_kernel + @test system.boundary_model.smoothing_length == smoothing_length + @test system.boundary_model.viscosity == viscosity + @test system.boundary_model.state_equation == state_equation + @test system.boundary_model.correction isa KernelCorrection + @test system.boundary_model.cache.reference_particle_spacing == 0.1 + @test system.adhesion_coefficient == 0.3 + @test system.cache.color == 2 + + edac_system = EntropicallyDampedSPHSystem(fluid_ic; smoothing_kernel, + smoothing_length, sound_speed=15.0) + edac_boundary_model = BoundaryModelDummyParticles(boundary_ic; + fluid_system=edac_system) + @test edac_boundary_model.state_equation === nothing + end + @testset verbose=true "Moving Boundaries" begin @testset "$(i+1)D" for i in 1:2 NDIMS = i + 1 diff --git a/test/systems/iisph_system.jl b/test/systems/iisph_system.jl index 2bcd740552..3d8dc65aa3 100644 --- a/test/systems/iisph_system.jl +++ b/test/systems/iisph_system.jl @@ -68,6 +68,7 @@ @test system.max_iterations == max_iterations @test system.time_step == time_step @test length(system.density) == size(coordinates, 2) + @test TrixiParticles.system_state_equation(system) === nothing # A too-short acceleration vector triggers dimension validation error_str1 = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" diff --git a/test/systems/open_boundary_system.jl b/test/systems/open_boundary_system.jl index e9481be303..3a346f9ef9 100644 --- a/test/systems/open_boundary_system.jl +++ b/test/systems/open_boundary_system.jl @@ -2,14 +2,16 @@ @testset "`show`" begin # Mock fluid system - struct FluidSystemMock2 <: TrixiParticles.AbstractFluidSystem{2} + struct FluidSystemMock2{B} <: TrixiParticles.AbstractFluidSystem{2} pressure_acceleration_formulation::Nothing density_diffusion::Nothing + buffer::B end TrixiParticles.initial_smoothing_length(system::FluidSystemMock2) = 1.0 TrixiParticles.nparticles(system::FluidSystemMock2) = 1 TrixiParticles.system_smoothing_kernel(system::FluidSystemMock2) = nothing TrixiParticles.density_calculator(system::FluidSystemMock2) = TrixiParticles.ContinuityDensity() + TrixiParticles.buffer(system::FluidSystemMock2) = system.buffer inflow = BoundaryZone(; boundary_face=([0.0, 0.0], [0.0, 1.0]), particle_spacing=0.05, @@ -17,7 +19,8 @@ open_boundary_layers=4, boundary_type=InFlow()) system = OpenBoundarySystem(inflow; buffer_size=0, boundary_model=BoundaryModelCharacteristicsLastiwka(), - fluid_system=FluidSystemMock2(nothing, nothing)) + fluid_system=FluidSystemMock2(nothing, nothing, + nothing)) show_compact = "OpenBoundarySystem{2}() with 80 particles" @test repr(system) == show_compact @@ -40,7 +43,8 @@ boundary_type=OutFlow()) system = OpenBoundarySystem(outflow; buffer_size=0, boundary_model=BoundaryModelMirroringTafuni(), - fluid_system=FluidSystemMock2(nothing, nothing)) + fluid_system=FluidSystemMock2(nothing, nothing, + nothing)) show_compact = "OpenBoundarySystem{2}() with 80 particles" @test repr(system) == show_compact @@ -59,7 +63,8 @@ system = OpenBoundarySystem(outflow, inflow; buffer_size=0, boundary_model=BoundaryModelMirroringTafuni(), - fluid_system=FluidSystemMock2(nothing, nothing)) + fluid_system=FluidSystemMock2(nothing, nothing, + nothing)) show_compact = "OpenBoundarySystem{2}() with 160 particles" @test repr(system) == show_compact @@ -78,7 +83,8 @@ system = OpenBoundarySystem(outflow, inflow; buffer_size=0, boundary_model=BoundaryModelDynamicalPressureZhang(), - fluid_system=FluidSystemMock2(nothing, nothing)) + fluid_system=FluidSystemMock2(nothing, nothing, + nothing)) show_compact = "OpenBoundarySystem{2}() with 160 particles" @test repr(system) == show_compact @@ -96,5 +102,19 @@ └──────────────────────────────────────────────────────────────────────────────────────────────────┘""" @test repr("text/plain", system) == show_box + + fluid_system_with_buffer = FluidSystemMock2(nothing, nothing, + TrixiParticles.SystemBuffer(1, 3)) + system = OpenBoundarySystem(outflow; fluid_system=fluid_system_with_buffer) + @test system.boundary_model isa BoundaryModelMirroringTafuni + @test system.buffer.buffer_size == 3 + + error_str = "`buffer_size` could not be inferred for `OpenBoundarySystem` " * + "because `fluid_system` has no buffer. Pass `buffer_size=...` " * + "explicitly or construct `fluid_system` with `buffer_size=...`." + @test_throws ArgumentError(error_str) OpenBoundarySystem(outflow; + fluid_system=FluidSystemMock2(nothing, + nothing, + nothing)) end end