|
| 1 | +# Lid-driven cavity |
| 2 | +# |
| 3 | +# S. Adami et al |
| 4 | +# "A transport-velocity formulation for smoothed particle hydrodynamics". |
| 5 | +# In: Journal of Computational Physics, Volume 241 (2013), pages 292-307. |
| 6 | +# https://doi.org/10.1016/j.jcp.2013.01.043 |
| 7 | + |
| 8 | +using TrixiParticles |
| 9 | +using OrdinaryDiffEq |
| 10 | + |
| 11 | +# ========================================================================================== |
| 12 | +# ==== Resolution |
| 13 | +particle_spacing = 0.02 |
| 14 | + |
| 15 | +# Make sure that the kernel support of fluid particles at a boundary is always fully sampled |
| 16 | +boundary_layers = 4 |
| 17 | + |
| 18 | +# ========================================================================================== |
| 19 | +# ==== Experiment Setup |
| 20 | +tspan = (0.0, 5.0) |
| 21 | +reynolds_number = 100.0 |
| 22 | + |
| 23 | +cavity_size = (1.0, 1.0) |
| 24 | + |
| 25 | +fluid_density = 1.0 |
| 26 | + |
| 27 | +const VELOCITY_LID = 1.0 |
| 28 | +sound_speed = 10 * VELOCITY_LID |
| 29 | + |
| 30 | +pressure = sound_speed^2 * fluid_density |
| 31 | + |
| 32 | +viscosity = ViscosityAdami(; nu=VELOCITY_LID / reynolds_number) |
| 33 | + |
| 34 | +cavity = RectangularTank(particle_spacing, cavity_size, cavity_size, fluid_density, |
| 35 | + n_layers=boundary_layers, |
| 36 | + faces=(true, true, true, false), pressure=pressure) |
| 37 | + |
| 38 | +lid_position = 0.0 - particle_spacing * boundary_layers |
| 39 | +lid_length = cavity.n_particles_per_dimension[1] + 2boundary_layers |
| 40 | + |
| 41 | +lid = RectangularShape(particle_spacing, (lid_length, 3), |
| 42 | + (lid_position, cavity_size[2]), density=fluid_density) |
| 43 | + |
| 44 | +# ========================================================================================== |
| 45 | +# ==== Fluid |
| 46 | + |
| 47 | +smoothing_length = 1.0 * particle_spacing |
| 48 | +smoothing_kernel = SchoenbergQuinticSplineKernel{2}() |
| 49 | + |
| 50 | +fluid_system = EntropicallyDampedSPHSystem(cavity.fluid, smoothing_kernel, smoothing_length, |
| 51 | + density_calculator=ContinuityDensity(), |
| 52 | + sound_speed, viscosity=viscosity, |
| 53 | + transport_velocity=TransportVelocityAdami(pressure)) |
| 54 | + |
| 55 | +# ========================================================================================== |
| 56 | +# ==== Boundary |
| 57 | + |
| 58 | +lid_movement_function(t) = SVector(VELOCITY_LID * t, 0.0) |
| 59 | + |
| 60 | +is_moving(t) = true |
| 61 | + |
| 62 | +lid_movement = BoundaryMovement(lid_movement_function, is_moving) |
| 63 | + |
| 64 | +boundary_model_cavity = BoundaryModelDummyParticles(cavity.boundary.density, |
| 65 | + cavity.boundary.mass, |
| 66 | + AdamiPressureExtrapolation(), |
| 67 | + viscosity=viscosity, |
| 68 | + smoothing_kernel, smoothing_length) |
| 69 | + |
| 70 | +boundary_model_lid = BoundaryModelDummyParticles(lid.density, lid.mass, |
| 71 | + AdamiPressureExtrapolation(), |
| 72 | + viscosity=viscosity, |
| 73 | + smoothing_kernel, smoothing_length) |
| 74 | + |
| 75 | +boundary_system_cavity = BoundarySPHSystem(cavity.boundary, boundary_model_cavity) |
| 76 | + |
| 77 | +boundary_system_lid = BoundarySPHSystem(lid, boundary_model_lid, movement=lid_movement) |
| 78 | + |
| 79 | +# ========================================================================================== |
| 80 | +# ==== Simulation |
| 81 | +bnd_thickness = boundary_layers * particle_spacing |
| 82 | +periodic_box = PeriodicBox(min_corner=[-bnd_thickness, -bnd_thickness], |
| 83 | + max_corner=cavity_size .+ [bnd_thickness, bnd_thickness]) |
| 84 | + |
| 85 | +semi = Semidiscretization(fluid_system, boundary_system_cavity, boundary_system_lid, |
| 86 | + neighborhood_search=GridNeighborhoodSearch{2}(; periodic_box)) |
| 87 | + |
| 88 | +ode = semidiscretize(semi, tspan) |
| 89 | + |
| 90 | +info_callback = InfoCallback(interval=100) |
| 91 | + |
| 92 | +saving_callback = SolutionSavingCallback(dt=0.02) |
| 93 | + |
| 94 | +pp_callback = nothing |
| 95 | + |
| 96 | +callbacks = CallbackSet(info_callback, saving_callback, pp_callback, UpdateCallback()) |
| 97 | + |
| 98 | +# Use a Runge-Kutta method with automatic (error based) time step size control |
| 99 | +sol = solve(ode, RDPK3SpFSAL49(), |
| 100 | + abstol=1e-6, # Default abstol is 1e-6 (may needs to be tuned to prevent boundary penetration) |
| 101 | + reltol=1e-4, # Default reltol is 1e-3 (may needs to be tuned to prevent boundary penetration) |
| 102 | + dtmax=1e-2, # Limit stepsize to prevent crashing |
| 103 | + maxiters=Int(1e7), |
| 104 | + save_everystep=false, callback=callbacks); |
0 commit comments