diff --git a/NEWS.md b/NEWS.md index 6aa6942134..8d4b321b91 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,86 @@ used in the Julia ecosystem. Notable changes will be documented in this file for ### API Changes +- Clipping of negative pressure values in the `BoundaryModelDummyParticles` is now disabled + by default and can be enabled with the keyword argument `clip_negative_pressure=true` (#1143). +- The example files are now loading sub-packages of OrdinaryDiffEq.jl instead of + OrdinaryDiffEq.jl itself. For example, `using OrdinaryDiffEqLowStorageRK` instead of + `using OrdinaryDiffEq` (#1154). +- `DensityDiffusionAntuono` now only has the kwarg `delta` and no positional + arguments (#1142). +- Return type of `vtk2trixi` changed to `NamedTuple` including an optional + `:initial_condition` field if `create_initial_condition=true` is passed (#959). +- Public system constructors now use keyword arguments for configuration values. + This affects `WeaklyCompressibleSPHSystem`, `EntropicallyDampedSPHSystem`, + `ImplicitIncompressibleSPHSystem`, `TotalLagrangianSPHSystem`, `DEMSystem`, + and `BoundaryDEMSystem`. + +#### Migration Guide for Keyword-Based System Constructors + +The initial condition remains the only positional argument for the affected system +constructors. All method, material, and configuration arguments that were previously +passed positionally now need to be passed as keywords. +Existing optional keyword arguments remain available. For example, the +`density_calculator` keyword of `EntropicallyDampedSPHSystem` still defaults to +`SummationDensity()`. + +Here are examples, where `ic` is the initial condition, `kernel` is the +smoothing kernel, and `h` is the smoothing length: + +```julia +WeaklyCompressibleSPHSystem(ic, density_calculator, state_equation, kernel, h; + kwargs...) +# becomes +WeaklyCompressibleSPHSystem(ic; smoothing_kernel=kernel, smoothing_length=h, + density_calculator, state_equation, kwargs...) + +EntropicallyDampedSPHSystem(ic, kernel, h, sound_speed; kwargs...) +# becomes +EntropicallyDampedSPHSystem(ic; smoothing_kernel=kernel, smoothing_length=h, + sound_speed, kwargs...) + +ImplicitIncompressibleSPHSystem(ic, kernel, h, reference_density; kwargs...) +# becomes +ImplicitIncompressibleSPHSystem(ic; smoothing_kernel=kernel, smoothing_length=h, + reference_density, kwargs...) + +TotalLagrangianSPHSystem(ic, kernel, h, young_modulus, poisson_ratio; kwargs...) +# becomes +TotalLagrangianSPHSystem(ic; smoothing_kernel=kernel, smoothing_length=h, + young_modulus, poisson_ratio, kwargs...) + +DEMSystem(ic, contact_model; kwargs...) +# becomes +DEMSystem(ic; contact_model, kwargs...) + +BoundaryDEMSystem(ic, normal_stiffness) +# becomes +BoundaryDEMSystem(ic; normal_stiffness) +``` + +### Performance + +- Greatly improved GPU performance of WCSPH and TLSPH + (#1128, #1117, #1124, #1125, #1130, #1116, #1139, #1149). + See [#1131](https://github.com/trixi-framework/TrixiParticles.jl/issues/1131) + for a detailed breakdown including benchmark results. + +### Features + +- Added a `SortingCallback` that can be used to sort particles by their spatial location + to improve performance (#1044). + +### Important Bugfixes + +- Fixed a bug where `DensityDiffusionAntuono` could not be used together with open + boundaries and `BoundaryModelDynamicalPressureZhang` (#1043). +- Fixed a bug where no-slip boundary conditions were not applied correctly when not using + `ViscosityAdami` (#1089). + +## Version 0.4.4 + +### API Changes + - Custom quantities called in the `PostprocessCallback` are now passed CPU arrays when the simulation is run on a GPU (#1065). @@ -21,13 +101,6 @@ used in the Julia ecosystem. Notable changes will be documented in this file for - Added new validation case hydrostatic water column (#724). - Added Carreau–Yasuda non-Newtonian viscosity model (#1010). -### Performance - -- Greatly improved GPU performance of WCSPH and TLSPH - (#1128, #1117, #1124, #1125, #1130, #1116, #1139, #1149). - See [#1131](https://github.com/trixi-framework/TrixiParticles.jl/issues/1131) - for a detailed breakdown including benchmark results. - ### Important Bugfixes - Fixed the periodic array of cylinders example file (#975). @@ -62,7 +135,6 @@ used in the Julia ecosystem. Notable changes will be documented in this file for - Added GPU and FP32 support for DEM (#979). - ### Performance - Improved GPU performance with shifting up to a factor of 10x (#974, #993). diff --git a/Project.toml b/Project.toml index 5abc6ed179..d5adea8c81 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "TrixiParticles" uuid = "66699cd8-9c01-4e9d-a059-b96c86d16b3a" -version = "0.4.5-dev" +version = "0.5" authors = ["erik.faulhaber <44124897+efaulhaber@users.noreply.github.com>"] [deps] diff --git a/README.md b/README.md index abf3fa066c..e9e9eb2957 100644 --- a/README.md +++ b/README.md @@ -75,13 +75,14 @@ with Julia v1.10 and newer. We recommend using the latest stable release of Juli ### For users TrixiParticles.jl is a registered Julia package. You can install TrixiParticles.jl, -[OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) (used for time integration) -and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) by executing the following commands +time integration sub-packages of [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) +(for example `OrdinaryDiffEqLowStorageRK`), and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) +by executing the following commands in the Julia REPL: ```julia julia> using Pkg -julia> Pkg.add(["TrixiParticles", "OrdinaryDiffEq", "Plots"]) +julia> Pkg.add(["TrixiParticles", "OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqSymplecticRK", "Plots"]) ``` ### For developers @@ -92,7 +93,7 @@ git clone git@github.com:trixi-framework/TrixiParticles.jl.git cd TrixiParticles.jl mkdir run julia --project=run -e 'using Pkg; Pkg.develop(PackageSpec(path="."))' # Add TrixiParticles.jl to `run` project -julia --project=run -e 'using Pkg; Pkg.add(["OrdinaryDiffEq", "Plots"])' # Add additional packages +julia --project=run -e 'using Pkg; Pkg.add(["OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqSymplecticRK", "Plots"])' # Add additional packages ``` If you installed TrixiParticles.jl this way, you always have to start Julia with the @@ -133,7 +134,7 @@ You can find the documentation for the latest release [![arXiv:2506.21206](https://img.shields.io/badge/arXiv-2506.21206-yellow)](https://arxiv.org/abs/2506.21206) [![doi:10.1016/j.cpc.2025.109898](https://zenodo.org/badge/doi/10.1016/j.cpc.2025.109898.svg)](https://doi.org/10.1016/j.cpc.2025.109898) [![reproduce me!](https://img.shields.io/badge/reproduce-me!-brightgreen)](https://github.com/trixi-framework/paper-2025-particle-based_preprocessing) - + ## Cite Us If you use TrixiParticles.jl in your own research or write a paper using results obtained @@ -190,4 +191,3 @@ or [create an issue](https://github.com/trixi-framework/TrixiParticles.jl/issues

The project has benefited from funding from [hereon](https://www.hereon.de/), [HiRSE](https://www.helmholtz-hirse.de/), and through [ScienceServe](https://www.helmholtz.de/en/research/current-calls-for-applications/article/scienceserve-boosting-research-software-at-helmholtz/) for the MATRIX project. - diff --git a/docs/Project.toml b/docs/Project.toml index 68c8cb9d70..eb8b6dfeec 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -5,7 +5,7 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" DocumenterMermaid = "a078cd44-4d9c-4618-b545-3ab9d77f9177" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +OrdinaryDiffEqLowStorageRK = "b0944070-b475-4768-8dec-fb6eb410534d" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" [compat] @@ -15,5 +15,5 @@ Documenter = "1" DocumenterCitations = "1" DocumenterMermaid = "0.2" Literate = "2" -OrdinaryDiffEq = "6" +OrdinaryDiffEqLowStorageRK = "1" Plots = "1" diff --git a/docs/literate/src/tut_custom_kernel.jl b/docs/literate/src/tut_custom_kernel.jl index 053f0c74a0..6169ce42fc 100644 --- a/docs/literate/src/tut_custom_kernel.jl +++ b/docs/literate/src/tut_custom_kernel.jl @@ -4,11 +4,12 @@ # of TrixiParticles.jl by custom implementations from within a simulation file, # without ever cloning the repository. -# First, we import TrixiParticles.jl and +# First, we import TrixiParticles.jl and the time integration sub-package +# `OrdinaryDiffEqLowStorageRK` of # [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl), which we will # use at the very end for the time integration. using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ## Load a simulation file @@ -117,13 +118,12 @@ nothing # hide # `examples/fluid/dam_break_2d.jl` with our custom kernel and the corresponding # smoothing length. # ```@cast @__NAME__; width=100, height=50, delay=0, loop=true, loop_delay=5 -# trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), +# trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); # smoothing_kernel=MyGaussianKernel(), -# smoothing_length=smoothing_length); +# smoothing_length); # ``` -trixi_include(joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), #!md - smoothing_kernel=MyGaussianKernel(), #!md - smoothing_length=smoothing_length) #!md +trixi_include(joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); #!md + smoothing_kernel=MyGaussianKernel(), smoothing_length) #!md # See [Visualization](@ref) for how to visualize the final solution. # For the simplest visualization, we can use [Plots.jl](https://docs.juliaplots.org/stable/): diff --git a/docs/literate/src/tut_packing.jl b/docs/literate/src/tut_packing.jl index b7d492779b..d5b9610283 100644 --- a/docs/literate/src/tut_packing.jl +++ b/docs/literate/src/tut_packing.jl @@ -48,8 +48,8 @@ signed_distance_field = SignedDistanceField(geometry, particle_spacing; # We can also visualize the SDF by simply creating an `InitialCondition` from the sampled points and plot it. # The color coding represents the signed distance to the geometry surface. -sdf_ic = InitialCondition(; coordinates=stack(signed_distance_field.positions), - density=1.0, particle_spacing=particle_spacing) +sdf_ic = InitialCondition(; coordinates=stack(signed_distance_field.positions), density=1.0, + particle_spacing) plot(sdf_ic, zcolor=signed_distance_field.distances, label=nothing, color=:coolwarm) plot!(geometry, linestyle=:dash, label=nothing, showaxis=false, color=:black, @@ -63,8 +63,8 @@ signed_distance_field = SignedDistanceField(geometry, particle_spacing; max_signed_distance=boundary_thickness) # We can see in the plot that the SDF has been extended outwards to twice `max_signed_distance`. -sdf_ic = InitialCondition(; coordinates=stack(signed_distance_field.positions), - density=1.0, particle_spacing=particle_spacing) +sdf_ic = InitialCondition(; coordinates=stack(signed_distance_field.positions), density=1.0, + particle_spacing) plot(sdf_ic, zcolor=signed_distance_field.distances, label=nothing, color=:coolwarm) @@ -105,7 +105,7 @@ point_in_geometry_algorithm = WindingNumberJacobson(; geometry) # This function creates an [`InitialCondition`](@ref InitialCondition) for the interior particles. # Here, we need to specify `particle_spacing` and `density`. For further arguments, please refer to # the documentation of [ComplexShape](@ref ComplexShape) or [InitialCondition](@ref InitialCondition). -shape_sampled = ComplexShape(geometry; particle_spacing, density=density, +shape_sampled = ComplexShape(geometry; particle_spacing, density, point_in_geometry_algorithm) # If we want to assign the mass of each sampled particle consistently with its density, @@ -130,8 +130,9 @@ plot!(geometry, linestyle=:dash, label=nothing, showaxis=false, color=:black, # which does not represent any physical law. Instead, we only use the simulation framework to time-integrate # the packing process. -# We first need to import [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl). -using OrdinaryDiffEq +# We first need to import `OrdinaryDiffEqLowStorageRK`, a time integration sub-package +# of [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl). +using OrdinaryDiffEqLowStorageRK # Next, we set a background pressure. This can be chosen arbitrarily. # A higher value results in smaller time steps, but the final packed state @@ -146,9 +147,7 @@ smoothing_length = 0.8 * particle_spacing # Now we can create the packing system. For learning purposes, let’s first try # passing no signed distance field (SDF) and see what happens. -packing_system = ParticlePackingSystem(shape_sampled; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, +packing_system = ParticlePackingSystem(shape_sampled; smoothing_kernel, smoothing_length, signed_distance_field=nothing, background_pressure) # We now proceed with the familiar steps @@ -163,8 +162,7 @@ maxiters = 100 callbacks = CallbackSet(UpdateCallback()) time_integrator = RDPK3SpFSAL35() -sol = solve(ode, time_integrator; - abstol=1e-7, reltol=1e-4, save_everystep=false, maxiters=maxiters, +sol = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, save_everystep=false, maxiters, callback=callbacks) packed_ic = InitialCondition(sol, packing_system, semi) @@ -176,11 +174,8 @@ plot!(geometry, seriestype=:path, linewidth=2, color=:black, label=nothing) # geometric surface. # We therefore add an SDF for the geometry and repeat the same procedure. -packing_system = ParticlePackingSystem(shape_sampled; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - signed_distance_field, - background_pressure) +packing_system = ParticlePackingSystem(shape_sampled; smoothing_kernel, smoothing_length, + signed_distance_field, background_pressure) # Again, we follow the same steps for semidiscretization and time integration. semi = Semidiscretization(packing_system) @@ -192,8 +187,7 @@ maxiters = 1000 callbacks = CallbackSet(UpdateCallback()) time_integrator = RDPK3SpFSAL35() -sol = solve(ode, time_integrator; - abstol=1e-7, reltol=1e-4, save_everystep=false, maxiters=maxiters, +sol = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, save_everystep=false, maxiters, callback=callbacks) packed_ic = InitialCondition(sol, packing_system, semi) @@ -214,12 +208,10 @@ plot!(geometry, seriestype=:path, color=:black, label=nothing, linewidth=2) # A `boundary_compress_factor` of `0.8` or `0.9` works well for most shapes. # Since we have a relatively large particle spacing compared to the # geometry size in this example, we will choose `0.7`. -boundary_system = ParticlePackingSystem(boundary_sampled; - is_boundary=true, - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - boundary_compress_factor=0.7, - signed_distance_field, background_pressure) +boundary_system = ParticlePackingSystem(boundary_sampled; is_boundary=true, + smoothing_kernel, smoothing_length, + boundary_compress_factor=0.7, signed_distance_field, + background_pressure) # We can now couple the boundary system with the interior system: semi = Semidiscretization(packing_system, boundary_system) @@ -231,8 +223,7 @@ maxiters = 1000 callbacks = CallbackSet(UpdateCallback()) time_integrator = RDPK3SpFSAL35() -sol = solve(ode, time_integrator; - abstol=1e-7, reltol=1e-4, save_everystep=false, maxiters=maxiters, +sol = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, save_everystep=false, maxiters, callback=callbacks) packed_ic = InitialCondition(sol, packing_system, semi) @@ -254,11 +245,8 @@ plot!(geometry, seriestype=:path, color=:black, linestyle=:dash, linewidth=2, la # Because we are satisfied with this particle distribution, we want it to remain unchanged. # Therefore, we set `fixed_system=true` so that this system is not integrated further # but instead serves as a static boundary for the packing of other domains. -fixed_system = ParticlePackingSystem(packed_ic; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - signed_distance_field=nothing, - background_pressure, +fixed_system = ParticlePackingSystem(packed_ic; smoothing_kernel, smoothing_length, + signed_distance_field=nothing, background_pressure, fixed_system=true) # Now we define a rectangular domain that we want to pack. @@ -273,10 +261,8 @@ sampled_outer_domain = setdiff(tank_domain.fluid, packed_ic) plot(sampled_outer_domain, packed_ic) # Next, we create a packing system for the outer domain. -packing_system = ParticlePackingSystem(sampled_outer_domain; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - signed_distance_field=nothing, +packing_system = ParticlePackingSystem(sampled_outer_domain; smoothing_kernel, + smoothing_length, signed_distance_field=nothing, background_pressure) # Since we do not want to sample a boundary for the outer domain, @@ -293,8 +279,8 @@ maxiters = 1000 callbacks = CallbackSet(UpdateCallback()) time_integrator = RDPK3SpFSAL35() -sol_1 = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, - save_everystep=false, maxiters=maxiters, callback=callbacks) +sol_1 = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, save_everystep=false, + maxiters, callback=callbacks) packed_outer_domain = InitialCondition(sol_1, packing_system, semi) @@ -323,24 +309,17 @@ plot(pack_domain, fixed_domain, packed_ic) # We can now treat the particles outside the window, along with the already # finalized configuration of the complex geometry, as fixed systems: -fixed_system_1 = ParticlePackingSystem(fixed_domain; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - signed_distance_field=nothing, - background_pressure, fixed_system=true) - -fixed_system_2 = ParticlePackingSystem(packed_ic; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - signed_distance_field=nothing, - background_pressure, fixed_system=true) +fixed_system_1 = ParticlePackingSystem(fixed_domain; smoothing_kernel, smoothing_length, + signed_distance_field=nothing, background_pressure, + fixed_system=true) + +fixed_system_2 = ParticlePackingSystem(packed_ic; smoothing_kernel, smoothing_length, + signed_distance_field=nothing, background_pressure, + fixed_system=true) # The window that we want to pack is passed to a moving packing system: -packing_system = ParticlePackingSystem(pack_domain; - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - signed_distance_field=nothing, - background_pressure) +packing_system = ParticlePackingSystem(pack_domain; smoothing_kernel, smoothing_length, + signed_distance_field=nothing, background_pressure) semi = Semidiscretization(packing_system, fixed_system_1, fixed_system_2) @@ -351,8 +330,8 @@ maxiters = 1000 callbacks = CallbackSet(UpdateCallback()) time_integrator = RDPK3SpFSAL35() -sol_2 = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, - save_everystep=false, maxiters=maxiters, callback=callbacks) +sol_2 = solve(ode, time_integrator; abstol=1e-7, reltol=1e-4, save_everystep=false, + maxiters, callback=callbacks) packed_fluid_domain = InitialCondition(sol_2, packing_system, semi) diff --git a/docs/literate/src/tut_rigid_body_fsi.jl b/docs/literate/src/tut_rigid_body_fsi.jl index 5f11a3d561..6175439484 100644 --- a/docs/literate/src/tut_rigid_body_fsi.jl +++ b/docs/literate/src/tut_rigid_body_fsi.jl @@ -14,7 +14,7 @@ # 4. Using a different geometry. using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK using Plots # ## Resolution and basic setup @@ -42,10 +42,10 @@ sound_speed = 100.0 state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - faces=(true, true, true, false), - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + faces=(true, true, true, false), acceleration=(0.0, -gravity), + state_equation) nothing # hide # ## Rigid body geometry @@ -97,10 +97,11 @@ fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; + smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, acceleration=(0.0, -gravity)) nothing # hide @@ -166,10 +167,10 @@ nothing # hide boundary_density_calculator = AdamiPressureExtrapolation() tank_boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) + fluid_smoothing_length; + state_equation) boundary_system = WallBoundarySystem(tank.boundary, tank_boundary_model) nothing # hide @@ -180,10 +181,10 @@ function rigid_body_boundary_model(shape) structure_particle_spacing^ndims(fluid_system) return BoundaryModelDummyParticles(hydrodynamic_densities, hydrodynamic_masses, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) + fluid_smoothing_length; + state_equation) end square1_boundary_model = rigid_body_boundary_model(square1) @@ -234,15 +235,11 @@ contact_model = RigidContactModel(; normal_stiffness=2.0e5, contact_distance=2.0 * structure_particle_spacing) nothing # hide -rigid_body_system_1_step3 = RigidBodySystem(square1; - boundary_model=square1_boundary_model, - contact_model=contact_model, - acceleration=(0.0, -gravity), +rigid_body_system_1_step3 = RigidBodySystem(square1; boundary_model=square1_boundary_model, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) -rigid_body_system_2_step3 = RigidBodySystem(square2; - boundary_model=square2_boundary_model, - contact_model=contact_model, - acceleration=(0.0, -gravity), +rigid_body_system_2_step3 = RigidBodySystem(square2; boundary_model=square2_boundary_model, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) nothing # hide @@ -301,15 +298,11 @@ circle1_boundary_model = rigid_body_boundary_model(circle1) circle2_boundary_model = rigid_body_boundary_model(circle2) nothing # hide -rigid_body_system_1_step4 = RigidBodySystem(circle1; - boundary_model=circle1_boundary_model, - contact_model=contact_model, - acceleration=(0.0, -gravity), +rigid_body_system_1_step4 = RigidBodySystem(circle1; boundary_model=circle1_boundary_model, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) -rigid_body_system_2_step4 = RigidBodySystem(circle2; - boundary_model=circle2_boundary_model, - contact_model=contact_model, - acceleration=(0.0, -gravity), +rigid_body_system_2_step4 = RigidBodySystem(circle2; boundary_model=circle2_boundary_model, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) nothing # hide @@ -359,10 +352,8 @@ small_spheres = [SphereShape(structure_particle_spacing, small_sphere_radius, small_sphere_systems = [begin sphere_boundary_model = rigid_body_boundary_model(sphere) - RigidBodySystem(sphere; - boundary_model=sphere_boundary_model, - contact_model=contact_model, - acceleration=(0.0, -gravity), + RigidBodySystem(sphere; boundary_model=sphere_boundary_model, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) end for sphere in small_spheres] @@ -418,10 +409,8 @@ hexagon_shape = TrixiParticles.@set hexagon_shape.particle_spacing = structure_p # just like the other shapes in this tutorial. hexagon_boundary_model = rigid_body_boundary_model(hexagon_shape) -hexagon_system = RigidBodySystem(hexagon_shape; - boundary_model=hexagon_boundary_model, - contact_model=contact_model, - acceleration=(0.0, -gravity), +hexagon_system = RigidBodySystem(hexagon_shape; boundary_model=hexagon_boundary_model, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) # # You can then create a semidiscretization with this new system. diff --git a/docs/literate/src/tut_setup.jl b/docs/literate/src/tut_setup.jl index 67e54bdcd3..b546c5eb89 100644 --- a/docs/literate/src/tut_setup.jl +++ b/docs/literate/src/tut_setup.jl @@ -6,11 +6,12 @@ # which is one of our simplest example simulations. # For different setups and physics, take a look at [our other example files](@ref examples). -# First, we import TrixiParticles.jl and +# First, we import TrixiParticles.jl and the time integration sub-package +# `OrdinaryDiffEqLowStorageRK` of # [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl), which we will # use at the very end for the time integration. using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ## Resolution @@ -79,9 +80,9 @@ nothing # hide # Here, we use the [`RectangularTank`](@ref) setup, which generates a rectangular # fluid inside a rectangular tank, and supports a hydrostatic pressure gradient # by passing a gravitational acceleration and a state equation (see above). -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, - fluid_density, n_layers=boundary_layers, - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, acceleration=(0.0, -gravity), + state_equation) nothing # hide # A `RectangularTank` consists of two [`InitialCondition`](@ref)s, `tank.fluid` and `tank.boundary`. # We can plot these initial conditions to visualize the initial setup. @@ -120,10 +121,9 @@ nothing # hide # The simulation quality greatly benefits from using [density diffusion](@ref density_diffusion). fluid_density_calculator = ContinuityDensity() density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, acceleration=(0.0, -gravity)) nothing # hide @@ -136,9 +136,9 @@ nothing # hide # 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, - state_equation=state_equation, AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) nothing # hide @@ -169,7 +169,7 @@ nothing # hide # We also want to save the current solution in regular intervals in terms of # simulation time as VTK, so that we can [look at the solution in ParaView](@ref Visualization). # The [`SolutionSavingCallback`](@ref) provides this functionality. -# To pass the callbacks to OrdinaryDiffEq.jl, we have to bundle them into a +# To pass the callbacks to the solver, we have to bundle them into a # `CallbackSet`. info_callback = InfoCallback(interval=50) saving_callback = SolutionSavingCallback(dt=0.02) @@ -178,7 +178,8 @@ callbacks = CallbackSet(info_callback, saving_callback) nothing # hide # Finally, we can start the simulation by solving the `ODEProblem`. -# We use the method `RDPK3SpFSAL35` of OrdinaryDiffEq.jl, which is a Runge-Kutta +# We use the method `RDPK3SpFSAL35` from `OrdinaryDiffEqLowStorageRK`, +# which is a Runge-Kutta # method with automatic (error based) time step size control. # This method is usually a good choice for prototyping, since we do not have to # worry about choosing a stable step size and can just run the simulation. diff --git a/docs/src/install.md b/docs/src/install.md index 15c6668b9c..821efe9e48 100644 --- a/docs/src/install.md +++ b/docs/src/install.md @@ -8,13 +8,14 @@ with Julia v1.10 and newer. We recommend using the latest stable release of Juli ## For users TrixiParticles.jl is a registered Julia package. You can install TrixiParticles.jl, -[OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) (used for time integration) -and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) by executing the following commands +time integration sub-packages of [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) +(for example `OrdinaryDiffEqLowStorageRK`), and [Plots.jl](https://github.com/JuliaPlots/Plots.jl) +by executing the following commands in the Julia REPL: ```julia julia> using Pkg -julia> Pkg.add(["TrixiParticles", "OrdinaryDiffEq", "Plots"]) +julia> Pkg.add(["TrixiParticles", "OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqSymplecticRK", "Plots"]) ``` ## [For developers](@id for-developers) @@ -25,7 +26,7 @@ git clone git@github.com:trixi-framework/TrixiParticles.jl.git cd TrixiParticles.jl mkdir run julia --project=run -e 'using Pkg; Pkg.develop(PackageSpec(path="."))' # Add TrixiParticles.jl to `run` project -julia --project=run -e 'using Pkg; Pkg.add(["OrdinaryDiffEq", "Plots"])' # Add additional packages +julia --project=run -e 'using Pkg; Pkg.add(["OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqSymplecticRK", "Plots"])' # Add additional packages ``` If you installed TrixiParticles.jl this way, you always have to start Julia with the @@ -36,11 +37,12 @@ julia --project=run from the TrixiParticles.jl root directory. The advantage of using a separate `run` directory is that you can also add other -related packages (e.g., OrdinaryDiffEq.jl, see above) to the project in the `run` folder +related packages (e.g., sub-packages of OrdinaryDiffEq.jl, see above) to the project +in the `run` folder and always have a reproducible environment at hand to share with others. ## Optional software/packages -- [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) -- A Julia package of ordinary differential equation solvers that is used in the examples +- [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) -- A Julia package of ordinary differential equation solvers; examples in TrixiParticles.jl use sub-packages such as `OrdinaryDiffEqLowStorageRK` and `OrdinaryDiffEqSymplecticRK` - [Plots.jl](https://github.com/JuliaPlots/Plots.jl) -- Julia Plotting library that is used in some examples - [PythonPlot.jl](https://github.com/JuliaPy/PythonPlot.jl) -- Plotting library that can be used instead of Plots.jl - [ParaView](https://www.paraview.org/) -- Software that can be used for visualization of results diff --git a/docs/src/time_integration.md b/docs/src/time_integration.md index 006c83261d..f8a2842c13 100644 --- a/docs/src/time_integration.md +++ b/docs/src/time_integration.md @@ -4,7 +4,9 @@ TrixiParticles.jl uses a modular approach where time integration is just another that can be customized and exchanged. The function [`semidiscretize`](@ref) returns an `ODEProblem` (see [the OrdinaryDiffEq.jl docs](https://docs.sciml.ai/DiffEqDocs/stable/types/ode_types/)), -which can be integrated with [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl). +which can be integrated with solvers provided by +[OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl) or its sub-packages +(e.g., `OrdinaryDiffEqLowStorageRK`). In particular, a [`DynamicalODEProblem`](https://docs.sciml.ai/DiffEqDocs/stable/types/dynamical_types/) is returned, where the right-hand side is split into two functions, the `kick!`, which @@ -23,18 +25,17 @@ After obtaining an `ODEProblem` from [`semidiscretize`](@ref), let us call it `o we can pass it to the function `solve` of OrdinaryDiffEq.jl. For most schemes, we do the following: ```julia -using OrdinaryDiffEq -sol = solve(ode, Euler(), +using OrdinaryDiffEqLowStorageRK +sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false), dt=1.0, save_everystep=false, callback=callbacks); ``` -Here, `Euler()` should in practice be replaced by a more useful scheme. `callbacks` should be a `CallbackSet` containing callbacks like the [`InfoCallback`](@ref). For callbacks, please refer to [the docs](@ref Callbacks) and the example files. In this case, we need to either set a reasonable, problem- and resolution-dependent step size `dt`, or use the [`StepsizeCallback`](@ref), which overwrites the step size dynamically during the simulation based on a CFL-number. -We always set `save_everystep=false`, or OrdinaryDiffEq.jl would return the solution vector +We always set `save_everystep=false`, or the solver would return the solution vector for every time step, writing massive amounts of data into the RAM for large simulations. To visualize data for every time step, [callbacks](@ref Callbacks) can be used. @@ -81,7 +82,7 @@ in the inviscid case. Once we add viscosity, ``\operatorname{kick}`` depends on both ``u`` and ``v``. Then, the calculation of ``v^1`` requires ``v^1`` and becomes implicit. -The way this scheme is implemented in OrdinaryDiffEq.jl as `VerletLeapfrog`, +The way this scheme is implemented in `OrdinaryDiffEqSymplecticRK` as `VerletLeapfrog`, the intermediate velocity ``v^{1/2}`` is passed to ``\operatorname{kick}`` in the last stage, resulting in first-order convergence when the scheme is used in the viscid case. @@ -109,7 +110,7 @@ v^1 &= v^0 + \Delta t\, \operatorname{kick} \left( v^{1/2}, u^{1/2}, t^0 + \frac u^1 &= u^{1/2} + \frac{1}{2} \Delta t\, \operatorname{drift}(v^{1}, u^{1}, t^0 + \Delta t). \end{align*} ``` -This scheme is implemented in OrdinaryDiffEq.jl as `LeapfrogDriftKickDrift` and yields +This scheme is implemented in `OrdinaryDiffEqSymplecticRK` as `LeapfrogDriftKickDrift` and yields the desired second order as long as ``\operatorname{drift}`` does not depend on ``u``, which is always the case. diff --git a/examples/dem/collapsing_sand_pile_3d.jl b/examples/dem/collapsing_sand_pile_3d.jl index f463ac2417..cd87732386 100644 --- a/examples/dem/collapsing_sand_pile_3d.jl +++ b/examples/dem/collapsing_sand_pile_3d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # Physical parameters gravity = -9.81 @@ -64,12 +64,11 @@ boundary_particles = floor_particles contact_model = LinearContactModel(1e6) damping_coefficient = 0.00001 -sand_system = DEMSystem(sand_particles, contact_model; - damping_coefficient=damping_coefficient, - acceleration=acceleration, radius=0.4 * particle_spacing) +sand_system = DEMSystem(sand_particles; contact_model, damping_coefficient, acceleration, + radius=0.4 * particle_spacing) boundary_stiffness = 1.0e5 -boundary_system = BoundaryDEMSystem(boundary_particles, boundary_stiffness) +boundary_system = BoundaryDEMSystem(boundary_particles; normal_stiffness=boundary_stiffness) # ========================================================================================== # ==== Simulation diff --git a/examples/dem/rectangular_tank_2d.jl b/examples/dem/rectangular_tank_2d.jl index 5c53f16562..cc477e9029 100644 --- a/examples/dem/rectangular_tank_2d.jl +++ b/examples/dem/rectangular_tank_2d.jl @@ -7,7 +7,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK gravity = -9.81 @@ -47,11 +47,11 @@ contact_model = HertzContactModel(10e9, 0.3) # contact_model = LinearContactModel(2 * 10e5) # Construct the rock system using the new DEMSystem signature. -rock_system = DEMSystem(tank.fluid, contact_model; damping_coefficient=0.0001, +rock_system = DEMSystem(tank.fluid; contact_model, damping_coefficient=0.0001, acceleration=(0.0, gravity), radius=0.4 * particle_spacing) # Construct the boundary system for the tank walls. -boundary_system = BoundaryDEMSystem(tank.boundary, 10e7) +boundary_system = BoundaryDEMSystem(tank.boundary; normal_stiffness=10e7) # ========================================================================================== # ==== Simulation diff --git a/examples/fluid/accelerated_tank_2d.jl b/examples/fluid/accelerated_tank_2d.jl index cb6fbfb9d1..d974b107c7 100644 --- a/examples/fluid/accelerated_tank_2d.jl +++ b/examples/fluid/accelerated_tank_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # Resolution fluid_particle_spacing = 0.05 @@ -19,7 +19,6 @@ is_moving(t) = true boundary_movement = PrescribedMotion(movement_function, is_moving) trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "hydrostatic_water_column_2d.jl"), - fluid_particle_spacing=fluid_particle_spacing, - prescribed_motion=boundary_movement, - tspan=(0.0, 1.0), system_acceleration=(0.0, 0.0)); + joinpath(examples_dir(), "fluid", "hydrostatic_water_column_2d.jl"); + fluid_particle_spacing, prescribed_motion=boundary_movement, tspan=(0.0, 1.0), + system_acceleration=(0.0, 0.0)); diff --git a/examples/fluid/dam_break_2d.jl b/examples/fluid/dam_break_2d.jl index 56303b1877..c14119cb60 100644 --- a/examples/fluid/dam_break_2d.jl +++ b/examples/fluid/dam_break_2d.jl @@ -13,7 +13,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # Size parameters H = 0.6 @@ -44,9 +44,9 @@ sound_speed = 20 * sqrt(gravity * H) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1, clip_negative_pressure=false) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - acceleration=(0.0, -gravity), state_equation=state_equation, +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + acceleration=(0.0, -gravity), state_equation, coordinates_eltype=Float64) # ========================================================================================== @@ -57,20 +57,19 @@ smoothing_kernel = WendlandC2Kernel{2}() fluid_density_calculator = ContinuityDensity() alpha = 0.02 -viscosity_fluid = ArtificialViscosityMonaghan(alpha=alpha, beta=0.0) +viscosity_fluid = ArtificialViscosityMonaghan(; alpha, beta=0.0) # The density diffusion model by Molteni and Colagrossi shows unphysical effects at the # free surface in long-running simulations, but is significantly faster than the model # by Antuono. This simulation is short enough to use the faster model. density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -# density_diffusion = DensityDiffusionAntuono(tank.fluid, delta=0.1) - -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity_fluid, - density_diffusion=density_diffusion, - acceleration=(0.0, -gravity), correction=nothing, - surface_tension=nothing, +# density_diffusion = DensityDiffusionAntuono(delta=0.1) + +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity=viscosity_fluid, + density_diffusion, acceleration=(0.0, -gravity), + correction=nothing, surface_tension=nothing, reference_particle_spacing=0) # ========================================================================================== @@ -79,13 +78,16 @@ boundary_density_calculator = AdamiPressureExtrapolation() viscosity_wall = nothing # For a no-slip boundary condition, define a wall viscosity: # 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, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length, + smoothing_kernel, smoothing_length; + state_equation, correction=nothing, reference_particle_spacing=0, - viscosity=viscosity_wall) + viscosity=viscosity_wall, + clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model, adhesion_coefficient=0.0) diff --git a/examples/fluid/dam_break_2d_gpu.jl b/examples/fluid/dam_break_2d_gpu.jl index dd0b140419..40d4727dfa 100644 --- a/examples/fluid/dam_break_2d_gpu.jl +++ b/examples/fluid/dam_break_2d_gpu.jl @@ -18,13 +18,13 @@ using TrixiParticles +tspan = (0.0, 5.7 / sqrt(9.81 / 0.6)) + # Load setup from dam break example trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - fluid_particle_spacing=0.6 / 40, - spacing_ratio=1, boundary_layers=4, - coordinates_eltype=Float64, - sol=nothing, ode=nothing) + fluid_particle_spacing=0.6 / 40, spacing_ratio=1, boundary_layers=4, + coordinates_eltype=Float64, tspan=tspan, sol=nothing, ode=nothing) # Define a GPU-compatible neighborhood search min_corner = minimum(tank.boundary.coordinates, dims=2) diff --git a/examples/fluid/dam_break_2d_iisph.jl b/examples/fluid/dam_break_2d_iisph.jl index 9c2ba6f224..3aa84ca5ab 100644 --- a/examples/fluid/dam_break_2d_iisph.jl +++ b/examples/fluid/dam_break_2d_iisph.jl @@ -1,13 +1,13 @@ # 2D dam break simulation using implicit incompressible SPH (IISPH) using TrixiParticles +using OrdinaryDiffEqSymplecticRK fluid_particle_spacing = 0.6 / 40 +tspan = (0.0, 5.7 / sqrt(9.81 / 0.6)) # Load setup from dam break example -trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - fluid_particle_spacing=fluid_particle_spacing, - sol=nothing, ode=nothing) +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + fluid_particle_spacing, tspan, sol=nothing, ode=nothing) # IISPH doesn't require a large compact support like WCSPH and performs worse with a typical # smoothing length used for WCSPH. @@ -26,24 +26,17 @@ viscosity = ViscosityAdami(; nu) # Use IISPH as fluid system time_step = 1e-3 -fluid_system = ImplicitIncompressibleSPHSystem(tank.fluid, smoothing_kernel, - smoothing_length, fluid_density, - viscosity=ViscosityAdami(nu=nu), +fluid_system = ImplicitIncompressibleSPHSystem(tank.fluid; smoothing_kernel, + smoothing_length, + reference_density=fluid_density, viscosity, acceleration=(0.0, -gravity), - min_iterations=2, - max_iterations=30, - time_step=time_step) + min_iterations=2, max_iterations=30, + time_step) # Run the dam break simulation with these changes -trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - neighborhood_search=GridNeighborhoodSearch{2}(), - viscosity_fluid=ViscosityAdami(nu=nu), - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, - fluid_system=fluid_system, - boundary_density_calculator=PressureZeroing(), - tspan=tspan, - state_equation=nothing, +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + neighborhood_search=GridNeighborhoodSearch{2}(), viscosity_fluid=viscosity, + smoothing_kernel, smoothing_length, fluid_system, + boundary_density_calculator=PressureZeroing(), tspan, state_equation=nothing, callbacks=CallbackSet(info_callback, saving_callback), time_integration_scheme=SymplecticEuler(), dt=time_step) diff --git a/examples/fluid/dam_break_2d_iisph_pressure_boundaries.jl b/examples/fluid/dam_break_2d_iisph_pressure_boundaries.jl index 86f9e6cde9..6f9989ff5c 100644 --- a/examples/fluid/dam_break_2d_iisph_pressure_boundaries.jl +++ b/examples/fluid/dam_break_2d_iisph_pressure_boundaries.jl @@ -1,10 +1,13 @@ # 2D dam break simulation using implicit incompressible SPH (IISPH) with pressure boundaries using TrixiParticles +using OrdinaryDiffEqSymplecticRK + +tspan = (0.0, 5.7 / sqrt(9.81 / 0.6)) # Load setup from dam break example trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - sol=nothing, ode=nothing) + joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + tspan, sol=nothing, ode=nothing) # Change smoothing kernel and length smoothing_length = 1.2 * fluid_particle_spacing @@ -19,25 +22,17 @@ time_step = 1e-3 # Reduce omega when using pressure boundaries to ensure numerical stability omega = 0.4 -iisph_system = ImplicitIncompressibleSPHSystem(tank.fluid, smoothing_kernel, - smoothing_length, fluid_density, - viscosity=ViscosityAdami(nu=nu), +iisph_system = ImplicitIncompressibleSPHSystem(tank.fluid; smoothing_kernel, + smoothing_length, + reference_density=fluid_density, viscosity, acceleration=(0.0, -gravity), - min_iterations=2, - max_iterations=30, - omega=omega, - time_step=time_step) + min_iterations=2, max_iterations=30, omega, + time_step) # Run the dam break simulation with these changes -trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - viscosity_fluid=ViscosityAdami(nu=nu), - smoothing_kernel=smoothing_kernel, - smoothing_length=smoothing_length, +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + viscosity_fluid=viscosity, smoothing_kernel, smoothing_length, fluid_system=iisph_system, - boundary_density_calculator=PressureBoundaries(; time_step=time_step, - omega=omega), - tspan=tspan, - state_equation=nothing, - callbacks=CallbackSet(info_callback, saving_callback), + boundary_density_calculator=PressureBoundaries(; time_step, omega), tspan, + state_equation=nothing, callbacks=CallbackSet(info_callback, saving_callback), time_integration_scheme=SymplecticEuler(), dt=time_step) diff --git a/examples/fluid/dam_break_2phase_2d.jl b/examples/fluid/dam_break_2phase_2d.jl index 6b626bf42e..5ac502a8cc 100644 --- a/examples/fluid/dam_break_2phase_2d.jl +++ b/examples/fluid/dam_break_2phase_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # Size parameters H = 0.6 @@ -40,11 +40,10 @@ nu_sim_water = nu_ratio * nu_sim_air air_viscosity = ViscosityMorris(nu=nu_sim_air) water_viscosity = ViscosityMorris(nu=nu_sim_water) -trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - sol=nothing, fluid_particle_spacing=fluid_particle_spacing, - viscosity_fluid=water_viscosity, smoothing_length=smoothing_length, - gravity=gravity, tspan=tspan, density_diffusion=nothing, - sound_speed=sound_speed, exponent=7, +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + sol=nothing, fluid_particle_spacing, viscosity_fluid=water_viscosity, + smoothing_length, gravity, tspan, density_diffusion=nothing, sound_speed, + exponent=7, tank_size=(floor(5.366 * H / fluid_particle_spacing) * fluid_particle_spacing, 2.6 * H)) @@ -76,8 +75,10 @@ air_eos = StateEquationCole(; sound_speed, reference_density=air_density, expone clip_negative_pressure=false) #air_eos = StateEquationIdealGas(; sound_speed, reference_density=air_density, gamma=1.4) -air_system_system = WeaklyCompressibleSPHSystem(air_system, fluid_density_calculator, - air_eos, smoothing_kernel, smoothing_length, +air_system_system = WeaklyCompressibleSPHSystem(air_system; + smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation=air_eos, viscosity=air_viscosity, acceleration=(0.0, -gravity)) diff --git a/examples/fluid/dam_break_3d.jl b/examples/fluid/dam_break_3d.jl index a073c001ec..ae9b580960 100644 --- a/examples/fluid/dam_break_3d.jl +++ b/examples/fluid/dam_break_3d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -33,9 +33,9 @@ fluid_density = 1000.0 state_equation = StateEquationAdaptiveCole(; reference_density=fluid_density, exponent=7) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - acceleration=(0.0, -gravity, 0.0), state_equation=state_equation, +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + acceleration=(0.0, -gravity, 0.0), state_equation, coordinates_eltype=Float64) # ========================================================================================== @@ -47,19 +47,21 @@ fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, acceleration=(0.0, -gravity, 0.0)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation, + clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) diff --git a/examples/fluid/dam_break_oil_film_2d.jl b/examples/fluid/dam_break_oil_film_2d.jl index ecf7bb2998..7a890eb918 100644 --- a/examples/fluid/dam_break_oil_film_2d.jl +++ b/examples/fluid/dam_break_oil_film_2d.jl @@ -7,7 +7,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # Size parameters H = 0.6 @@ -34,12 +34,11 @@ nu_sim_water = nu_ratio * nu_sim_oil oil_viscosity = ViscosityMorris(nu=nu_sim_oil) # TODO: broken if both systems use surface tension -trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - sol=nothing, fluid_particle_spacing=fluid_particle_spacing, tspan=tspan, - viscosity_fluid=ViscosityMorris(nu=nu_sim_water), - smoothing_length=smoothing_length, - gravity=gravity, density_diffusion=nothing, sound_speed=sound_speed, - prefix="", reference_particle_spacing=fluid_particle_spacing) +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + sol=nothing, fluid_particle_spacing, tspan, + viscosity_fluid=ViscosityMorris(nu=nu_sim_water), smoothing_length, gravity, + density_diffusion=nothing, sound_speed, prefix="", + reference_particle_spacing=fluid_particle_spacing) # ========================================================================================== # ==== Setup oil layer @@ -60,17 +59,21 @@ end oil_state_equation = StateEquationCole(; sound_speed, reference_density=oil_density, exponent=1, clip_negative_pressure=false) -oil_system = WeaklyCompressibleSPHSystem(oil, fluid_density_calculator, - oil_eos, smoothing_kernel, - smoothing_length, viscosity=oil_viscosity, +oil_system = WeaklyCompressibleSPHSystem(oil; + smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation=oil_eos, + viscosity=oil_viscosity, acceleration=(0.0, -gravity), surface_tension=SurfaceTensionAkinci(surface_tension_coefficient=0.01), correction=AkinciFreeSurfaceCorrection(oil_density), reference_particle_spacing=fluid_particle_spacing) -# oil_system = WeaklyCompressibleSPHSystem(oil, fluid_density_calculator, -# oil_eos, smoothing_kernel, -# smoothing_length, viscosity=oil_viscosity, +# oil_system = WeaklyCompressibleSPHSystem(oil; +# smoothing_kernel, smoothing_length, +# density_calculator=fluid_density_calculator, +# state_equation=oil_eos, +# viscosity=oil_viscosity, # acceleration=(0.0, -gravity), # surface_tension=SurfaceTensionMorris(surface_tension_coefficient=0.03), # reference_particle_spacing=fluid_particle_spacing) diff --git a/examples/fluid/falling_water_column_2d.jl b/examples/fluid/falling_water_column_2d.jl index f712f88d93..694c13ab76 100644 --- a/examples/fluid/falling_water_column_2d.jl +++ b/examples/fluid/falling_water_column_2d.jl @@ -5,7 +5,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -29,8 +29,8 @@ sound_speed = 10 * sqrt(gravity * initial_fluid_size[2]) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=7) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio) # Move water column for i in axes(tank.fluid.coordinates, 2) @@ -45,18 +45,21 @@ smoothing_kernel = SchoenbergCubicSplineKernel{2}() fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length) + 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 778d404d69..1f0016ac6d 100644 --- a/examples/fluid/falling_water_spheres_2d.jl +++ b/examples/fluid/falling_water_spheres_2d.jl @@ -7,7 +7,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -20,20 +20,21 @@ spacing_ratio = 1 # ==== Experiment Setup gravity = 9.81 tspan = (0.0, 0.3) +acceleration = (0.0, -gravity) # Boundary geometry and initial fluid particle positions initial_fluid_size = (0.0, 0.0) tank_size = (2.0, 0.5) +faces = (true, true, true, false) fluid_density = 1000.0 sound_speed = 100 state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - faces=(true, true, true, false), - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, faces, acceleration, + state_equation) sphere_radius = 0.05 @@ -56,35 +57,40 @@ fluid_density_calculator = ContinuityDensity() nu = 0.005 alpha = 8 * nu / (fluid_smoothing_length * sound_speed) -viscosity = ArtificialViscosityMonaghan(alpha=alpha, beta=0.0) -density_diffusion = DensityDiffusionAntuono(sphere2, delta=0.1) - -sphere_surface_tension = EntropicallyDampedSPHSystem(sphere1, fluid_smoothing_kernel, - fluid_smoothing_length, - sound_speed, viscosity=viscosity, +viscosity = ArtificialViscosityMonaghan(; alpha, beta=0.0) +density_diffusion = DensityDiffusionAntuono(delta=0.1) +surface_tension_coefficient = 0.05 +surface_tension = SurfaceTensionAkinci(; surface_tension_coefficient) + +sphere_surface_tension = EntropicallyDampedSPHSystem(sphere1; + smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + sound_speed, viscosity, density_calculator=ContinuityDensity(), - acceleration=(0.0, -gravity), - surface_tension=SurfaceTensionAkinci(surface_tension_coefficient=0.05), + acceleration, surface_tension, reference_particle_spacing=fluid_particle_spacing) -sphere = WeaklyCompressibleSPHSystem(sphere2, fluid_density_calculator, - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, - acceleration=(0.0, -gravity)) +sphere = WeaklyCompressibleSPHSystem(sphere2; smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, + acceleration) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length, + fluid_smoothing_kernel, fluid_smoothing_length; + state_equation, viscosity=ViscosityAdami(nu=wall_viscosity), - reference_particle_spacing=fluid_particle_spacing) + reference_particle_spacing=fluid_particle_spacing, + clip_negative_pressure=true) -boundary_system = WallBoundarySystem(tank.boundary, boundary_model, +boundary_system = WallBoundarySystem(tank.boundary, boundary_model; adhesion_coefficient=1.0) # ========================================================================================== diff --git a/examples/fluid/falling_water_spheres_3d.jl b/examples/fluid/falling_water_spheres_3d.jl index 78db127b5f..511927145f 100644 --- a/examples/fluid/falling_water_spheres_3d.jl +++ b/examples/fluid/falling_water_spheres_3d.jl @@ -8,7 +8,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -33,14 +33,12 @@ sphere2 = SphereShape(fluid_particle_spacing, sphere1_radius, sphere2_center, # `compact_support` needs to be `2.0 * particle_spacing` to be correct fluid_smoothing_length = 1.0 * fluid_particle_spacing -trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "falling_water_spheres_2d.jl"), - fluid_particle_spacing=fluid_particle_spacing, tspan=(0.0, 0.1), - initial_fluid_size=(0.0, 0.0, 0.0), interval=100, - tank_size=(2.0, 1.0, 0.1), sound_speed=sound_speed, +surface_tension = SurfaceTensionAkinci(surface_tension_coefficient=0.05) + +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "falling_water_spheres_2d.jl"); + fluid_particle_spacing, tspan=(0.0, 0.1), initial_fluid_size=(0.0, 0.0, 0.0), + interval=100, tank_size=(2.0, 1.0, 0.1), sound_speed, faces=(true, true, true, true, true, false), - acceleration=(0.0, 0.0, -gravity), sphere1=sphere1, sphere2=sphere2, - fluid_smoothing_length=fluid_smoothing_length, - fluid_smoothing_kernel=SchoenbergCubicSplineKernel{3}(), - nu=nu, alpha=10 * nu / (fluid_smoothing_length * sound_speed), - surface_tension=SurfaceTensionAkinci(surface_tension_coefficient=0.05)) + acceleration=(0.0, 0.0, -gravity), sphere1, sphere2, fluid_smoothing_length, + fluid_smoothing_kernel=SchoenbergCubicSplineKernel{3}(), nu, + alpha=10 * nu / (fluid_smoothing_length * sound_speed), surface_tension) diff --git a/examples/fluid/hydrostatic_water_column_2d.jl b/examples/fluid/hydrostatic_water_column_2d.jl index a62dbab249..58b381c0c0 100644 --- a/examples/fluid/hydrostatic_water_column_2d.jl +++ b/examples/fluid/hydrostatic_water_column_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -29,9 +29,9 @@ sound_speed = 10.0 state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=7, clip_negative_pressure=false) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; n_layers=boundary_layers, acceleration=(0.0, -gravity), - state_equation=state_equation) + state_equation) # ========================================================================================== # ==== Fluid @@ -39,15 +39,16 @@ smoothing_length = 1.2 * fluid_particle_spacing smoothing_kernel = SchoenbergCubicSplineKernel{2}() alpha = 0.02 -viscosity_fluid = ArtificialViscosityMonaghan(alpha=alpha, beta=0.0) +viscosity_fluid = ArtificialViscosityMonaghan(; alpha, beta=0.0) fluid_density_calculator = ContinuityDensity() # This is to set acceleration with `trixi_include` system_acceleration = (0.0, -gravity) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity_fluid, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; + smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity=viscosity_fluid, acceleration=system_acceleration, source_terms=nothing) @@ -60,9 +61,9 @@ 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, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length, + 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 9849ca06f7..c1aa4ae2a8 100644 --- a/examples/fluid/lid_driven_cavity_2d.jl +++ b/examples/fluid/lid_driven_cavity_2d.jl @@ -16,7 +16,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -41,9 +41,9 @@ pressure = sound_speed^2 * fluid_density viscosity = ViscosityAdami(; nu=VELOCITY_LID / reynolds_number) -cavity = RectangularTank(particle_spacing, cavity_size, cavity_size, fluid_density, - n_layers=boundary_layers, - faces=(true, true, true, false), pressure=pressure) +cavity = RectangularTank(particle_spacing, cavity_size, cavity_size, fluid_density; + n_layers=boundary_layers, faces=(true, true, true, false), + pressure) lid_position = 0.0 - particle_spacing * boundary_layers lid_length = cavity.n_particles_per_dimension[1] + 2boundary_layers @@ -61,18 +61,17 @@ if wcsph density_calculator = ContinuityDensity() state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) - fluid_system = WeaklyCompressibleSPHSystem(cavity.fluid, density_calculator, - state_equation, smoothing_kernel, + fluid_system = WeaklyCompressibleSPHSystem(cavity.fluid; smoothing_kernel, + smoothing_length, density_calculator, + state_equation, viscosity, pressure_acceleration=TrixiParticles.inter_particle_averaged_pressure, - smoothing_length, viscosity=viscosity, shifting_technique=TransportVelocityAdami(background_pressure=pressure)) else state_equation = nothing density_calculator = ContinuityDensity() - fluid_system = EntropicallyDampedSPHSystem(cavity.fluid, smoothing_kernel, - smoothing_length, - density_calculator=density_calculator, - sound_speed, viscosity=viscosity, + fluid_system = EntropicallyDampedSPHSystem(cavity.fluid; smoothing_kernel, + smoothing_length, density_calculator, + sound_speed, viscosity, shifting_technique=TransportVelocityAdami(background_pressure=pressure)) end @@ -88,15 +87,13 @@ lid_movement = PrescribedMotion(lid_movement_function, is_moving) boundary_model_cavity = BoundaryModelDummyParticles(cavity.boundary.density, cavity.boundary.mass, AdamiPressureExtrapolation(), - viscosity=viscosity, - state_equation=state_equation, - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + viscosity, state_equation) boundary_model_lid = BoundaryModelDummyParticles(lid.density, lid.mass, AdamiPressureExtrapolation(), - viscosity=viscosity, - state_equation=state_equation, - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + viscosity, state_equation) boundary_system_cavity = WallBoundarySystem(cavity.boundary, boundary_model_cavity) diff --git a/examples/fluid/moving_wall_2d.jl b/examples/fluid/moving_wall_2d.jl index 85663188ea..6e0b0f9dfe 100644 --- a/examples/fluid/moving_wall_2d.jl +++ b/examples/fluid/moving_wall_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -29,9 +29,9 @@ sound_speed = 10 * sqrt(gravity * initial_fluid_size[2]) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=7) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; n_layers=boundary_layers, spacing_ratio=1.0, - acceleration=(0.0, -gravity), state_equation=state_equation) + acceleration=(0.0, -gravity), state_equation) reset_wall!(tank, (false, true, false, false), (0.0, tank.fluid_size[1], 0.0, 0.0)) @@ -51,18 +51,18 @@ smoothing_kernel = SchoenbergCubicSplineKernel{2}() fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.1, beta=0.0) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary boundary_density_calculator = AdamiPressureExtrapolation() boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation) boundary_system = WallBoundarySystem(tank.boundary, boundary_model, prescribed_motion=boundary_movement) diff --git a/examples/fluid/oscillating_drop_2d.jl b/examples/fluid/oscillating_drop_2d.jl index fb96050f42..98c39651ef 100644 --- a/examples/fluid/oscillating_drop_2d.jl +++ b/examples/fluid/oscillating_drop_2d.jl @@ -12,7 +12,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -42,8 +42,7 @@ Q = (sigma^2 + OMEGA^2) * fluid_density / 2 pressure = coords -> Q * (1 - coords[1]^2 - coords[2]^2) density = coords -> TrixiParticles.inverse_state_equation(state_equation, pressure(coords)) -fluid = SphereShape(fluid_particle_spacing, radius, (0.0, 0.0), - density, pressure=pressure, +fluid = SphereShape(fluid_particle_spacing, radius, (0.0, 0.0), density; pressure, sphere_type=RoundSphere(), velocity=coords -> sigma .* (coords[1], -coords[2])) @@ -55,12 +54,11 @@ smoothing_kernel = WendlandC2Kernel{2}() fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) -density_diffusion = DensityDiffusionAntuono(fluid, delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, - source_terms=source_terms) +density_diffusion = DensityDiffusionAntuono(delta=0.1) +fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, + source_terms) # ========================================================================================== # ==== Simulation diff --git a/examples/fluid/periodic_array_of_cylinders_2d.jl b/examples/fluid/periodic_array_of_cylinders_2d.jl index b2dad5bca6..84d2ae140f 100644 --- a/examples/fluid/periodic_array_of_cylinders_2d.jl +++ b/examples/fluid/periodic_array_of_cylinders_2d.jl @@ -13,7 +13,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -46,9 +46,8 @@ pressure = sound_speed^2 * fluid_density particle_spacing = tank_size[1] / n_particles_x -box = RectangularTank(particle_spacing, fluid_size, tank_size, - fluid_density, n_layers=boundary_layers, - pressure=pressure, faces=(false, false, true, true)) +box = RectangularTank(particle_spacing, fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, pressure, faces=(false, false, true, true)) cylinder = SphereShape(particle_spacing, cylinder_radius, tank_size ./ 2, fluid_density, sphere_type=RoundSphere()) @@ -63,10 +62,10 @@ smoothing_kernel = WendlandC2Kernel{2}() state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1, clip_negative_pressure=false) -density_diffusion = DensityDiffusionAntuono(fluid, delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), state_equation, - smoothing_kernel, smoothing_length, - density_diffusion=density_diffusion, +density_diffusion = DensityDiffusionAntuono(delta=0.1) +fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, density_diffusion, viscosity=ViscosityAdami(; nu), shifting_technique=ParticleShiftingTechnique(), pressure_acceleration=tensile_instability_control, @@ -75,10 +74,9 @@ fluid_system = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), state_equ # ========================================================================================== # ==== Boundary boundary_model = BoundaryModelDummyParticles(boundary.density, boundary.mass, - AdamiPressureExtrapolation(), - viscosity=ViscosityAdami(; nu), - smoothing_kernel, smoothing_length, - state_equation=state_equation) + AdamiPressureExtrapolation(), smoothing_kernel, + smoothing_length; + viscosity=ViscosityAdami(; nu), state_equation) boundary_system = WallBoundarySystem(boundary, boundary_model) diff --git a/examples/fluid/periodic_channel_2d.jl b/examples/fluid/periodic_channel_2d.jl index 5dab8cfc4a..3dbd9f3bab 100644 --- a/examples/fluid/periodic_channel_2d.jl +++ b/examples/fluid/periodic_channel_2d.jl @@ -8,7 +8,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -32,8 +32,8 @@ sound_speed = 10 * initial_velocity[1] state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=7) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, faces=(false, false, true, true), velocity=initial_velocity, coordinates_eltype=Float64) @@ -46,9 +46,9 @@ fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) # `pressure_acceleration=nothing` is the default and can be overwritten with `trixi_include` -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, shifting_technique=nothing, pressure_acceleration=nothing) @@ -60,9 +60,9 @@ viscosity_wall = nothing #viscosity_wall = ViscosityAdami(nu=0.0025 * smoothing_length * sound_speed / 8) boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length, + 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 d81b72b094..6022b980e4 100644 --- a/examples/fluid/pipe_flow_2d.jl +++ b/examples/fluid/pipe_flow_2d.jl @@ -8,7 +8,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -82,19 +82,18 @@ if wcsph exponent=1) density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) - fluid_system = WeaklyCompressibleSPHSystem(pipe.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - density_diffusion=density_diffusion, - smoothing_length, viscosity=viscosity, + fluid_system = WeaklyCompressibleSPHSystem(pipe.fluid; smoothing_kernel, + smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, density_diffusion, viscosity, shifting_technique=ParticleShiftingTechnique(v_max_factor=1.5), buffer_size=n_buffer_particles) else # Alternatively the EDAC scheme can be used state_equation = nothing - fluid_system = EntropicallyDampedSPHSystem(pipe.fluid, smoothing_kernel, - smoothing_length, sound_speed, - viscosity=viscosity, + fluid_system = EntropicallyDampedSPHSystem(pipe.fluid; smoothing_kernel, + smoothing_length, sound_speed, viscosity, density_calculator=fluid_density_calculator, shifting_technique=ParticleShiftingTechnique(), buffer_size=n_buffer_particles) @@ -145,10 +144,9 @@ open_boundary = OpenBoundarySystem(inflow, outflow; fluid_system, wall = union(pipe.boundary, inlet.boundary, outlet.boundary) viscosity_boundary = viscosity boundary_model = BoundaryModelDummyParticles(wall.density, wall.mass, - AdamiPressureExtrapolation(), - state_equation=state_equation, - viscosity=viscosity_boundary, - smoothing_kernel, smoothing_length) + AdamiPressureExtrapolation(), smoothing_kernel, + smoothing_length; state_equation, + viscosity=viscosity_boundary) boundary_system = WallBoundarySystem(wall, boundary_model) diff --git a/examples/fluid/pipe_flow_3d.jl b/examples/fluid/pipe_flow_3d.jl index a0f16b57a6..dc0e401531 100644 --- a/examples/fluid/pipe_flow_3d.jl +++ b/examples/fluid/pipe_flow_3d.jl @@ -34,12 +34,10 @@ min_coords_inlet = (-open_boundary_layers * particle_spacing, 0.0, 0.0) min_coords_outlet = (-open_boundary_layers * particle_spacing, 0.0, 0.0) # setup simulation -trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "pipe_flow_2d.jl"), - domain_size=domain_size, open_boundary_size=open_boundary_size, - flow_direction=flow_direction, faces=(false, false, true, true, true, true), - tspan=tspan, prescribed_velocity=prescribed_velocity, - open_boundary_layers=open_boundary_layers, min_coords_inlet=min_coords_inlet, - min_coords_outlet=min_coords_outlet, +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "pipe_flow_2d.jl"); + domain_size, open_boundary_size, flow_direction, + faces=(false, false, true, true, true, true), tspan, prescribed_velocity, + open_boundary_layers, min_coords_inlet, min_coords_outlet, face_in=([0.0, 0.0, 0.0], [0.0, domain_size[2], 0.0], [0.0, 0.0, domain_size[3]]), face_out=([domain_size[1], 0.0, 0.0], [domain_size[1], domain_size[2], 0.0], diff --git a/examples/fluid/poiseuille_flow_2d.jl b/examples/fluid/poiseuille_flow_2d.jl index d808b1be71..ba36a2f471 100644 --- a/examples/fluid/poiseuille_flow_2d.jl +++ b/examples/fluid/poiseuille_flow_2d.jl @@ -11,7 +11,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -96,20 +96,19 @@ shifting_technique = TransportVelocityAdami(; background_pressure) if use_wcsph state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) - fluid_system = WeaklyCompressibleSPHSystem(fluid, fluid_density_calculator, - state_equation, smoothing_kernel, + fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, shifting_technique, buffer_size=n_buffer_particles, - shifting_technique=shifting_technique, density_diffusion=DensityDiffusionMolteniColagrossi(delta=0.1), - smoothing_length, viscosity=viscosity) + viscosity) else state_equation = nothing - fluid_system = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, - smoothing_length, - sound_speed, viscosity=viscosity, + fluid_system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, smoothing_length, + sound_speed, viscosity, density_calculator=fluid_density_calculator, - shifting_technique=shifting_technique, + shifting_technique, buffer_size=n_buffer_particles) end @@ -154,10 +153,8 @@ open_boundary = OpenBoundarySystem(inlet_boundary_zone, outlet_boundary_zone; fl wall_boundary = union(channel.boundary) boundary_model = BoundaryModelDummyParticles(wall_boundary.density, wall_boundary.mass, - AdamiPressureExtrapolation(), - state_equation=state_equation, - viscosity=viscosity, - smoothing_kernel, smoothing_length) + AdamiPressureExtrapolation(), smoothing_kernel, + smoothing_length; state_equation, 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 c49e7f66bb..4459df0648 100644 --- a/examples/fluid/poiseuille_flow_3d.jl +++ b/examples/fluid/poiseuille_flow_3d.jl @@ -10,7 +10,7 @@ # including open boundary conditions. # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -113,12 +113,12 @@ shifting_technique = TransportVelocityAdami(; background_pressure) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -fluid_system = WeaklyCompressibleSPHSystem(fluid_particles, fluid_density_calculator, - state_equation, smoothing_kernel, - buffer_size=n_buffer_particles, - shifting_technique=shifting_technique, +fluid_system = WeaklyCompressibleSPHSystem(fluid_particles; smoothing_kernel, + smoothing_length, shifting_technique, + density_calculator=fluid_density_calculator, + state_equation, buffer_size=n_buffer_particles, density_diffusion=DensityDiffusionMolteniColagrossi(delta=0.1), - smoothing_length, viscosity=viscosity) + viscosity) # ========================================================================================== # ==== Open Boundary @@ -168,10 +168,8 @@ open_boundary = OpenBoundarySystem(inlet_zone, outlet_zone; fluid_system, # ========================================================================================== # ==== Boundary boundary_model = BoundaryModelDummyParticles(wall_boundary.density, wall_boundary.mass, - AdamiPressureExtrapolation(), - state_equation=state_equation, - viscosity=viscosity, - smoothing_kernel, smoothing_length) + AdamiPressureExtrapolation(), smoothing_kernel, + smoothing_length; state_equation, viscosity) boundary_system = WallBoundarySystem(wall_boundary, boundary_model) @@ -185,9 +183,7 @@ neighborhood_search = GridNeighborhoodSearch{3}(; max_corner), update_strategy=ParallelUpdate()) -semi = Semidiscretization(fluid_system, open_boundary, - boundary_system, - neighborhood_search=neighborhood_search, +semi = Semidiscretization(fluid_system, open_boundary, boundary_system; neighborhood_search, parallelization_backend=PolyesterBackend()) ode_problem = semidiscretize(semi, tspan) diff --git a/examples/fluid/pulsative_channel_flow_3d.jl b/examples/fluid/pulsative_channel_flow_3d.jl index 6a020fe016..82d9e10b66 100644 --- a/examples/fluid/pulsative_channel_flow_3d.jl +++ b/examples/fluid/pulsative_channel_flow_3d.jl @@ -14,8 +14,8 @@ using TrixiParticles # A more reasonable particle spacing factor is 30, which takes around an hour to 0.5s simulation time particle_spacing_factor = 15 -trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "poiseuille_flow_3d.jl"), - sol=nothing, particle_spacing_factor=particle_spacing_factor) +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "poiseuille_flow_3d.jl"); + sol=nothing, particle_spacing_factor) v_max = channel_diameter^2 * imposed_pressure_drop / (8 * dynamic_viscosity * channel_length) @@ -38,9 +38,7 @@ extra_callback = nothing # simulation end time has been shortened to avoid long runtimes in the example # a more full pulse is seen with a runtime of 3.0, which takes around 30m at particle_spacing_factor = 15 and around 6h at particle_spacing_factor = 30 simulation_end_time = 0.5 -trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "poiseuille_flow_3d.jl"), - tspan=(0.0, simulation_end_time), - particle_spacing_factor=particle_spacing_factor, - extra_callback=extra_callback, saving_callback=saving_callback, v_max=v_max, - inlet_reference_pressure=dynamic_pressure_drop, +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "poiseuille_flow_3d.jl"); + tspan=(0.0, simulation_end_time), particle_spacing_factor, extra_callback, + saving_callback, v_max, inlet_reference_pressure=dynamic_pressure_drop, outlet_reference_pressure=dynamic_pressure_drop) diff --git a/examples/fluid/sphere_surface_tension_2d.jl b/examples/fluid/sphere_surface_tension_2d.jl index ca33941ee3..1abcdcb149 100644 --- a/examples/fluid/sphere_surface_tension_2d.jl +++ b/examples/fluid/sphere_surface_tension_2d.jl @@ -7,7 +7,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK fluid_density = 1000.0 @@ -38,21 +38,18 @@ fluid = RectangularShape(particle_spacing, round.(Int, fluid_size ./ particle_sp alpha = 8 * nu / (smoothing_length * sound_speed) source_terms = SourceTermDamping(; damping_coefficient=0.5) -# fluid_system = WeaklyCompressibleSPHSystem(fluid, SummationDensity(), -# state_equation, fluid_smoothing_kernel, -# smoothing_length, -# reference_particle_spacing=particle_spacing, -# viscosity=ArtificialViscosityMonaghan(alpha=alpha, -# beta=0.0), +# fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel=fluid_smoothing_kernel, +# smoothing_length, density_calculator=SummationDensity(), +# state_equation, reference_particle_spacing=particle_spacing, +# viscosity=ArtificialViscosityMonaghan(; alpha, beta=0.0), # surface_tension=SurfaceTensionAkinci(surface_tension_coefficient=0.02), # correction=AkinciFreeSurfaceCorrection(fluid_density), -# source_terms=source_terms) +# source_terms) # Alternatively can also be used with surface_tension=SurfaceTensionMomentumMorris(surface_tension_coefficient=1.0) -fluid_system = EntropicallyDampedSPHSystem(fluid, fluid_smoothing_kernel, - smoothing_length, - sound_speed, - viscosity=ViscosityMorris(nu=nu), +fluid_system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel=fluid_smoothing_kernel, + smoothing_length, sound_speed, + viscosity=ViscosityMorris(; nu), density_calculator=ContinuityDensity(), reference_particle_spacing=particle_spacing, acceleration=zeros(length(fluid_size)), diff --git a/examples/fluid/sphere_surface_tension_3d.jl b/examples/fluid/sphere_surface_tension_3d.jl index 77eacb0ece..7cc8ce78af 100644 --- a/examples/fluid/sphere_surface_tension_3d.jl +++ b/examples/fluid/sphere_surface_tension_3d.jl @@ -8,7 +8,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK fluid_density = 1000.0 @@ -23,9 +23,8 @@ smoothing_length = 1.0 * particle_spacing nu = 0.04 trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "sphere_surface_tension_2d.jl"), - surface_tension_coefficient=0.5, dt=0.25, - tspan=(0.0, 100.0), nu=nu, smoothing_length=1.5 * particle_spacing, - fluid_smoothing_kernel=WendlandC2Kernel{3}(), - particle_spacing=particle_spacing, sound_speed=sound_speed, - fluid_density=fluid_density, fluid_size=fluid_size) + joinpath(examples_dir(), "fluid", "sphere_surface_tension_2d.jl"); + surface_tension_coefficient=0.5, dt=0.25, tspan=(0.0, 100.0), nu, + smoothing_length=1.5 * particle_spacing, + fluid_smoothing_kernel=WendlandC2Kernel{3}(), particle_spacing, sound_speed, + fluid_density, fluid_size) diff --git a/examples/fluid/sphere_surface_tension_wall_2d.jl b/examples/fluid/sphere_surface_tension_wall_2d.jl index 3df25ae986..5065536c93 100644 --- a/examples/fluid/sphere_surface_tension_wall_2d.jl +++ b/examples/fluid/sphere_surface_tension_wall_2d.jl @@ -8,7 +8,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -51,21 +51,18 @@ alpha = 8 * nu / (fluid_smoothing_length * sound_speed) # `adhesion_coefficient = 1.0` and `surface_tension_coefficient = 0.01` for perfect wetting # `adhesion_coefficient = 0.001` and `surface_tension_coefficient = 2.0` for no wetting -viscosity = ArtificialViscosityMonaghan(alpha=alpha, beta=0.0) -sphere_surface_tension = WeaklyCompressibleSPHSystem(sphere1, ContinuityDensity(), - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, - viscosity=viscosity, +viscosity = ArtificialViscosityMonaghan(; alpha, beta=0.0) +sphere_surface_tension = WeaklyCompressibleSPHSystem(sphere1; + smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity, acceleration=(0.0, -gravity), surface_tension=SurfaceTensionAkinci(surface_tension_coefficient=2.0), correction=AkinciFreeSurfaceCorrection(fluid_density), reference_particle_spacing=fluid_particle_spacing) -trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "falling_water_spheres_2d.jl"), - sphere=nothing, sphere1=sphere1, adhesion_coefficient=0.001, - wall_viscosity=4.0 * nu, surface_tension_coefficient=0.9, alpha=alpha, - sound_speed=sound_speed, fluid_density=fluid_density, nu=nu, - fluid_particle_spacing=fluid_particle_spacing, tspan=tspan, - tank_size=tank_size, fluid_smoothing_length=fluid_smoothing_length, - sphere_surface_tension=sphere_surface_tension) +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "falling_water_spheres_2d.jl"); + sphere=nothing, sphere1, adhesion_coefficient=0.001, wall_viscosity=4.0 * nu, + alpha, sound_speed, fluid_density, nu, fluid_particle_spacing, tspan, + tank_size, fluid_smoothing_length, sphere_surface_tension) diff --git a/examples/fluid/taylor_green_vortex_2d.jl b/examples/fluid/taylor_green_vortex_2d.jl index 0e13d3738d..afa2b96ebe 100644 --- a/examples/fluid/taylor_green_vortex_2d.jl +++ b/examples/fluid/taylor_green_vortex_2d.jl @@ -12,7 +12,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -81,18 +81,17 @@ if wcsph density_calculator = ContinuityDensity() state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) - fluid_system = WeaklyCompressibleSPHSystem(fluid, density_calculator, - state_equation, smoothing_kernel, + fluid_system = WeaklyCompressibleSPHSystem(fluid; + smoothing_kernel, smoothing_length, + density_calculator, state_equation, pressure_acceleration=TrixiParticles.inter_particle_averaged_pressure, - smoothing_length, viscosity=ViscosityAdami(; nu), shifting_technique=TransportVelocityAdami(; background_pressure)) else density_calculator = SummationDensity() - fluid_system = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, smoothing_length, - sound_speed, - density_calculator=density_calculator, + fluid_system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, smoothing_length, + sound_speed, density_calculator, shifting_technique=TransportVelocityAdami(; background_pressure), viscosity=ViscosityAdami(; nu)) diff --git a/examples/fsi/dam_break_gate_2d.jl b/examples/fsi/dam_break_gate_2d.jl index 4667b1af42..49d72f2aee 100644 --- a/examples/fsi/dam_break_gate_2d.jl +++ b/examples/fsi/dam_break_gate_2d.jl @@ -17,7 +17,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -47,9 +47,9 @@ sound_speed = 10 * sqrt(2 * gravity * initial_fluid_size[2]) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=7) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - acceleration=(0.0, -gravity), state_equation=state_equation, +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + acceleration=(0.0, -gravity), state_equation, coordinates_eltype=Float64) # Make the gate slightly higher than the fluid @@ -110,23 +110,27 @@ smoothing_kernel = WendlandC2Kernel{2}() fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.1, beta=0.0) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation, + clip_negative_pressure=true) boundary_model_gate = BoundaryModelDummyParticles(gate.density, gate.mass, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length) + 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, @@ -143,14 +147,16 @@ hydrodynamic_masses = hydrodynamic_densites * structure_particle_spacing^2 boundary_model_structure = BoundaryModelDummyParticles(hydrodynamic_densites, hydrodynamic_masses, - state_equation=state_equation, AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length) - -structure_system = TotalLagrangianSPHSystem(structure, - structure_smoothing_kernel, - structure_smoothing_length, - E, nu, boundary_model=boundary_model_structure, + smoothing_kernel, smoothing_length; + state_equation, + clip_negative_pressure=true) + +structure_system = TotalLagrangianSPHSystem(structure; + smoothing_kernel=structure_smoothing_kernel, + smoothing_length=structure_smoothing_length, + young_modulus=E, poisson_ratio=nu, + boundary_model=boundary_model_structure, clamped_particles=1:nparticles(clamped_particles), acceleration=(0.0, -gravity)) diff --git a/examples/fsi/dam_break_plate_2d.jl b/examples/fsi/dam_break_plate_2d.jl index 44d86c5317..3f6ff7bba0 100644 --- a/examples/fsi/dam_break_plate_2d.jl +++ b/examples/fsi/dam_break_plate_2d.jl @@ -12,7 +12,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -37,9 +37,9 @@ sound_speed = 20 * sqrt(gravity * initial_fluid_size[2]) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + acceleration=(0.0, -gravity), state_equation) # Elastic plate/beam length_beam = 0.08 @@ -80,18 +80,21 @@ smoothing_kernel = WendlandC2Kernel{2}() fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation, + clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) @@ -119,14 +122,16 @@ boundary_model_structure = BoundaryModelMonaghanKajtar(k_structure, spacing_rati # # boundary_model_structure = BoundaryModelDummyParticles(hydrodynamic_densites, # hydrodynamic_masses, -# state_equation=state_equation, # boundary_density_calculator, -# smoothing_kernel, smoothing_length) - -structure_system = TotalLagrangianSPHSystem(structure, - structure_smoothing_kernel, - structure_smoothing_length, - E, nu, boundary_model=boundary_model_structure, +# smoothing_kernel, smoothing_length; +# state_equation, +# clip_negative_pressure=true) + +structure_system = TotalLagrangianSPHSystem(structure; + smoothing_kernel=structure_smoothing_kernel, + smoothing_length=structure_smoothing_length, + young_modulus=E, poisson_ratio=nu, + boundary_model=boundary_model_structure, clamped_particles=1:nparticles(clamped_particles), acceleration=(0.0, -gravity), penalty_force=PenaltyForceGanzenmueller(alpha=0.01)) diff --git a/examples/fsi/falling_rigid_spheres_2d.jl b/examples/fsi/falling_rigid_spheres_2d.jl index 026e35793e..7eaa2b4dcb 100644 --- a/examples/fsi/falling_rigid_spheres_2d.jl +++ b/examples/fsi/falling_rigid_spheres_2d.jl @@ -5,7 +5,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -30,10 +30,10 @@ sound_speed = 100.0 state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - faces=(true, true, true, false), - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + faces=(true, true, true, false), acceleration=(0.0, -gravity), + state_equation) sphere1_radius = 0.3 sphere2_radius = 0.2 @@ -58,19 +58,23 @@ fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; + smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length) + fluid_smoothing_kernel, fluid_smoothing_length; + state_equation, + clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) @@ -83,10 +87,10 @@ hydrodynamic_masses_1 = hydrodynamic_densities_1 * boundary_model_structure_1 = BoundaryModelDummyParticles(hydrodynamic_densities_1, hydrodynamic_masses_1, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) + fluid_smoothing_length; + state_equation) hydrodynamic_densities_2 = fluid_density * ones(size(sphere2.density)) hydrodynamic_masses_2 = hydrodynamic_densities_2 * @@ -94,10 +98,10 @@ hydrodynamic_masses_2 = hydrodynamic_densities_2 * boundary_model_structure_2 = BoundaryModelDummyParticles(hydrodynamic_densities_2, hydrodynamic_masses_2, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) + fluid_smoothing_length; + state_equation) # Basic rigid contact model used for both rigid bodies. contact_model = RigidContactModel(; normal_stiffness=2.0e5, @@ -105,15 +109,11 @@ contact_model = RigidContactModel(; normal_stiffness=2.0e5, contact_distance=2.0 * structure_particle_spacing) -structure_system_1 = RigidBodySystem(sphere1; - boundary_model=boundary_model_structure_1, - contact_model=contact_model, - acceleration=(0.0, -gravity), +structure_system_1 = RigidBodySystem(sphere1; boundary_model=boundary_model_structure_1, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) -structure_system_2 = RigidBodySystem(sphere2; - boundary_model=boundary_model_structure_2, - contact_model=contact_model, - acceleration=(0.0, -gravity), +structure_system_2 = RigidBodySystem(sphere2; boundary_model=boundary_model_structure_2, + contact_model, acceleration=(0.0, -gravity), particle_spacing=structure_particle_spacing) # ========================================================================================== diff --git a/examples/fsi/falling_rotating_rigid_squares_2d.jl b/examples/fsi/falling_rotating_rigid_squares_2d.jl index 5eb1160ea0..b4758e39db 100644 --- a/examples/fsi/falling_rotating_rigid_squares_2d.jl +++ b/examples/fsi/falling_rotating_rigid_squares_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -31,10 +31,10 @@ sound_speed = 100.0 state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - faces=(true, true, true, false), - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + faces=(true, true, true, false), acceleration=(0.0, -gravity), + state_equation) square1_side_length = 0.4 square2_side_length = 0.3 @@ -74,19 +74,23 @@ fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; + smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length) + fluid_smoothing_kernel, fluid_smoothing_length; + state_equation, + clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) @@ -100,10 +104,11 @@ function structure_boundary_model(shape) return BoundaryModelDummyParticles(hydrodynamic_densities, hydrodynamic_masses, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) + fluid_smoothing_length; + state_equation, + clip_negative_pressure=true) end boundary_model_structure_1 = structure_boundary_model(square1) diff --git a/examples/fsi/falling_rotating_rigid_squares_w_buoys_2d.jl b/examples/fsi/falling_rotating_rigid_squares_w_buoys_2d.jl index 37efb627a9..61d77bcdb1 100644 --- a/examples/fsi/falling_rotating_rigid_squares_w_buoys_2d.jl +++ b/examples/fsi/falling_rotating_rigid_squares_w_buoys_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK tspan = (0.0, 2.0) @@ -38,5 +38,5 @@ extra_structure_systems = [begin for x in small_sphere_x_positions] trixi_include(@__MODULE__, - joinpath(examples_dir(), "fsi", "falling_rotating_rigid_squares_2d.jl"), - extra_structure_systems=extra_structure_systems, tspan=tspan); + joinpath(examples_dir(), "fsi", "falling_rotating_rigid_squares_2d.jl"); + extra_structure_systems, tspan); diff --git a/examples/fsi/falling_spheres_2d.jl b/examples/fsi/falling_spheres_2d.jl index e938cbf6f8..035f9ad3da 100644 --- a/examples/fsi/falling_spheres_2d.jl +++ b/examples/fsi/falling_spheres_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -31,10 +31,10 @@ sound_speed = 10 * sqrt(gravity * initial_fluid_size[2]) state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density, exponent=1) -tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, - faces=(true, true, true, false), - acceleration=(0.0, -gravity), state_equation=state_equation) +tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density; + n_layers=boundary_layers, spacing_ratio, + faces=(true, true, true, false), acceleration=(0.0, -gravity), + state_equation) sphere1_radius = 0.3 sphere2_radius = 0.2 @@ -62,19 +62,23 @@ fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) -fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, viscosity=viscosity, - density_diffusion=density_diffusion, +fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; + smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, density_diffusion, acceleration=(0.0, -gravity)) # ========================================================================================== # ==== Boundary 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, - state_equation=state_equation, boundary_density_calculator, - fluid_smoothing_kernel, fluid_smoothing_length) + fluid_smoothing_kernel, fluid_smoothing_length; + state_equation, + clip_negative_pressure=true) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) @@ -90,10 +94,11 @@ hydrodynamic_masses_1 = hydrodynamic_densites_1 * structure_boundary_model_1 = BoundaryModelDummyParticles(hydrodynamic_densites_1, hydrodynamic_masses_1, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) + fluid_smoothing_length; + state_equation, + clip_negative_pressure=true) hydrodynamic_densites_2 = fluid_density * ones(size(sphere2.density)) hydrodynamic_masses_2 = hydrodynamic_densites_2 * @@ -101,23 +106,26 @@ hydrodynamic_masses_2 = hydrodynamic_densites_2 * structure_boundary_model_2 = BoundaryModelDummyParticles(hydrodynamic_densites_2, hydrodynamic_masses_2, - state_equation=state_equation, boundary_density_calculator, fluid_smoothing_kernel, - fluid_smoothing_length) - -structure_system_1 = TotalLagrangianSPHSystem(sphere1, - structure_smoothing_kernel, - structure_smoothing_length, - sphere1_E, nu, + fluid_smoothing_length; + state_equation, + clip_negative_pressure=true) + +structure_system_1 = TotalLagrangianSPHSystem(sphere1; + smoothing_kernel=structure_smoothing_kernel, + smoothing_length=structure_smoothing_length, + young_modulus=sphere1_E, + poisson_ratio=nu, acceleration=(0.0, -gravity), boundary_model=structure_boundary_model_1, penalty_force=PenaltyForceGanzenmueller(alpha=0.3)) -structure_system_2 = TotalLagrangianSPHSystem(sphere2, - structure_smoothing_kernel, - structure_smoothing_length, - sphere2_E, nu, +structure_system_2 = TotalLagrangianSPHSystem(sphere2; + smoothing_kernel=structure_smoothing_kernel, + smoothing_length=structure_smoothing_length, + young_modulus=sphere2_E, + poisson_ratio=nu, acceleration=(0.0, -gravity), boundary_model=structure_boundary_model_2, penalty_force=PenaltyForceGanzenmueller(alpha=0.3)) diff --git a/examples/fsi/falling_water_column_2d.jl b/examples/fsi/falling_water_column_2d.jl index 210806213d..4f886d4f20 100644 --- a/examples/fsi/falling_water_column_2d.jl +++ b/examples/fsi/falling_water_column_2d.jl @@ -7,16 +7,15 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution n_particles_y = 5 # Load setup from oscillating beam example -trixi_include(@__MODULE__, joinpath(examples_dir(), "structure", "oscillating_beam_2d.jl"), - thickness=0.05, n_particles_y=n_particles_y, - sol=nothing) # Don't run simulation, only include the setup part +trixi_include(@__MODULE__, joinpath(examples_dir(), "structure", "oscillating_beam_2d.jl"); + thickness=0.05, n_particles_y, sol=nothing) # Don't run simulation, only include the setup part # Fluid resolution fluid_particle_spacing = 3 * particle_spacing @@ -47,9 +46,10 @@ fluid_smoothing_kernel = SchoenbergCubicSplineKernel{2}() fluid_density_calculator = ContinuityDensity() viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) -fluid_system = WeaklyCompressibleSPHSystem(fluid, fluid_density_calculator, - state_equation, fluid_smoothing_kernel, - fluid_smoothing_length, viscosity=viscosity, +fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel=fluid_smoothing_kernel, + smoothing_length=fluid_smoothing_length, + density_calculator=fluid_density_calculator, + state_equation, viscosity, acceleration=(0.0, -gravity)) # ========================================================================================== @@ -64,10 +64,9 @@ hydrodynamic_masses = hydrodynamic_densites * particle_spacing^2 boundary_model = BoundaryModelMonaghanKajtar(k, spacing_ratio, particle_spacing, hydrodynamic_masses) -structure_system = TotalLagrangianSPHSystem(structure, - smoothing_kernel, smoothing_length, - material.E, material.nu, - boundary_model=boundary_model, +structure_system = TotalLagrangianSPHSystem(structure; smoothing_kernel, smoothing_length, + young_modulus=material.E, + poisson_ratio=material.nu, boundary_model, clamped_particles=1:nparticles(clamped_particles), acceleration=(0.0, -gravity)) diff --git a/examples/fsi/hydrostatic_water_column_2d.jl b/examples/fsi/hydrostatic_water_column_2d.jl index 22a132fd3e..9fd7e15a36 100644 --- a/examples/fsi/hydrostatic_water_column_2d.jl +++ b/examples/fsi/hydrostatic_water_column_2d.jl @@ -9,7 +9,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK using JSON # ========================================================================================== @@ -65,7 +65,7 @@ right_wall = RectangularShape(structure_particle_spacing, (3, n_particles_plate_ place_on_shell=true) fixed_particles = union(left_wall, right_wall) -structure_geometry = union(plate, fixed_particles) +structure_geometry = union(fixed_particles, plate) # ========================================================================================== # ==== Smoothing Kernel, Boundary, and Related Quantities @@ -86,16 +86,16 @@ state_equation = use_edac ? nothing : exponent=7, clip_negative_pressure=false) tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, (plate_size[1], 3.0), - min_coordinates=(0.0, fluid_particle_spacing / 2), - fluid_density, n_layers=boundary_layers, - spacing_ratio=spacing_ratio, - faces=(true, true, false, false), - acceleration=(0.0, -gravity), - state_equation=state_equation) + fluid_density; min_coordinates=(0.0, fluid_particle_spacing / 2), + n_layers=boundary_layers, spacing_ratio, + faces=(true, true, false, false), acceleration=(0.0, -gravity), + state_equation) if use_edac - fluid_system = EntropicallyDampedSPHSystem(tank.fluid, smoothing_kernel, - smoothing_length_fluid, sound_speed, + fluid_system = EntropicallyDampedSPHSystem(tank.fluid; + smoothing_kernel, + smoothing_length=smoothing_length_fluid, + sound_speed, acceleration=(0.0, -gravity), correction=ShepardKernelCorrection(), source_terms=SourceTermDamping(; @@ -103,31 +103,33 @@ if use_edac else fluid_density_calculator = ContinuityDensity() density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1) - # density_diffusion = DensityDiffusionAntuono(tank.fluid, delta=0.1) - fluid_system = WeaklyCompressibleSPHSystem(tank.fluid, fluid_density_calculator, - state_equation, smoothing_kernel, - smoothing_length_fluid, - density_diffusion=density_diffusion, + # density_diffusion = DensityDiffusionAntuono(delta=0.1) + fluid_system = WeaklyCompressibleSPHSystem(tank.fluid; smoothing_kernel, + smoothing_length=smoothing_length_fluid, + density_calculator=fluid_density_calculator, + state_equation, density_diffusion, acceleration=(0.0, -gravity), source_terms=SourceTermDamping(; damping_coefficient=0.05)) end boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass, - state_equation=state_equation, boundary_density_calculator, - smoothing_kernel, smoothing_length_fluid) + smoothing_kernel, smoothing_length_fluid; + state_equation) boundary_system = WallBoundarySystem(tank.boundary, boundary_model) boundary_model_structure = BoundaryModelDummyParticles(hydrodynamic_densities, hydrodynamic_masses, - state_equation=state_equation, boundary_density_calculator, smoothing_kernel, - smoothing_length_structure) -structure_system = TotalLagrangianSPHSystem(structure_geometry, smoothing_kernel, - smoothing_length_structure, - E, nu, boundary_model=boundary_model_structure, - n_clamped_particles=nparticles(fixed_particles), + smoothing_length_structure; + state_equation) +structure_system = TotalLagrangianSPHSystem(structure_geometry; + smoothing_kernel, + smoothing_length=smoothing_length_structure, + young_modulus=E, poisson_ratio=nu, + boundary_model=boundary_model_structure, + clamped_particles=1:nparticles(fixed_particles), acceleration=(0.0, -gravity)) min_corner = min.(minimum(structure_geometry.coordinates, dims=2), @@ -140,9 +142,8 @@ max_corner = max.(maximum(structure_geometry.coordinates, dims=2), cell_list = FullGridCellList(; min_corner, max_corner) neighborhood_search = GridNeighborhoodSearch{2}(; update_strategy=ParallelUpdate(), cell_list) -semi = Semidiscretization(structure_system, fluid_system, boundary_system, - neighborhood_search=neighborhood_search, - parallelization_backend=PolyesterBackend()) +semi = Semidiscretization(structure_system, fluid_system, boundary_system; + neighborhood_search, parallelization_backend=PolyesterBackend()) ode = semidiscretize(semi, tspan) split_integration = SplitIntegrationCallback(CarpenterKennedy2N54(williamson_condition=false), diff --git a/examples/n_body/n_body_solar_system.jl b/examples/n_body/n_body_solar_system.jl index 060eab5330..505ebae238 100644 --- a/examples/n_body/n_body_solar_system.jl +++ b/examples/n_body/n_body_solar_system.jl @@ -4,7 +4,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqSymplecticRK using Printf include("n_body_system.jl") diff --git a/examples/preprocessing/packing_2d.jl b/examples/preprocessing/packing_2d.jl index 0975b6e2ad..02951323ef 100644 --- a/examples/preprocessing/packing_2d.jl +++ b/examples/preprocessing/packing_2d.jl @@ -13,7 +13,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq, Plots +using OrdinaryDiffEqLowStorageRK, Plots filename = "circle" file = pkgdir(TrixiParticles, "examples", "preprocessing", "data", filename * ".asc") @@ -50,7 +50,7 @@ shape_sampled = ComplexShape(geometry; particle_spacing, density, # Returns `InitialCondition` boundary_sampled = sample_boundary(signed_distance_field; boundary_density=density, - boundary_thickness, place_on_shell=place_on_shell) + boundary_thickness, place_on_shell) trixi2vtk(shape_sampled) trixi2vtk(boundary_sampled, filename="boundary") @@ -65,14 +65,13 @@ trixi2vtk(boundary_sampled, filename="boundary") background_pressure = 1.0 smoothing_length = 0.8 * particle_spacing -packing_system = ParticlePackingSystem(shape_sampled; smoothing_length=smoothing_length, - signed_distance_field, place_on_shell=place_on_shell, +packing_system = ParticlePackingSystem(shape_sampled; smoothing_length, + signed_distance_field, place_on_shell, background_pressure) -boundary_system = ParticlePackingSystem(boundary_sampled; smoothing_length=smoothing_length, +boundary_system = ParticlePackingSystem(boundary_sampled; smoothing_length, is_boundary=true, signed_distance_field, - place_on_shell=place_on_shell, - boundary_compress_factor=0.8, + place_on_shell, boundary_compress_factor=0.8, background_pressure) # ========================================================================================== diff --git a/examples/preprocessing/packing_3d.jl b/examples/preprocessing/packing_3d.jl index ede3433b38..e0ecf84791 100644 --- a/examples/preprocessing/packing_3d.jl +++ b/examples/preprocessing/packing_3d.jl @@ -8,7 +8,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK filename = "sphere" file = pkgdir(TrixiParticles, "examples", "preprocessing", "data", filename * ".stl") @@ -22,7 +22,6 @@ particle_spacing = 0.1 # how many rows of boundary particles will be sampled. boundary_thickness = 8 * particle_spacing -trixi_include(joinpath(examples_dir(), "preprocessing", "packing_2d.jl"), - density=1000.0, particle_spacing=particle_spacing, file=file, - boundary_thickness=boundary_thickness, place_on_shell=true, +trixi_include(joinpath(examples_dir(), "preprocessing", "packing_2d.jl"); density=1000.0, + particle_spacing, file, boundary_thickness, place_on_shell=true, save_intervals=false) diff --git a/examples/structure/colliding_rigid_spheres_2d.jl b/examples/structure/colliding_rigid_spheres_2d.jl index 6bfa1877d1..732457b121 100644 --- a/examples/structure/colliding_rigid_spheres_2d.jl +++ b/examples/structure/colliding_rigid_spheres_2d.jl @@ -6,7 +6,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -36,14 +36,10 @@ contact_model = RigidContactModel(; normal_stiffness=2.0e4, normal_damping=120.0, contact_distance=2.0 * particle_spacing) -structure_system_1 = RigidBodySystem(sphere_1; - contact_model=contact_model, - acceleration=(0.0, 0.0), - particle_spacing=particle_spacing) -structure_system_2 = RigidBodySystem(sphere_2; - contact_model=contact_model, - acceleration=(0.0, 0.0), - particle_spacing=particle_spacing) +structure_system_1 = RigidBodySystem(sphere_1; contact_model, acceleration=(0.0, 0.0), + particle_spacing) +structure_system_2 = RigidBodySystem(sphere_2; contact_model, acceleration=(0.0, 0.0), + particle_spacing) # ========================================================================================== # ==== Simulation diff --git a/examples/structure/oscillating_beam_2d.jl b/examples/structure/oscillating_beam_2d.jl index b48a10bcbf..784692001c 100644 --- a/examples/structure/oscillating_beam_2d.jl +++ b/examples/structure/oscillating_beam_2d.jl @@ -14,7 +14,7 @@ # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # ========================================================================================== # ==== Resolution @@ -60,8 +60,9 @@ structure = union(clamped_particles, beam) smoothing_length = sqrt(2) * particle_spacing smoothing_kernel = WendlandC2Kernel{2}() -structure_system = TotalLagrangianSPHSystem(structure, smoothing_kernel, smoothing_length, - material.E, material.nu, +structure_system = TotalLagrangianSPHSystem(structure; smoothing_kernel, smoothing_length, + young_modulus=material.E, + poisson_ratio=material.nu, clamped_particles=1:nparticles(clamped_particles), acceleration=(0.0, -gravity), penalty_force=nothing, viscosity=nothing, @@ -96,9 +97,7 @@ function deflection_y(system, data, t) return data.coordinates[2, middle_particle_id] - STARTPOSITION_Y end -saving_callback = SolutionSavingCallback(dt=0.02, prefix="", - deflection_x=deflection_x, - deflection_y=deflection_y) +saving_callback = SolutionSavingCallback(dt=0.02, prefix=""; deflection_x, deflection_y) callbacks = CallbackSet(info_callback, saving_callback) diff --git a/src/callbacks/info.jl b/src/callbacks/info.jl index 59b6d3454e..811f01146d 100644 --- a/src/callbacks/info.jl +++ b/src/callbacks/info.jl @@ -40,9 +40,8 @@ function InfoCallback(; interval=0, reset_threads=true) reset_threads) end - DiscreteCallback(info_callback, info_callback, - save_positions=(false, false), - initialize=initialize) + DiscreteCallback(info_callback, info_callback; save_positions=(false, false), + initialize) end # condition @@ -163,7 +162,7 @@ function format_key_value_line(key::AbstractString, value::AbstractString, key_w # Indent the key as requested (or not at all if `indentation_level == 0`) indentation = prefix^indentation_level reduced_key_width = key_width - length(indentation) - squeezed_key = indentation * squeeze(key, reduced_key_width, filler=filler) + squeezed_key = indentation * squeeze(key, reduced_key_width; filler) line *= squeezed_key line *= ": " short = key_width - length(squeezed_key) @@ -173,7 +172,7 @@ function format_key_value_line(key::AbstractString, value::AbstractString, key_w line *= guide^(short - 1) * " " end value_width = total_width - length(prefix) - length(suffix) - key_width - 2 - squeezed_value = squeeze(value, value_width, filler=filler) + squeezed_value = squeeze(value, value_width; filler) line *= squeezed_value short = value_width - length(squeezed_value) line *= " "^short @@ -239,8 +238,7 @@ function summary_line(io, key, value; key_width=30, total_width=100, indentation total_width = get(io, :total_width, total_width) indentation_level = get(io, :indentation_level, indentation_level) - s = format_key_value_line(key, value, key_width, total_width, - indentation_level=indentation_level) + s = format_key_value_line(key, value, key_width, total_width; indentation_level) println(io, s) end diff --git a/src/callbacks/solution_saving.jl b/src/callbacks/solution_saving.jl index 1fbdae547a..a3ac18b604 100644 --- a/src/callbacks/solution_saving.jl +++ b/src/callbacks/solution_saving.jl @@ -158,8 +158,7 @@ end function (solution_callback::SolutionSavingCallback)(u, t, integrator) (; interval, save_final_solution) = solution_callback - return condition_integrator_interval(integrator, interval, - save_final_solution=save_final_solution) + return condition_integrator_interval(integrator, interval; save_final_solution) end # `affect!` diff --git a/src/callbacks/split_integration.jl b/src/callbacks/split_integration.jl index feff7e26bf..39939a837e 100644 --- a/src/callbacks/split_integration.jl +++ b/src/callbacks/split_integration.jl @@ -32,7 +32,7 @@ of fluid to solid particles is large enough (e.g. 100:1 or more). # Examples ```jldoctest; output=false -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK # Low-storage RK method with fixed step size callback = SplitIntegrationCallback(CarpenterKennedy2N54(williamson_condition=false), diff --git a/src/general/corrections.jl b/src/general/corrections.jl index 2cebdb8db8..db82309881 100644 --- a/src/general/corrections.jl +++ b/src/general/corrections.jl @@ -326,7 +326,9 @@ function compute_gradient_correction_matrix!(corr_matrix, system, coordinates, d volume = @inbounds mass[neighbor] / density_fun(neighbor) - result = volume * grad_kernel * pos_diff' + # This is the same as using `transpose`, but it's faster due to + # https://github.com/JuliaLang/LinearAlgebra.jl/issues/1102. + result = volume * grad_kernel * permutedims(pos_diff) for j in 1:ndims(system), i in 1:ndims(system) @inbounds corr_matrix[i, j, particle] -= result[i, j] @@ -380,7 +382,9 @@ function compute_gradient_correction_matrix!(corr_matrix::AbstractArray, system, volume = hydrodynamic_mass(neighbor_system, neighbor) / current_density(v_neighbor_system, neighbor_system, neighbor) - L = volume * grad_kernel * pos_diff' + # This is the same as using `transpose`, but it's faster due to + # https://github.com/JuliaLang/LinearAlgebra.jl/issues/1102. + L = volume * grad_kernel * permutedims(pos_diff) # pos_diff is always x_a - x_b hence * -1 to switch the order to x_b - x_a @inbounds for j in 1:ndims(system), i in 1:ndims(system) diff --git a/src/general/interpolation.jl b/src/general/interpolation.jl index 58b171d0f7..8ab74d5e73 100644 --- a/src/general/interpolation.jl +++ b/src/general/interpolation.jl @@ -405,8 +405,8 @@ function interpolate_line(start, end_, n_points, semi, ref_system, v_ode, u_ode; points_coords_ = collect(reinterpret(reshape, eltype(start_svector), points_coords)) return interpolate_points(points_coords_, semi, ref_system, v_ode, u_ode; - smoothing_length=smoothing_length, include_wall_velocity, - cut_off_bnd=cut_off_bnd, clip_negative_pressure) + smoothing_length, include_wall_velocity, cut_off_bnd, + clip_negative_pressure) end @doc raw""" @@ -637,8 +637,7 @@ end end end - return (; computed_density=computed_density, point_coords=point_coords, - neighbor_count=neighbor_count, cache...) + return (; computed_density, point_coords, neighbor_count, cache...) end @inline function create_cache_interpolation(ref_system::AbstractFluidSystem, n_points, semi) diff --git a/src/general/semidiscretization.jl b/src/general/semidiscretization.jl index b2d7a20b04..7b91c0baf9 100644 --- a/src/general/semidiscretization.jl +++ b/src/general/semidiscretization.jl @@ -325,7 +325,7 @@ in the solution `sol`. # Arguments - `semi`: The semidiscretization -- `sol`: The `ODESolution` returned by `solve` of `OrdinaryDiffEq` +- `sol`: The `ODESolution` returned by `solve` of OrdinaryDiffEq.jl """ function restart_with!(semi, sol; reset_threads=true) # Optionally reset Polyester.jl threads. See @@ -711,7 +711,7 @@ function system_interaction!(dv_ode, v_ode, u_ode, semi) timer_str = "" end - interact!(dv_ode, v_ode, u_ode, system, neighbor, semi, timer_str=timer_str) + interact!(dv_ode, v_ode, u_ode, system, neighbor, semi; timer_str) end end diff --git a/src/general/time_integration.jl b/src/general/time_integration.jl index 2d1827b1a5..c4a8fd878c 100644 --- a/src/general/time_integration.jl +++ b/src/general/time_integration.jl @@ -1,7 +1,7 @@ # Time integration is handled by the package OrdinaryDiffEq.jl. # See the docs for more details. # In this file, we define the structs for extra time integration schemes that -# are implemented in the package extension TrixiParticlesOrdinaryDiffEqExt.jl. +# are implemented in the package extension TrixiParticlesOrdinaryDiffEqSymplecticRKExt. """ SymplecticPositionVerlet() @@ -16,5 +16,5 @@ and [Domínguez et al. 2022, Section 2.5.2](@cite Dominguez2022). See [time integration](@ref time_integration) for more details. """ function SymplecticPositionVerlet(_...) - error("the package OrdinaryDiffEq.jl needs to be loaded to use this scheme.") + error("the package OrdinaryDiffEqSymplecticRK needs to be loaded to use this scheme.") end diff --git a/src/io/read_vtk.jl b/src/io/read_vtk.jl index c2e4021173..86bae1af77 100644 --- a/src/io/read_vtk.jl +++ b/src/io/read_vtk.jl @@ -1,7 +1,11 @@ """ - vtk2trixi(file::String; element_type=nothing, coordinates_eltype=nothing) + vtk2trixi(file::String; element_type=nothing, coordinates_eltype=nothing, + create_initial_condition=true) -Load VTK file and convert data to an [`InitialCondition`](@ref). +Read a VTK file and return a `NamedTuple` with keys +`:coordinates`, `:velocity`, `:density`, `:pressure`, `:particle_spacing`, `:time`, `:initial_condition`, +plus any custom quantities. +Missing fields are zero-filled; `:particle_spacing` is scalar if constant, otherwise per-particle. # Arguments - `file`: Name of the VTK file to be loaded. @@ -13,35 +17,32 @@ Load VTK file and convert data to an [`InitialCondition`](@ref). - `coordinates_eltype`: Element type for particle coordinates. By default, the type stored in the VTK file is used. Otherwise, data is converted to the specified type. +- `create_initial_condition`: If `true`, an `InitialCondition` object is created + and included in the returned `NamedTuple` under + the key `:initial_condition`. Default is `true`. !!! warning "Experimental Implementation" This is an experimental feature and may change in any future releases. # Example -```jldoctest; output = false +```jldoctest; output = false, filter = r"density = \\[.*\\]|pressure = \\[.*\\]|velocity = \\[.*\\]|coordinates = \\[.*\\]" # Create a rectangular shape rectangular = RectangularShape(0.1, (10, 10), (0, 0), density=1.5, velocity=(1.0, -2.0), pressure=1000.0) -# Write the `InitialCondition` to a vtk file -trixi2vtk(rectangular; filename="rectangular", output_directory="out") +# Write the `InitialCondition` with custom quantity to a VTK file +trixi2vtk(rectangular; filename="rectangular", output_directory="out", + my_custom_quantity=3.0) -# Read the vtk file and convert it to `InitialCondition` -ic = vtk2trixi(joinpath("out", "rectangular.vtu")) +# Read the VTK file and convert the data to a `NamedTuple` +data = vtk2trixi(joinpath("out", "rectangular.vtu")) # output -┌──────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ InitialCondition │ -│ ════════════════ │ -│ #dimensions: ……………………………………………… 2 │ -│ #particles: ………………………………………………… 100 │ -│ particle spacing: ………………………………… 0.1 │ -│ eltype: …………………………………………………………… Float64 │ -│ coordinate eltype: ……………………………… Float64 │ -└──────────────────────────────────────────────────────────────────────────────────────────────────┘ +(particle_spacing = 0.1, density = [...], time = 0.0, pressure = [...], mass = [...], my_custom_quantity = 3.0, velocity = [...], coordinates = [...], initial_condition = InitialCondition{Float64, Float64}()) ``` """ -function vtk2trixi(file; element_type=nothing, coordinates_eltype=nothing) +function vtk2trixi(file; element_type=nothing, coordinates_eltype=nothing, + create_initial_condition=true) vtk_file = ReadVTK.VTKFile(file) # Retrieve data fields (e.g., pressure, velocity, ...) @@ -53,38 +54,67 @@ function vtk2trixi(file; element_type=nothing, coordinates_eltype=nothing) ELTYPE = isnothing(element_type) ? eltype(first(ReadVTK.get_data(point_data["pressure"]))) : element_type + results = Dict{Symbol, Any}() + + # Tracking used keys like `initial_velocity` + used_keys = String[] + # Retrieve fields ndims = first(ReadVTK.get_data(field_data["ndims"])) coordinates = convert.(cELTYPE, point_coords[1:ndims, :]) - fields = ["velocity", "density", "pressure", "mass", "particle_spacing"] - results = Dict{String, Array{Float64}}() - + fields = [:velocity, :density, :pressure, :particle_spacing] for field in fields # First look for an exact key match, then fall back to substring matching. all_keys = keys(point_data) - idx = findfirst(k -> k == field, all_keys) + idx = findfirst(k -> k == string(field), all_keys) if idx === nothing - idx = findfirst(k -> occursin(field, k), all_keys) + idx = findfirst(k -> occursin(string(field), k), all_keys) end if idx !== nothing results[field] = convert.(ELTYPE, ReadVTK.get_data(point_data[all_keys[idx]])) + push!(used_keys, all_keys[idx]) else # Use zeros as default values when a field is missing - results[field] = field in ["mass"] ? - zeros(ELTYPE, size(coordinates, 2)) : zero(coordinates) + results[field] = string(field) in ["velocity"] ? + zero(coordinates) : zeros(ELTYPE, size(coordinates, 2)) @info "No '$field' field found in VTK file. Will be set to zero." end end - particle_spacing = allequal(results["particle_spacing"]) ? - first(results["particle_spacing"]) : - results["particle_spacing"] + results[:particle_spacing] = allequal(results[:particle_spacing]) ? + first(results[:particle_spacing]) : + results[:particle_spacing] + results[:coordinates] = coordinates + results[:time] = "time" in keys(field_data) ? + first(ReadVTK.get_data(field_data["time"])) : zero(ELTYPE) + + append!(used_keys, ["index", "ndims"]) + # Load any custom quantities + for key in keys(point_data) + if !(key in used_keys) + results[Symbol(key)] = convert.(ELTYPE, ReadVTK.get_data(point_data[key])) + end + end + + for key in keys(field_data) + if !(key in used_keys) + data = ReadVTK.get_data(field_data[key]) + conv_data = convert.(ELTYPE, data) + results[Symbol(key)] = length(conv_data) == 1 ? first(conv_data) : conv_data + end + end + + results = NamedTuple(results) + + if create_initial_condition + ic = InitialCondition(; coordinates=results.coordinates, + particle_spacing=results.particle_spacing, + velocity=results.velocity, density=results.density, + pressure=results.pressure) - return InitialCondition(; coordinates, - particle_spacing=convert(ELTYPE, particle_spacing), - velocity=results["velocity"], - mass=results["mass"], - density=results["density"], - pressure=results["pressure"]) + return (; results..., initial_condition=ic) + else + return results + end end diff --git a/src/io/write_vtk.jl b/src/io/write_vtk.jl index 2ac9c0694b..58bb3868a6 100644 --- a/src/io/write_vtk.jl +++ b/src/io/write_vtk.jl @@ -101,8 +101,16 @@ function trixi2vtk(system_, dvdu_ode_, vu_ode_, semi_, t, periodic_box; # Transfer to CPU if data is on the GPU. Do nothing if already on CPU. v_ode, u_ode, system, semi = transfer2cpu(v_ode_, u_ode_, system_, semi_) - v = wrap_v(v_ode, system, semi) - u = wrap_u(u_ode, system, semi) + if v_ode_ isa AbstractGPUArray || u_ode_ isa AbstractGPUArray + system_index = system_indices(system, semi) + v = reshape(view(v_ode, semi.ranges_v[system_index]), v_nvariables(system), + n_integrated_particles(system)) + u = reshape(view(u_ode, semi.ranges_u[system_index]), u_nvariables(system), + n_integrated_particles(system)) + else + v = wrap_v(v_ode, system, semi) + u = wrap_u(u_ode, system, semi) + end overwrite = isnothing(iter) @@ -309,11 +317,11 @@ function trixi2vtk(initial_condition::InitialCondition; output_directory="out", prefix="", filename="initial_condition", custom_quantities...) (; coordinates, velocity, density, mass, pressure) = initial_condition - return trixi2vtk(coordinates; output_directory, prefix, filename, - density=density, initial_velocity=velocity, mass=mass, + return trixi2vtk(coordinates; output_directory, prefix, filename, density, + initial_velocity=velocity, mass, particle_spacing=(initial_condition.particle_spacing .* - ones(nparticles(initial_condition))), - pressure=pressure, custom_quantities...) + ones(nparticles(initial_condition))), pressure, + custom_quantities...) end function write2vtk!(vtk, v, u, t, system) diff --git a/src/preprocessing/geometries/io.jl b/src/preprocessing/geometries/io.jl index ea97f6dcf1..bbccc276ec 100644 --- a/src/preprocessing/geometries/io.jl +++ b/src/preprocessing/geometries/io.jl @@ -278,8 +278,8 @@ function trixi2vtk(geometry::Polygon; output_directory="out", prefix="", push!(vertices, geometry.vertices[geometry.edge_vertices_ids[edge][2]]) end - return trixi2vtk(stack(vertices); output_directory, filename, prefix, - vertex_normals=vertex_normals, custom_quantities...) + return trixi2vtk(stack(vertices); output_directory, filename, prefix, vertex_normals, + custom_quantities...) end function trixi2vtk(geometry::TriangleMesh; output_directory="out", prefix="", @@ -288,5 +288,5 @@ function trixi2vtk(geometry::TriangleMesh; output_directory="out", prefix="", for face in eachindex(geometry.vertices)]) return trixi2vtk(stack(geometry.vertices); output_directory, filename, prefix, - vertex_normals=vertex_normals, custom_quantities...) + vertex_normals, custom_quantities...) end diff --git a/src/preprocessing/particle_packing/signed_distance.jl b/src/preprocessing/particle_packing/signed_distance.jl index e6bbc6891f..01e862365f 100644 --- a/src/preprocessing/particle_packing/signed_distance.jl +++ b/src/preprocessing/particle_packing/signed_distance.jl @@ -103,8 +103,7 @@ function trixi2vtk(signed_distance_field::SignedDistanceField; (; positions, distances, normals) = signed_distance_field positions = stack(signed_distance_field.positions) - trixi2vtk(positions, signed_distances=distances, normals=normals, - filename=filename, output_directory=output_directory) + trixi2vtk(positions; signed_distances=distances, normals, filename, output_directory) end delete_positions_in_empty_cells!(positions, nhs::TrivialNeighborhoodSearch) = positions diff --git a/src/schemes/boundary/dem_boundary/system.jl b/src/schemes/boundary/dem_boundary/system.jl index 02bfe1b415..cfb0d5247d 100644 --- a/src/schemes/boundary/dem_boundary/system.jl +++ b/src/schemes/boundary/dem_boundary/system.jl @@ -1,9 +1,15 @@ """ - BoundaryDEMSystem(initial_condition, normal_stiffness) + BoundaryDEMSystem(initial_condition; normal_stiffness) System for boundaries modeled by boundary particles. The interaction between fluid and boundary particles is specified by the boundary model. +# Arguments +- `initial_condition`: Initial condition of the boundary particles. + +# Keywords +- `normal_stiffness`: Normal stiffness used for DEM wall contact. + !!! warning "Experimental Implementation" This is an experimental feature and may change in a future releases. @@ -16,6 +22,8 @@ struct BoundaryDEMSystem{NDIMS, ELTYPE <: Real, IC, normal_stiffness :: ELTYPE buffer :: Nothing + # This constructor is necessary for Adapt.jl to work with this struct. + # See the comments in general/gpu.jl for more details. function BoundaryDEMSystem(initial_condition, coordinates, radius, normal_stiffness, buffer) NDIMS = ndims(initial_condition) @@ -27,9 +35,7 @@ struct BoundaryDEMSystem{NDIMS, ELTYPE <: Real, IC, end 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 BoundaryDEMSystem(initial_condition, normal_stiffness) +function BoundaryDEMSystem(initial_condition; normal_stiffness) ELTYPE = eltype(initial_condition) coordinates = initial_condition.coordinates radius = initial_condition.particle_spacing * diff --git a/src/schemes/boundary/open_boundary/system.jl b/src/schemes/boundary/open_boundary/system.jl index 75ed87aad2..3e4754d4ad 100644 --- a/src/schemes/boundary/open_boundary/system.jl +++ b/src/schemes/boundary/open_boundary/system.jl @@ -143,9 +143,8 @@ function create_cache_open_boundary(boundary_model, fluid_system, initial_condit density_reference_values = map(ref -> ref.reference_density, reference_values) velocity_reference_values = map(ref -> ref.reference_velocity, reference_values) - cache = (; pressure_reference_values=pressure_reference_values, - density_reference_values=density_reference_values, - velocity_reference_values=velocity_reference_values) + cache = (; pressure_reference_values, density_reference_values, + velocity_reference_values) if calculate_flow_rate || any(pr -> isa(pr, RCRWindkesselModel), cache.pressure_reference_values) @@ -164,8 +163,7 @@ function create_cache_open_boundary(boundary_model, fluid_system, initial_condit characteristics = zeros(ELTYPE, 3, nparticles(initial_condition)) previous_characteristics = zeros(ELTYPE, 3, nparticles(initial_condition)) - return (; characteristics=characteristics, - previous_characteristics=previous_characteristics, + return (; characteristics, previous_characteristics, pressure=copy(initial_condition.pressure), density=copy(initial_condition.density), cache...) @@ -178,16 +176,9 @@ function create_cache_open_boundary(boundary_model, fluid_system, initial_condit # as it was already verified in `allocate_buffer` that the density array is constant. density_rest = first(initial_condition.density) - if density_diffusion isa DensityDiffusionAntuono - density_diffusion_ = DensityDiffusionAntuono(initial_condition; - delta=density_diffusion.delta) - else - density_diffusion_ = density_diffusion - end - - cache = (; density_diffusion=density_diffusion_, - pressure_boundary=pressure_boundary, - density_rest=density_rest, cache...) + cache = (; density_diffusion, + create_cache_density_diffusion(initial_condition, density_diffusion)..., + pressure_boundary, density_rest, cache...) if fluid_system isa EntropicallyDampedSPHSystem # Density and pressure is stored in `v` @@ -660,7 +651,7 @@ function interpolate_velocity!(system::OpenBoundarySystem, boundary_zone, # We can do this because we require the neighborhood search to support querying neighbors # of arbitrary positions (see `PointNeighbors.requires_update` and `check_configuration`). foreach_point_neighbor(system, neighbor_system, sample_points, neighbor_coords, - semi, points=points) do point, neighbor, pos_diff, distance + semi; points) do point, neighbor, pos_diff, distance m_b = @inbounds hydrodynamic_mass(neighbor_system, neighbor) rho_b = @inbounds current_density(v_neighbor, neighbor_system, neighbor) volume_b = m_b / rho_b diff --git a/src/schemes/boundary/wall_boundary/dummy_particles.jl b/src/schemes/boundary/wall_boundary/dummy_particles.jl index 6b1ea25427..6453fc0c2a 100644 --- a/src/schemes/boundary/wall_boundary/dummy_particles.jl +++ b/src/schemes/boundary/wall_boundary/dummy_particles.jl @@ -3,6 +3,7 @@ density_calculator, smoothing_kernel, smoothing_length; viscosity=nothing, state_equation=nothing, correction=nothing, + clip_negative_pressure=false, reference_particle_spacing=0.0) Boundary model for [`WallBoundarySystem`](@ref). @@ -10,9 +11,9 @@ Boundary model for [`WallBoundarySystem`](@ref). # Arguments - `initial_density`: Vector holding the initial density of each boundary particle. - `hydrodynamic_mass`: Vector holding the "hydrodynamic mass" of each boundary particle. - See description above for more information. + See [the docs](@ref boundary_models) for more information. - `density_calculator`: Strategy to compute the hydrodynamic density of the boundary particles. - See description below for more information. + See [the docs](@ref boundary_models) for more information. - `smoothing_kernel`: Smoothing kernel should be the same as for the adjacent fluid system. - `smoothing_length`: Smoothing length should be the same as for the adjacent fluid system. @@ -22,6 +23,15 @@ Boundary model for [`WallBoundarySystem`](@ref). - `correction`: Correction method of the adjacent fluid system (see [Corrections](@ref corrections)). - `viscosity`: Slip (default) or no-slip condition. See description below for further information. +- `clip_negative_pressure=false`: Clip negative boundary pressures to avoid sticking + artifacts from attractive fluid-boundary forces at free + surfaces. Note that this is not a correct formulation + at interior boundaries (away from free surfaces). + Disable this option when simulating closed systems without + free surfaces to avoid artificially increased boundary + pressures that cause larger gaps between fluid and boundary + in areas of low pressure, against which the particle + shifting technique is fighting. - `reference_particle_spacing`: The reference particle spacing used for weighting values at the boundary, which currently is only needed when using surface tension. # Examples @@ -39,7 +49,7 @@ boundary_model = BoundaryModelDummyParticles(densities, masses, AdamiPressureExt BoundaryModelDummyParticles(AdamiPressureExtrapolation, ViscosityAdami) ``` """ -struct BoundaryModelDummyParticles{DC, ELTYPE <: Real, VECTOR, SE, K, V, COR, C} +struct BoundaryModelDummyParticles{DC, SE, CLIP, ELTYPE <: Real, VECTOR, K, V, COR, C} pressure :: VECTOR # Vector{ELTYPE} hydrodynamic_mass :: VECTOR # Vector{ELTYPE} state_equation :: SE @@ -49,14 +59,28 @@ struct BoundaryModelDummyParticles{DC, ELTYPE <: Real, VECTOR, SE, K, V, COR, C} viscosity :: V correction :: COR cache :: C + # Store this both as field and type parameter to avoid annoying hand-written + # `adapt_structure` functions. + clip_negative_pressure::Bool + + function BoundaryModelDummyParticles(pressure, hydrodynamic_mass, state_equation, + density_calculator, smoothing_kernel, + smoothing_length, viscosity, correction, + cache, clip_negative_pressure) + return new{typeof(density_calculator), typeof(state_equation), + clip_negative_pressure, eltype(pressure), typeof(pressure), + typeof(smoothing_kernel), typeof(viscosity), typeof(correction), + typeof(cache)}(pressure, hydrodynamic_mass, state_equation, + density_calculator, smoothing_kernel, smoothing_length, + viscosity, correction, cache, clip_negative_pressure) + end 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, state_equation=nothing, correction=nothing, + clip_negative_pressure=false, reference_particle_spacing=0.0) pressure = initial_boundary_pressure(initial_density, density_calculator, state_equation) @@ -72,9 +96,8 @@ function BoundaryModelDummyParticles(initial_density, hydrodynamic_mass, # If the `reference_density_spacing` is set calculate the `ideal_neighbor_count` if reference_particle_spacing > 0 # `reference_particle_spacing` has to be set for surface normals to be determined - cache = (; - cache..., # Existing cache fields - reference_particle_spacing=reference_particle_spacing, + # Existing cache fields + cache = (; cache..., reference_particle_spacing, initial_colorfield=zeros(ELTYPE, n_particles), colorfield=zeros(ELTYPE, n_particles), neighbor_count=zeros(ELTYPE, n_particles)) @@ -82,10 +105,17 @@ function BoundaryModelDummyParticles(initial_density, hydrodynamic_mass, return BoundaryModelDummyParticles(pressure, hydrodynamic_mass, state_equation, density_calculator, smoothing_kernel, - smoothing_length, viscosity, correction, cache) + smoothing_length, viscosity, correction, cache, + clip_negative_pressure) +end + +@inline function Base.ndims(boundary_model::BoundaryModelDummyParticles) + return ndims(boundary_model.smoothing_kernel) end -@inline Base.ndims(boundary_model::BoundaryModelDummyParticles) = ndims(boundary_model.smoothing_kernel) +@inline function clip_negative_pressure(::BoundaryModelDummyParticles{<:Any, <:Any, CLIP}) where {CLIP} + return CLIP +end @doc raw""" AdamiPressureExtrapolation(; pressure_offset=0, allow_loop_flipping=true) @@ -108,7 +138,6 @@ end loop is not thread parallelizable. This can cause error variations between simulations with different numbers of threads. - """ struct AdamiPressureExtrapolation{ELTYPE} pressure_offset :: ELTYPE @@ -424,33 +453,33 @@ end function compute_pressure!(boundary_model, ::Union{SummationDensity, ContinuityDensity}, system, v, u, v_ode, u_ode, semi) - - # Limit pressure to be non-negative to avoid attractive forces between fluid and - # boundary particles at free surfaces (sticking artifacts). @threaded semi for particle in eachparticle(system) - apply_state_equation!(boundary_model, current_density(v, system, particle), - particle) + @inbounds apply_state_equation!(boundary_model, + current_density(v, system, particle), particle) end return boundary_model end -# Use this function to avoid passing closures to Polyester.jl with `@batch` (`@threaded`). -# Otherwise, `@threaded` does not work here with Julia ARM on macOS. -# See https://github.com/JuliaSIMD/Polyester.jl/issues/88. -@inline function apply_state_equation!(boundary_model, density, particle) - boundary_model.pressure[particle] = max(boundary_model.state_equation(density), 0) +@propagate_inbounds function apply_state_equation!(boundary_model, density, particle) + pressure = boundary_model.state_equation(density) + + # This is determined statically and has therefore no overhead. + if clip_negative_pressure(boundary_model) + # Clip pressure to avoid sticking artifacts from negative pressures at free surfaces. + pressure = max(pressure, 0) + end + + boundary_model.pressure[particle] = pressure end @propagate_inbounds function apply_state_equation!(boundary_model::BoundaryModelDummyParticles{<:Any, - <:Any, - <:Any, Nothing}, density, particle) # Contact-only wall setups can reuse dummy particles for rigid contact without # configuring a hydrodynamic state equation. In that case, keep the auxiliary wall # pressure at zero because it is only meaningful for fluid-coupled updates. - boundary_model.pressure[particle] = zero(eltype(boundary_model.pressure)) + boundary_model.pressure[particle] = 0 end function compute_pressure!(boundary_model, @@ -519,9 +548,11 @@ function compute_adami_density!(boundary_model, system, v, particle) compute_wall_velocity!(viscosity, system, v, particle) end - # Limit pressure to be non-negative to avoid attractive forces between fluid and - # boundary particles at free surfaces (sticking artifacts). - @inbounds pressure[particle] = max(pressure[particle], 0) + # Clip pressure to avoid sticking artifacts from negative pressures at free surfaces. + # This is determined statically and has therefore no overhead. + if clip_negative_pressure(boundary_model) + @inbounds pressure[particle] = max(pressure[particle], 0) + end # Apply inverse state equation to compute density (not used with EDAC) inverse_state_equation!(density, state_equation, pressure, particle) diff --git a/src/schemes/fluid/entropically_damped_sph/system.jl b/src/schemes/fluid/entropically_damped_sph/system.jl index 413c0d6a3d..2b085d3ebb 100644 --- a/src/schemes/fluid/entropically_damped_sph/system.jl +++ b/src/schemes/fluid/entropically_damped_sph/system.jl @@ -1,6 +1,6 @@ @doc raw""" - EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, sound_speed; + EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, sound_speed, pressure_acceleration=inter_particle_averaged_pressure, density_calculator=SummationDensity(), shifting_technique=nothing, @@ -17,13 +17,13 @@ See [Entropically Damped Artificial Compressibility for SPH](@ref edac) for more # Arguments - `initial_condition`: Initial condition representing the system's particles. -- `sound_speed`: Speed of sound. -- `smoothing_kernel`: Smoothing kernel to be used for this system. - See [Smoothing Kernels](@ref smoothing_kernel). -- `smoothing_length`: Smoothing length to be used for this system. - See [Smoothing Kernels](@ref smoothing_kernel). # Keywords +- `sound_speed`: Speed of sound. +- `smoothing_kernel`: Smoothing kernel to be used for this system. + See [Smoothing Kernels](@ref smoothing_kernel). +- `smoothing_length`: Smoothing length to be used for this system. + See [Smoothing Kernels](@ref smoothing_kernel). - `viscosity`: Viscosity model for this system (default: no viscosity). Recommended: [`ViscosityAdami`](@ref). - `acceleration`: Acceleration vector for the system. (default: zero vector) @@ -85,10 +85,9 @@ 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 EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, sound_speed; +function EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, + sound_speed, density_calculator=SummationDensity(), pressure_acceleration=inter_particle_averaged_pressure, - density_calculator=SummationDensity(), shifting_technique=nothing, average_pressure_reduction=(!isnothing(shifting_technique)), alpha=0.5, viscosity=nothing, @@ -160,9 +159,8 @@ function EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, # If the `reference_density_spacing` is set calculate the `ideal_neighbor_count` if reference_particle_spacing > 0 # `reference_particle_spacing` has to be set for surface normals to be determined - cache = (; - cache..., # Existing cache fields - reference_particle_spacing=reference_particle_spacing) + # Existing cache fields + cache = (; cache..., reference_particle_spacing) end EntropicallyDampedSPHSystem{NDIMS, ELTYPE, typeof(initial_condition), typeof(mass), diff --git a/src/schemes/fluid/implicit_incompressible_sph/system.jl b/src/schemes/fluid/implicit_incompressible_sph/system.jl index 218dd96f87..6e54ce7b66 100644 --- a/src/schemes/fluid/implicit_incompressible_sph/system.jl +++ b/src/schemes/fluid/implicit_incompressible_sph/system.jl @@ -1,7 +1,6 @@ """ - ImplicitIncompressibleSPHSystem(initial_condition, - smoothing_kernel, smoothing_length, - reference_density; + ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, reference_density, viscosity=nothing, acceleration=ntuple(_ -> 0.0, ndims(smoothing_kernel)), omega=0.5, max_error=0.1, min_iterations=2, @@ -16,13 +15,13 @@ See [Implicit Incompressible SPH](@ref iisph) for more details on the method. # Arguments - `initial_condition`: [`InitialCondition`](@ref) representing the system's particles. -- `smoothing_kernel`: Smoothing kernel to be used for this system. - See [Smoothing Kernels](@ref smoothing_kernel). -- `smoothing_length`: Smoothing length to be used for this system. - See [Smoothing Kernels](@ref smoothing_kernel). -- `reference_density`: Reference density used for the fluid particles -# Keyword Arguments +# Keywords +- `smoothing_kernel`: Smoothing kernel to be used for this system. + See [Smoothing Kernels](@ref smoothing_kernel). +- `smoothing_length`: Smoothing length to be used for this system. + See [Smoothing Kernels](@ref smoothing_kernel). +- `reference_density`: Reference density used for the fluid particles. - `viscosity`: Currently, only [`ViscosityMorris`](@ref) and [`ViscosityAdami`](@ref) are supported. - `acceleration`: Acceleration vector for the system. (default: zero vector) @@ -65,9 +64,8 @@ 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 ImplicitIncompressibleSPHSystem(initial_condition, - smoothing_kernel, smoothing_length, - reference_density; +function ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, reference_density, viscosity=nothing, acceleration=ntuple(_ -> 0.0, ndims(smoothing_kernel)), diff --git a/src/schemes/fluid/pressure_acceleration.jl b/src/schemes/fluid/pressure_acceleration.jl index 79220ad696..b6114c0bc1 100644 --- a/src/schemes/fluid/pressure_acceleration.jl +++ b/src/schemes/fluid/pressure_acceleration.jl @@ -10,6 +10,7 @@ # Since this is one of the most performance critical functions, using fast divisions # here gives a significant speedup on GPUs. # See the docs page "Development" for more details on `div_fast`. + # -m_b * (p_a / ρ_a^2 + p_b / ρ_b^2) * ∇W_ab return -m_b * (div_fast(p_a, rho_a^2) + div_fast(p_b, rho_b^2)) * W_a end @@ -35,6 +36,7 @@ end # Since this is one of the most performance critical functions, using fast divisions # here gives a significant speedup on GPUs. # See the docs page "Development" for more details on `div_fast`. + # -m_b * (p_a + p_b) / (ρ_a * ρ_b) * ∇W_ab return -m_b * div_fast(p_a + p_b, rho_a * rho_b) * W_a end diff --git a/src/schemes/fluid/shifting_techniques.jl b/src/schemes/fluid/shifting_techniques.jl index 58753ea34c..e68b57d6c1 100644 --- a/src/schemes/fluid/shifting_techniques.jl +++ b/src/schemes/fluid/shifting_techniques.jl @@ -591,8 +591,10 @@ end delta_v_a = delta_v(system, particle) delta_v_b = delta_v(neighbor_system, neighbor) - A_a = rho_a * v_a * delta_v_a' - A_b = rho_b * v_b * delta_v_b' + # This is the same as using `transpose`, but it's faster due to + # https://github.com/JuliaLang/LinearAlgebra.jl/issues/1102. + A_a = rho_a * v_a * permutedims(delta_v_a) + A_b = rho_b * v_b * permutedims(delta_v_b) # The following term depends on the pressure acceleration formulation. # See the large comment below. In the original paper (Adami et al., 2013), this is diff --git a/src/schemes/fluid/weakly_compressible_sph/density_diffusion.jl b/src/schemes/fluid/weakly_compressible_sph/density_diffusion.jl index 4fabd5317a..10aee9d66c 100644 --- a/src/schemes/fluid/weakly_compressible_sph/density_diffusion.jl +++ b/src/schemes/fluid/weakly_compressible_sph/density_diffusion.jl @@ -88,7 +88,7 @@ end end @doc raw""" - DensityDiffusionAntuono(initial_condition; delta) + DensityDiffusionAntuono(; delta) The commonly used density diffusion terms by [Antuono (2010)](@cite Antuono2010), also referred to as δ-SPH. The density diffusion term by [Molteni (2009)](@cite Molteni2009) is extended by a second @@ -115,33 +115,31 @@ where ``d`` is the number of dimensions. See [`AbstractDensityDiffusion`](@ref TrixiParticles.AbstractDensityDiffusion) for an overview and comparison of implemented density diffusion terms. """ -struct DensityDiffusionAntuono{NDIMS, ELTYPE, ARRAY2D, ARRAY3D} <: AbstractDensityDiffusion - delta :: ELTYPE - correction_matrix :: ARRAY3D # Array{ELTYPE, 3}: [i, j, particle] - normalized_density_gradient :: ARRAY2D # Array{ELTYPE, 2}: [i, particle] - - function DensityDiffusionAntuono(delta, correction_matrix, normalized_density_gradient) - new{size(correction_matrix, 1), typeof(delta), - typeof(normalized_density_gradient), - typeof(correction_matrix)}(delta, correction_matrix, - normalized_density_gradient) +struct DensityDiffusionAntuono{ELTYPE} <: AbstractDensityDiffusion + delta::ELTYPE + + function DensityDiffusionAntuono(; delta) + new{typeof(delta)}(delta) end end -function DensityDiffusionAntuono(initial_condition; delta) +create_cache_density_diffusion(initial_condition, density_diffusion) = (;) + +function create_cache_density_diffusion(initial_condition, + ::DensityDiffusionAntuono) NDIMS = ndims(initial_condition) ELTYPE = eltype(initial_condition) - correction_matrix = Array{ELTYPE, 3}(undef, NDIMS, NDIMS, - nparticles(initial_condition)) + n_particles = nparticles(initial_condition) - normalized_density_gradient = Array{ELTYPE, 2}(undef, NDIMS, - nparticles(initial_condition)) + density_diffusion_correction_matrix = Array{ELTYPE, 3}(undef, NDIMS, NDIMS, + n_particles) + density_diffusion_normalized_density_gradient = Array{ELTYPE, 2}(undef, NDIMS, + n_particles) - return DensityDiffusionAntuono(delta, correction_matrix, normalized_density_gradient) + return (; density_diffusion_correction_matrix, + density_diffusion_normalized_density_gradient) end -@inline Base.ndims(::DensityDiffusionAntuono{NDIMS}) where {NDIMS} = NDIMS - function Base.show(io::IO, density_diffusion::DensityDiffusionAntuono) @nospecialize density_diffusion # reduce precompilation time @@ -154,22 +152,19 @@ function allocate_buffer(initial_condition, density_diffusion, buffer) return allocate_buffer(initial_condition, buffer), density_diffusion end -function allocate_buffer(ic, dd::DensityDiffusionAntuono, buffer::SystemBuffer) - initial_condition = allocate_buffer(ic, buffer) - return initial_condition, DensityDiffusionAntuono(initial_condition; delta=dd.delta) -end - @propagate_inbounds function density_diffusion_psi(density_diffusion::DensityDiffusionAntuono, rho_a, rho_b, pos_diff, distance, system, particle, neighbor) - (; normalized_density_gradient) = density_diffusion + (; density_diffusion_normalized_density_gradient) = system.cache # First term by Molteni & Colagrossi result = 2 * (rho_a - rho_b) # Second correction term - normalized_gradient_a = extract_svector(normalized_density_gradient, system, particle) - normalized_gradient_b = extract_svector(normalized_density_gradient, system, neighbor) + normalized_gradient_a = extract_svector(density_diffusion_normalized_density_gradient, + system, particle) + normalized_gradient_b = extract_svector(density_diffusion_normalized_density_gradient, + system, neighbor) result -= dot(normalized_gradient_a + normalized_gradient_b, pos_diff) # Since this is one of the most performance critical functions, using fast divisions @@ -179,13 +174,14 @@ end end function update!(density_diffusion::DensityDiffusionAntuono, v, u, system, semi) - (; normalized_density_gradient) = density_diffusion + density_diffusion_correction_matrix = system.cache.density_diffusion_correction_matrix + normalized_density_gradient = system.cache.density_diffusion_normalized_density_gradient # Compute correction matrix density_fun = @propagate_inbounds(particle->current_density(v, system, particle)) system_coords = current_coordinates(u, system) - compute_gradient_correction_matrix!(density_diffusion.correction_matrix, + compute_gradient_correction_matrix!(density_diffusion_correction_matrix, system, system_coords, density_fun, semi) # Compute normalized density gradient @@ -198,7 +194,8 @@ function update!(density_diffusion::DensityDiffusionAntuono, v, u, system, semi) rho_b = @inbounds current_density(v, system, neighbor) grad_kernel = smoothing_kernel_grad(system, pos_diff, distance, particle) - L = @inbounds correction_matrix(density_diffusion, particle) + L = @inbounds extract_smatrix(density_diffusion_correction_matrix, system, + particle) m_b = @inbounds hydrodynamic_mass(system, neighbor) volume_b = m_b / rho_b diff --git a/src/schemes/fluid/weakly_compressible_sph/state_equations.jl b/src/schemes/fluid/weakly_compressible_sph/state_equations.jl index b85a0d5e52..bfa7affd2b 100644 --- a/src/schemes/fluid/weakly_compressible_sph/state_equations.jl +++ b/src/schemes/fluid/weakly_compressible_sph/state_equations.jl @@ -25,7 +25,14 @@ The speed of sound is initialized as `min_sound_speed`. - `max_sound_speed=100.0f0`: The maximum permissible speed of sound. - `exponent`: An exponent, typically 7 for water simulations. - `background_pressure=0.0f0`: A constant background pressure. -- `clip_negative_pressure=false`: When true, negative pressure values are clipped to 0.0. This can prevent spurious surface tension effects but might allow for unphysical fluid rarefaction. +- `clip_negative_pressure=false`: When true, negative pressure values are clipped to 0.0. + This can prevent spurious surface tension effects but allows for unphysical fluid + rarefaction and causes incorrect fluid behavior in regions of low pressure. + Note that negative pressure values of boundary particles in the + [`BoundaryModelDummyParticles`](@ref) can lead to sticking artifacts at the boundary. + The `BoundaryModelDummyParticles` itself also provides an option to clip negative + pressure of boundary particles, which is a more targeted way to prevent sticking artifacts + without affecting the fluid behavior in the rest of the domain. """ struct StateEquationAdaptiveCole{ELTYPE, CLIP, SR} # Boolean to clip negative pressure sound_speed_ref :: SR diff --git a/src/schemes/fluid/weakly_compressible_sph/system.jl b/src/schemes/fluid/weakly_compressible_sph/system.jl index 108a075ae6..4b1caf351a 100644 --- a/src/schemes/fluid/weakly_compressible_sph/system.jl +++ b/src/schemes/fluid/weakly_compressible_sph/system.jl @@ -1,7 +1,6 @@ """ - WeaklyCompressibleSPHSystem(initial_condition, - density_calculator, state_equation, - smoothing_kernel, smoothing_length; + WeaklyCompressibleSPHSystem(initial_condition; density_calculator, state_equation, + smoothing_kernel, smoothing_length, acceleration=ntuple(_ -> 0.0, NDIMS), viscosity=nothing, density_diffusion=nothing, pressure_acceleration=nothing, @@ -18,15 +17,15 @@ See [Weakly Compressible SPH](@ref wcsph) for more details on the method. # Arguments - `initial_condition`: [`InitialCondition`](@ref) representing the system's particles. -- `density_calculator`: Density calculator for the system. - See [`ContinuityDensity`](@ref) and [`SummationDensity`](@ref). -- `state_equation`: Equation of state for the system. See [`StateEquationCole`](@ref). -- `smoothing_kernel`: Smoothing kernel to be used for this system. - See [Smoothing Kernels](@ref smoothing_kernel). -- `smoothing_length`: Smoothing length to be used for this system. - See [Smoothing Kernels](@ref smoothing_kernel). # Keywords +- `density_calculator`: Density calculator for the system. + See [`ContinuityDensity`](@ref) and [`SummationDensity`](@ref). +- `state_equation`: Equation of state for the system. See [`StateEquationCole`](@ref). +- `smoothing_kernel`: Smoothing kernel to be used for this system. + See [Smoothing Kernels](@ref smoothing_kernel). +- `smoothing_length`: Smoothing length to be used for this system. + See [Smoothing Kernels](@ref smoothing_kernel). - `acceleration`: Acceleration vector for the system. (default: zero vector) - `viscosity`: Viscosity model for this system (default: no viscosity). See [`ArtificialViscosityMonaghan`](@ref) or [`ViscosityAdami`](@ref). @@ -88,8 +87,9 @@ 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 WeaklyCompressibleSPHSystem(initial_condition, density_calculator, state_equation, - smoothing_kernel, smoothing_length; +function WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, density_calculator, + state_equation, acceleration=ntuple(_ -> zero(eltype(initial_condition)), ndims(smoothing_kernel)), viscosity=nothing, density_diffusion=nothing, @@ -152,6 +152,7 @@ function WeaklyCompressibleSPHSystem(initial_condition, density_calculator, stat n_particles)..., create_cache_refinement(initial_condition, particle_refinement, smoothing_length)..., + create_cache_density_diffusion(initial_condition, density_diffusion)..., create_cache_shifting(initial_condition, shifting_technique)..., # Per-system color tag for colorfield surface-normal logic and VTK output. color=Int(color_value)) @@ -159,9 +160,8 @@ function WeaklyCompressibleSPHSystem(initial_condition, density_calculator, stat # If the `reference_density_spacing` is set calculate the `ideal_neighbor_count` if reference_particle_spacing > 0 # `reference_particle_spacing` has to be set for surface normals to be determined - cache = (; - cache..., # Existing cache fields - reference_particle_spacing=reference_particle_spacing) + # Existing cache fields + cache = (; cache..., reference_particle_spacing) end return WeaklyCompressibleSPHSystem(initial_condition, mass, pressure, diff --git a/src/schemes/structure/discrete_element_method/system.jl b/src/schemes/structure/discrete_element_method/system.jl index ecdd5a29a5..2f6dbd2e18 100644 --- a/src/schemes/structure/discrete_element_method/system.jl +++ b/src/schemes/structure/discrete_element_method/system.jl @@ -1,6 +1,7 @@ """ - DEMSystem(initial_condition, contact_model; damping_coefficient=0.0001, - acceleration=ntuple(_ -> 0.0, ndims(initial_condition)), source_terms=nothing, + DEMSystem(initial_condition; contact_model, damping_coefficient=0.0001, + acceleration=ntuple(_ -> 0.0, ndims(initial_condition)), + source_terms=nothing, radius=nothing) Constructs a Discrete Element Method (DEM) system for numerically simulating the dynamics of @@ -13,12 +14,12 @@ specified material properties and contact mechanics. # Arguments - `initial_condition`: Initial condition of the system, encapsulating the initial positions, velocities, masses, and radii of particles. - - `contact_model`: Contact model used for particle interactions. # Keywords - - `acceleration`: Global acceleration vector applied to the system, such as gravity. Specified as + - `contact_model`: Contact model used for particle interactions. + - `acceleration`: Global acceleration vector applied to the system, such as gravity. Specified as an `SVector` of length `NDIMS`, with a default of zero in each dimension. - - `source_terms`: Optional; additional forces or modifications to particle dynamics not + - `source_terms`: Optional; additional forces or modifications to particle dynamics not captured by standard DEM interactions, such as electromagnetic forces or user-defined perturbations. - `damping_coefficient=0.0001`: Set a damping coefficient for the collision interactions. - `radius=nothing`: Specifies the radius of the particles, defaults to `initial_condition.particle_spacing / 2`. @@ -42,7 +43,7 @@ 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 DEMSystem(initial_condition, contact_model; damping_coefficient=0.0001, +function DEMSystem(initial_condition; contact_model, damping_coefficient=0.0001, acceleration=ntuple(_ -> 0.0, ndims(initial_condition)), source_terms=nothing, radius=nothing) diff --git a/src/schemes/structure/total_lagrangian_sph/system.jl b/src/schemes/structure/total_lagrangian_sph/system.jl index f5b1fd5d87..f12004401a 100644 --- a/src/schemes/structure/total_lagrangian_sph/system.jl +++ b/src/schemes/structure/total_lagrangian_sph/system.jl @@ -1,7 +1,6 @@ @doc raw""" - TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing_length, - young_modulus, poisson_ratio; - n_clamped_particles=0, + TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, smoothing_length, + young_modulus, poisson_ratio, clamped_particles=Int[], clamped_particles_motion=nothing, acceleration=ntuple(_ -> 0.0, NDIMS), @@ -18,21 +17,16 @@ See [Total Lagrangian SPH](@ref tlsph) for more details on the method. # Arguments - `initial_condition`: Initial condition representing the system's particles. -- `young_modulus`: Young's modulus. -- `poisson_ratio`: Poisson ratio. + +# Keywords - `smoothing_kernel`: Smoothing kernel to be used for this system. See [Smoothing Kernels](@ref smoothing_kernel). - `smoothing_length`: Smoothing length to be used for this system. See [Smoothing Kernels](@ref smoothing_kernel). - -# Keywords -- `n_clamped_particles` (deprecated): Number of clamped particles that are fixed and not integrated - to clamp the structure. Note that the clamped particles must be the **last** - particles in the `InitialCondition`. See the info box below. - This keyword is deprecated and will be removed in a future release. - Instead pass `clamped_particles` with the explicit particle indices to be clamped. -- `clamped_particles`: Indices specifying the clamped particles that are fixed - and not integrated to clamp the structure. +- `young_modulus`: Young's modulus. +- `poisson_ratio`: Poisson ratio. +- `clamped_particles`: Indices specifying the clamped particles that are fixed + and not integrated to clamp the structure. - `clamped_particles_motion`: Prescribed motion of the clamped particles. If `nothing` (default), the clamped particles are fixed. See [`PrescribedMotion`](@ref) for details. @@ -63,24 +57,17 @@ See [Total Lagrangian SPH](@ref tlsph) for more details on the method. Alternatively, a user-defined neighborhood search can be passed here. !!! note - If specifying the clamped particles manually (via `n_clamped_particles`), - the clamped particles must be the **last** particles in the `InitialCondition`. - To do so, e.g. use the `union` function: + To define `clamped_particles` conveniently, place the clamped block first and combine + initial conditions with `union`: ```jldoctest; output = false, setup = :(clamped_particles = RectangularShape(0.1, (1, 4), (0.0, 0.0), density=1.0); beam = RectangularShape(0.1, (3, 4), (0.1, 0.0), density=1.0)) - structure = union(beam, clamped_particles) + structure = union(clamped_particles, beam) + clamped_particle_indices = 1:nparticles(clamped_particles) # output - ┌──────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ InitialCondition │ - │ ════════════════ │ - │ #dimensions: ……………………………………………… 2 │ - │ #particles: ………………………………………………… 16 │ - │ particle spacing: ………………………………… 0.1 │ - │ eltype: …………………………………………………………… Float64 │ - │ coordinate eltype: ……………………………… Float64 │ - └──────────────────────────────────────────────────────────────────────────────────────────────────┘ + 1:4 ``` - where `beam` and `clamped_particles` are of type [`InitialCondition`](@ref). + Since `clamped_particles` is the first argument, these particles appear first in + `structure`, so their indices are `1:nparticles(clamped_particles)`. """ struct TotalLagrangianSPHSystem{BM, NDIMS, ELTYPE <: Real, IC, ARRAY1D, ARRAY2D, ARRAY3D, YM, PR, LL, LM, K, PF, V, ST, M, IM, NHS, @@ -112,10 +99,8 @@ struct TotalLagrangianSPHSystem{BM, NDIMS, ELTYPE <: Real, IC, ARRAY1D, ARRAY2D, cache :: C end -function TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing_length, - young_modulus, poisson_ratio; - n_clamped_particles=0, - clamped_particles=Int[], +function TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, smoothing_length, + young_modulus, poisson_ratio, clamped_particles=Int[], clamped_particles_motion=nothing, acceleration=ntuple(_ -> zero(eltype(initial_condition)), ndims(smoothing_kernel)), @@ -136,20 +121,6 @@ function TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing throw(ArgumentError("`acceleration` must be of length $NDIMS for a $(NDIMS)D problem")) end - # Backwards compatibility: `n_clamped_particles` is deprecated. - # Emit a deprecation warning and (if the user didn't supply explicit indices) - # convert the old `n_clamped_particles` convention to `clamped_particles`. - if n_clamped_particles != 0 - Base.depwarn("keyword `n_clamped_particles` is deprecated and will be removed in a future release; " * - "pass `clamped_particles` (Vector{Int} of indices) instead.", - :n_clamped_particles) - if isempty(clamped_particles) - clamped_particles = collect((n_particles - n_clamped_particles + 1):n_particles) - else - throw(ArgumentError("Either `n_clamped_particles` or `clamped_particles` can be specified, not both.")) - end - end - # Handle clamped particles if !isempty(clamped_particles) @assert allunique(clamped_particles) "`clamped_particles` contains duplicate particle indices" @@ -162,6 +133,7 @@ function TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing move_particles_to_end!(young_modulus_sorted, clamped_particles) move_particles_to_end!(poisson_ratio_sorted, clamped_particles) else + n_clamped_particles = 0 initial_condition_sorted = initial_condition young_modulus_sorted = young_modulus poisson_ratio_sorted = poisson_ratio diff --git a/src/setups/complex_shape.jl b/src/setups/complex_shape.jl index 55d3c996af..6a78b412e2 100644 --- a/src/setups/complex_shape.jl +++ b/src/setups/complex_shape.jl @@ -70,8 +70,7 @@ function ComplexShape(geometry; particle_spacing, density, # This is most likely only useful for debugging. Note that this is not public API. if store_winding_number - return (; initial_condition=initial_condition, winding_numbers=winding_numbers, - grid=grid) + return (; initial_condition, winding_numbers, grid) end return initial_condition diff --git a/src/setups/extrude_geometry.jl b/src/setups/extrude_geometry.jl index 3ff618205f..460583c38e 100644 --- a/src/setups/extrude_geometry.jl +++ b/src/setups/extrude_geometry.jl @@ -103,7 +103,7 @@ function extrude_geometry(geometry; particle_spacing=-1, direction, n_extrude::I geometry = shift_plane_corners(geometry, direction_, particle_spacing, place_on_shell) - face_coords = sample_plane(geometry, particle_spacing; place_on_shell=place_on_shell) + face_coords = sample_plane(geometry, particle_spacing; place_on_shell) coords = (face_coords .+ i * particle_spacing * direction_ for i in 0:(n_extrude - 1)) @@ -115,7 +115,7 @@ function extrude_geometry(geometry; particle_spacing=-1, direction, n_extrude::I end return InitialCondition(; coordinates, velocity, density, mass, pressure, - particle_spacing=particle_spacing) + particle_spacing) end # For corners/endpoints of a plane/line, sample the plane/line with particles. diff --git a/src/setups/rectangular_shape.jl b/src/setups/rectangular_shape.jl index ff7c9d9b26..c9043a35e6 100644 --- a/src/setups/rectangular_shape.jl +++ b/src/setups/rectangular_shape.jl @@ -59,8 +59,7 @@ rectangular = RectangularShape(particle_spacing, (5, 4), (1.0, 2.0), density=100 # 2D with hydrostatic pressure gradient. # `state_equation` has to be the same as for the WCSPH system. state_equation = StateEquationCole(sound_speed=20.0, exponent=7, reference_density=1000.0) -rectangular = RectangularShape(particle_spacing, (5, 4), (1.0, 2.0), - acceleration=(0.0, -9.81), state_equation=state_equation) +rectangular = RectangularShape(particle_spacing, (5, 4), (1.0, 2.0); acceleration=(0.0, -9.81), state_equation) # 3D rectangular = RectangularShape(particle_spacing, (5, 4, 7), (1.0, 2.0, 3.0), density=1000.0) @@ -102,9 +101,8 @@ function RectangularShape(particle_spacing, n_particles_per_dimension, min_coord # The type of the particle spacing determines the eltype of the coordinates coordinates = rectangular_shape_coords(convert(coordinates_eltype, particle_spacing), - n_particles_per_dimension, - min_coordinates, place_on_shell=place_on_shell, - loop_order=loop_order) + n_particles_per_dimension, min_coordinates; + place_on_shell, loop_order) if !isnothing(coordinates_perturbation) seed!(1) diff --git a/src/setups/rectangular_tank.jl b/src/setups/rectangular_tank.jl index 768f4723bd..2b59bbc8b0 100644 --- a/src/setups/rectangular_tank.jl +++ b/src/setups/rectangular_tank.jl @@ -70,8 +70,8 @@ setup = RectangularTank(particle_spacing, (water_width, water_height), # `state_equation` has to be the same as for the WCSPH system. state_equation = StateEquationCole(sound_speed=10.0, exponent=1, reference_density=1000.0) setup = RectangularTank(particle_spacing, (water_width, water_height), - (container_width, container_height), fluid_density, - acceleration=(0.0, -9.81), state_equation=state_equation) + (container_width, container_height), fluid_density; + acceleration=(0.0, -9.81), state_equation) # 3D setup = RectangularTank(particle_spacing, (water_width, water_height, water_depth), diff --git a/test/Project.toml b/test/Project.toml index 583f367bc9..1f0b9366b4 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -6,7 +6,8 @@ GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a" Glob = "c27321d9-0574-5035-807b-f59d2c89b15c" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +OrdinaryDiffEqLowStorageRK = "b0944070-b475-4768-8dec-fb6eb410534d" +OrdinaryDiffEqSymplecticRK = "fa646aed-7ef9-47eb-84c4-9443fc8cbfa8" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -22,7 +23,8 @@ DataFrames = "1.6" GLM = "1.9" Glob = "1.3" JSON = "1" -OrdinaryDiffEq = "6.49" +OrdinaryDiffEqLowStorageRK = "1" +OrdinaryDiffEqSymplecticRK = "1.10" Plots = "1" Polyester = "0.7" QuadGK = "2" diff --git a/test/callbacks/solution_saving.jl b/test/callbacks/solution_saving.jl index c82df25de2..8e32af8f06 100644 --- a/test/callbacks/solution_saving.jl +++ b/test/callbacks/solution_saving.jl @@ -1,6 +1,6 @@ @testset verbose=true "SolutionSavingCallback" begin @testset verbose=true "show" begin - out = joinpath(pkgdir(TrixiParticles), "out") + out = joinpath(tempdir(), "trixi_out") output_directory_padded = out * " "^(65 - length(out)) @testset verbose=true "dt" begin diff --git a/test/count_allocations.jl b/test/count_allocations.jl index 8303616e91..2fdc3e3721 100644 --- a/test/count_allocations.jl +++ b/test/count_allocations.jl @@ -22,8 +22,7 @@ end particle; search_radius=PointNeighbors.search_radius(neighborhood_search.nhs)) PointNeighbors.foreach_neighbor(f, system_coords, neighbor_coords, - neighborhood_search.nhs, particle, - search_radius=search_radius) + neighborhood_search.nhs, particle; search_radius) end # No update diff --git a/test/examples/dam_break_2d_corrections.jl b/test/examples/dam_break_2d_corrections.jl index 9c3e29fbe7..f31db69bfa 100644 --- a/test/examples/dam_break_2d_corrections.jl +++ b/test/examples/dam_break_2d_corrections.jl @@ -63,14 +63,13 @@ @testset "continuity_reinit" begin @trixi_test_nowarn trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", - "dam_break_2d.jl"), + "dam_break_2d.jl"); fluid_particle_spacing=particle_spacing, smoothing_length=1.5 * particle_spacing, boundary_density_calculator=ContinuityDensity(), fluid_density_calculator=ContinuityDensity(), correction=nothing, use_reinit=true, - prefix="continuity_reinit", tspan=tspan, - fluid_density=fluid_density, + prefix="continuity_reinit", tspan, fluid_density, density_diffusion=nothing) @test sol.retcode == ReturnCode.Success @@ -88,18 +87,16 @@ @trixi_test_nowarn trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", - "dam_break_2d.jl"), + "dam_break_2d.jl"); fluid_particle_spacing=particle_spacing, - smoothing_length=smoothing_length, + smoothing_length, boundary_density_calculator=SummationDensity(), - fluid_density_calculator=fluid_density_calculator, - correction=correction, use_reinit=false, + fluid_density_calculator, correction, + use_reinit=false, clip_negative_pressure=(fluid_density_calculator isa SummationDensity), - smoothing_kernel=smoothing_kernel, - prefix="$(correction_name)", tspan=tspan, - fluid_density=fluid_density, - density_diffusion=nothing, + smoothing_kernel, prefix="$(correction_name)", + tspan, fluid_density, density_diffusion=nothing, boundary_layers=5, sol=nothing) # Some correction methods require very small time steps at the beginning of the simulation. diff --git a/test/examples/examples.jl b/test/examples/examples.jl index ae5add731a..68e79c25cc 100644 --- a/test/examples/examples.jl +++ b/test/examples/examples.jl @@ -281,9 +281,6 @@ "hydrostatic_water_column_2d.jl"), tspan=(0.0, 0.1), n_particles_plate_y=3) [ r"\[ Info: To create the self-interaction neighborhood search.*\n", - r"┌ Warning: keyword `n_clamped_particles` is deprecated.*\n", - r"│ caller = ip:0x0\n", - r"└ @ Core :-1\n" ] @test sol.retcode == ReturnCode.Success if VERSION < v"1.12" @@ -334,9 +331,6 @@ tspan=(0.0, 0.1), n_particles_plate_y=3, use_edac=true) [ r"\[ Info: To create the self-interaction neighborhood search.*\n", - r"┌ Warning: keyword `n_clamped_particles` is deprecated.*\n", - r"│ caller = ip:0x0\n", - r"└ @ Core :-1\n" ] @test sol.retcode == ReturnCode.Success if VERSION < v"1.12" diff --git a/test/examples/examples_fluid.jl b/test/examples/examples_fluid.jl index 125f3bd38e..5fb60c3c31 100644 --- a/test/examples/examples_fluid.jl +++ b/test/examples/examples_fluid.jl @@ -39,19 +39,23 @@ viscosity_fluid=ViscosityMorris(nu=0.0015), fluid_density_calculator=SummationDensity(), clip_negative_pressure=true), - "WCSPH with smoothing_length=1.3" => (smoothing_length=1.3,), - "WCSPH with SchoenbergQuarticSplineKernel" => (smoothing_length=1.1, + "WCSPH with smoothing_length=1.3" => (smoothing_length=1.3 * + fluid_particle_spacing,), + "WCSPH with SchoenbergQuarticSplineKernel" => (smoothing_length=1.1 * + fluid_particle_spacing, smoothing_kernel=SchoenbergQuarticSplineKernel{2}()), - "WCSPH with SchoenbergQuinticSplineKernel" => (smoothing_length=1.1, + "WCSPH with SchoenbergQuinticSplineKernel" => (smoothing_length=1.1 * + fluid_particle_spacing, smoothing_kernel=SchoenbergQuinticSplineKernel{2}()), - "WCSPH with WendlandC2Kernel" => (smoothing_length=1.5, + "WCSPH with WendlandC2Kernel" => (smoothing_length=1.5 * fluid_particle_spacing, smoothing_kernel=WendlandC2Kernel{2}()), - "WCSPH with WendlandC4Kernel" => (smoothing_length=1.75, + "WCSPH with WendlandC4Kernel" => (smoothing_length=1.75 * + fluid_particle_spacing, smoothing_kernel=WendlandC4Kernel{2}()), - "WCSPH with WendlandC6Kernel" => (smoothing_length=2.0, + "WCSPH with WendlandC6Kernel" => (smoothing_length=2.0 * fluid_particle_spacing, smoothing_kernel=WendlandC6Kernel{2}()), "EDAC with source term damping" => (source_terms=SourceTermDamping(damping_coefficient=1e-4), - fluid_system=EntropicallyDampedSPHSystem(tank.fluid, + fluid_system=EntropicallyDampedSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, sound_speed, @@ -59,7 +63,7 @@ density_calculator=ContinuityDensity(), acceleration=(0.0, -gravity))), - "EDAC with SummationDensity" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid, + "EDAC with SummationDensity" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, sound_speed, @@ -67,7 +71,7 @@ density_calculator=SummationDensity(), acceleration=(0.0, -gravity)),), - "EDAC with ViscosityAdami" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid, + "EDAC with ViscosityAdami" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, sound_speed, @@ -75,7 +79,7 @@ density_calculator=ContinuityDensity(), acceleration=(0.0, -gravity)),), - "EDAC with ViscosityMorris" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid, + "EDAC with ViscosityMorris" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, sound_speed, @@ -426,6 +430,8 @@ @trixi_test_nowarn trixi_include(@__MODULE__, tspan=(0.0, 0.5), wcsph=false, joinpath(examples_dir(), "fluid", "pipe_flow_2d.jl"), + open_boundary_model=BoundaryModelMirroringTafuni(; + mirror_method=ZerothOrderMirroring()), boundary_type_in=BidirectionalFlow(), boundary_type_out=BidirectionalFlow()) @test sol.retcode == ReturnCode.Success @@ -433,9 +439,11 @@ end @trixi_testset "fluid/pipe_flow_2d.jl - BoundaryModelMirroringTafuni (WCSPH)" begin - @trixi_test_nowarn trixi_include(@__MODULE__, tspan=(0.0, 0.5), + @trixi_test_nowarn trixi_include(@__MODULE__, tspan=(0.0, 0.5), wcsph=true, joinpath(examples_dir(), "fluid", "pipe_flow_2d.jl"), + open_boundary_model=BoundaryModelMirroringTafuni(; + mirror_method=ZerothOrderMirroring()), boundary_type_in=BidirectionalFlow(), boundary_type_out=BidirectionalFlow()) @test sol.retcode == ReturnCode.Success @@ -590,16 +598,11 @@ println("═"^100) println("Running falling_water_spheres_2d.jl with $model_name") - # Prepare keyword arguments - kwargs = model_name == "SurfaceTensionNone" ? - (surface_tension=nothing,) : - (surface_tension=surface_tension,) - # Execute the example script with the current surface tension model @trixi_test_nowarn trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "falling_water_spheres_2d.jl"); - tspan=(0, 0.1), kwargs...) + tspan=(0, 0.1), surface_tension) # Assert that the simulation ran successfully @test sol.retcode == ReturnCode.Success @@ -623,18 +626,13 @@ println("═"^100) println("Running falling_water_spheres_3d.jl with $model_name") - # Prepare keyword arguments - kwargs = model_name == "SurfaceTensionNone" ? - (surface_tension=nothing,) : - (surface_tension=surface_tension,) - # Execute the example script with the current surface tension model @trixi_test_nowarn trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "falling_water_spheres_3d.jl"); tspan=(0, 0.05), fluid_particle_spacing=0.01, - kwargs...) [ + surface_tension) [ # Optional: Add regex patterns to ignore specific warnings or logs r"┌ Info: The desired tank length in x-direction .*\n", r"└ New tank length in x-direction.*\n", diff --git a/test/examples/gpu.jl b/test/examples/gpu.jl index 3117a67ca5..8f84611647 100644 --- a/test/examples/gpu.jl +++ b/test/examples/gpu.jl @@ -229,7 +229,7 @@ end coordinates_eltype=Float32, boundary_layers=1, spacing_ratio=3, - boundary_model=boundary_model, + boundary_model, parallelization_backend=Main.parallelization_backend) [ r"\[ Info: To move data to the GPU, `semidiscretize` creates a deep copy.*\n", r"┌ Info: The desired tank length in y-direction.*\n", @@ -267,12 +267,11 @@ end @trixi_test_nowarn trixi_include_changeprecision(Float32, @__MODULE__, joinpath(examples_dir(), "fluid", - "dam_break_3d.jl"), + "dam_break_3d.jl"); tspan=(0.0f0, 0.1f0), coordinates_eltype=Float32, fluid_particle_spacing=0.1, - semi=semi_fullgrid, - maxiters=maxiters) [ + semi=semi_fullgrid, maxiters) [ r"\[ Info: To move data to the GPU, `semidiscretize` creates a deep copy.*\n" ] @test sol.retcode == ReturnCode.Success @@ -308,10 +307,9 @@ end sol=nothing, ode=nothing) # Create tank with Float32 coordinates - tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, - tank_size, fluid_density, n_layers=boundary_layers, - acceleration=(0.0f0, -gravity), - state_equation=state_equation, + tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, + fluid_density; n_layers=boundary_layers, + acceleration=(0.0f0, -gravity), state_equation, coordinates_eltype=Float32) hydrostatic_water_column_tests = Dict( @@ -342,7 +340,7 @@ end "WCSPH with WendlandC6Kernel" => (smoothing_length=2.0, smoothing_kernel=WendlandC6Kernel{2}()), "EDAC with source term damping" => (source_terms=SourceTermDamping(damping_coefficient=1.0f-4), - fluid_system=EntropicallyDampedSPHSystem(tank.fluid, + fluid_system=EntropicallyDampedSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, sound_speed, @@ -350,7 +348,7 @@ end density_calculator=ContinuityDensity(), acceleration=(0.0, -gravity))), - "EDAC with SummationDensity" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid, + "EDAC with SummationDensity" => (fluid_system=EntropicallyDampedSPHSystem(tank.fluid; smoothing_kernel, smoothing_length, sound_speed, @@ -369,8 +367,7 @@ end trixi_include_changeprecision(Float32, @__MODULE__, joinpath(examples_dir(), "fluid", "hydrostatic_water_column_2d.jl"); - sol=nothing, ode=nothing, tank=tank, - kwargs...) + sol=nothing, ode=nothing, tank, kwargs...) # Neighborhood search with `FullGridCellList` for GPU compatibility min_corner = minimum(tank.boundary.coordinates, dims=2) @@ -388,7 +385,7 @@ end "fluid", "hydrostatic_water_column_2d.jl"); semi=semi_fullgrid, - tank=tank, + tank, tspan=(0.0f0, 0.1f0), kwargs...) [ r"\[ Info: To move data to the GPU, `semidiscretize` creates a deep copy.*\n", @@ -508,14 +505,12 @@ end joinpath(examples_dir(), "fluid", "pipe_flow_2d.jl"), + wcsph=false, coordinates_eltype=Float32, - open_boundary_model=BoundaryModelMirroringTafuni(), + open_boundary_model=BoundaryModelMirroringTafuni(; + mirror_method=ZerothOrderMirroring()), boundary_type_in=BidirectionalFlow(), boundary_type_out=BidirectionalFlow(), - reference_density_in=nothing, - reference_pressure_in=nothing, - reference_density_out=nothing, - reference_velocity_out=nothing, parallelization_backend=Main.parallelization_backend) [ r"\[ Info: To move data to the GPU, `semidiscretize` creates a deep copy.*\n" ] @@ -530,17 +525,12 @@ end joinpath(examples_dir(), "fluid", "pipe_flow_2d.jl"), - wcsph=true, sound_speed=20.0f0, + wcsph=true, coordinates_eltype=Float32, open_boundary_model=BoundaryModelMirroringTafuni(; mirror_method=ZerothOrderMirroring()), boundary_type_in=BidirectionalFlow(), boundary_type_out=BidirectionalFlow(), - reference_density_in=nothing, - reference_pressure_in=nothing, - reference_density_out=nothing, - reference_pressure_out=nothing, - reference_velocity_out=nothing, parallelization_backend=Main.parallelization_backend) [ r"\[ Info: To move data to the GPU, `semidiscretize` creates a deep copy.*\n" ] @@ -667,10 +657,10 @@ end @trixi_test_nowarn trixi_include_changeprecision(Float32, @__MODULE__, joinpath(examples_dir(), "dem", - "rectangular_tank_2d.jl"), + "rectangular_tank_2d.jl"); tspan=(0.0f0, 0.05f0), coordinates_eltype=Float32, - neighborhood_search=neighborhood_search, + neighborhood_search, parallelization_backend=Main.parallelization_backend) [ r"\[ Info: To move data to the GPU, `semidiscretize` creates a deep copy.*\n" ] diff --git a/test/general/custom_quantities.jl b/test/general/custom_quantities.jl index 54e976b395..33435c8fd1 100644 --- a/test/general/custom_quantities.jl +++ b/test/general/custom_quantities.jl @@ -12,8 +12,8 @@ smoothing_kernel = SchoenbergCubicSplineKernel{2}() smoothing_length = 1.2 * particle_spacing - fluid_system = EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, 1.0) + fluid_system = EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, sound_speed=1.0) fluid_system.cache.density .= initial_condition.density boundary_model = BoundaryModelDummyParticles(initial_condition.density, diff --git a/test/general/density_calculator.jl b/test/general/density_calculator.jl index 6bf895f7be..f6057f0598 100644 --- a/test/general/density_calculator.jl +++ b/test/general/density_calculator.jl @@ -13,10 +13,10 @@ exponent=7) viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) - fluid_system = WeaklyCompressibleSPHSystem(initial_condition, SummationDensity(), - state_equation, - smoothing_kernel, smoothing_length, - viscosity=viscosity) + fluid_system = WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation, viscosity) (; cache) = fluid_system (; density) = cache # Density is in the cache for SummationDensity diff --git a/test/general/initial_condition.jl b/test/general/initial_condition.jl index 2d16828274..0c2949adef 100644 --- a/test/general/initial_condition.jl +++ b/test/general/initial_condition.jl @@ -394,8 +394,7 @@ density = [10.0, 20.0, 30.0, 40.0, 50.0] pressure = [100.0, 200.0, 300.0, 400.0, 500.0] - ic = InitialCondition(coordinates=coordinates, velocity=velocity, - mass=mass, density=density, pressure=pressure) + ic = InitialCondition(; coordinates, velocity, mass, density, pressure) # Move particles 2 and 4 to the end particle_ids_to_move = [2, 4] @@ -423,8 +422,7 @@ mass = [1.1, 2.2, 3.3, 4.4] density = [10.0, 20.0, 30.0, 40.0] - ic = InitialCondition(coordinates=coordinates, velocity=velocity, - mass=mass, density=density) + ic = InitialCondition(; coordinates, velocity, mass, density) # Move particle 2 multiple times (should only move once) TrixiParticles.move_particles_to_end!(ic, [2, 2, 3]) diff --git a/test/general/interpolation.jl b/test/general/interpolation.jl index e620c8a7ac..7bffc86272 100644 --- a/test/general/interpolation.jl +++ b/test/general/interpolation.jl @@ -100,16 +100,16 @@ viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) - fluid_system = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, + fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity, acceleration=(0.0, -9.81)) boundary_model = BoundaryModelDummyParticles(bnd.density, bnd.mass, - state_equation=state_equation, - viscosity=viscosity, AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation, viscosity) boundary_system = WallBoundarySystem(bnd, boundary_model) @@ -141,8 +141,8 @@ semi_no_boundary, fluid_system, v_no_bnd, - u_no_bnd, - cut_off_bnd=cut_off_bnd) + u_no_bnd; + cut_off_bnd) # Top outside distance_top_outside = binary_search_outside(ny * particle_spacing, @@ -206,8 +206,8 @@ result_multipoint = TrixiParticles.interpolate_points(multi_point_coords, semi_no_boundary, fluid_system, - v_no_bnd, u_no_bnd, - cut_off_bnd=cut_off_bnd) + v_no_bnd, u_no_bnd; + cut_off_bnd) expected_multi = (density=[666.0, 666.0000000000001, 666.0], neighbor_count=[2, 6, 5], @@ -221,16 +221,14 @@ @testset verbose=true "Interpolation Line no boundary - cut_off_bnd = $(cut_off_bnd)" begin result_endpoint = TrixiParticles.interpolate_line([1.0, -0.05], [1.0, 1.0], 5, semi_no_boundary, - fluid_system, - v_no_bnd, u_no_bnd, - endpoint=true, - cut_off_bnd=cut_off_bnd) + fluid_system, v_no_bnd, + u_no_bnd; endpoint=true, + cut_off_bnd) - result = TrixiParticles.interpolate_line([1.0, -0.05], [1.0, 1.0], - 5, semi_no_boundary, - fluid_system, v_no_bnd, u_no_bnd, - endpoint=false, - cut_off_bnd=cut_off_bnd) + result = TrixiParticles.interpolate_line([1.0, -0.05], [1.0, 1.0], 5, + semi_no_boundary, fluid_system, + v_no_bnd, u_no_bnd; endpoint=false, + cut_off_bnd) expected_res = (density=[666.0, 666.0, 666.0], neighbor_count=[2, 2, 1], point_coords=[1.0 1.0 1.0; @@ -354,8 +352,8 @@ semi_boundary, fluid_system, v_bnd, - u_bnd, - cut_off_bnd=cut_off_bnd) + u_bnd; + cut_off_bnd) # Top outside distance_top_outside = binary_search_outside(ny * particle_spacing, @@ -440,9 +438,8 @@ result_multipoint = TrixiParticles.interpolate_points(multi_point_coords, semi_boundary, - fluid_system, - v_bnd, u_bnd, - cut_off_bnd=cut_off_bnd) + fluid_system, v_bnd, + u_bnd; cut_off_bnd) if cut_off_bnd expected_multi = (density=[666.0, 666.0000000000001, 666.0], neighbor_count=[4, 6, 5], @@ -474,16 +471,14 @@ @testset verbose=true "Interpolation Line boundary - cut_off_bnd = $(cut_off_bnd)" begin result_endpoint = TrixiParticles.interpolate_line([1.0, -0.05], [1.0, 1.0], 5, semi_boundary, - fluid_system, - v_bnd, u_bnd, - endpoint=true, - cut_off_bnd=cut_off_bnd) - - result = TrixiParticles.interpolate_line([1.0, -0.05], [1.0, 1.0], - 5, semi_no_boundary, - fluid_system, v_no_bnd, u_no_bnd, - endpoint=false, - cut_off_bnd=cut_off_bnd) + fluid_system, v_bnd, + u_bnd; endpoint=true, + cut_off_bnd) + + result = TrixiParticles.interpolate_line([1.0, -0.05], [1.0, 1.0], 5, + semi_no_boundary, fluid_system, + v_no_bnd, u_no_bnd; endpoint=false, + cut_off_bnd) if cut_off_bnd expected_res = (density=[666.0, 666.0, 666.0], neighbor_count=[2, 2, 1], point_coords=[1.0 1.0 1.0; @@ -618,10 +613,8 @@ const_pressure = [2 * new_wall_distance] const_velocity = [5; 0.1 * new_wall_distance^2+0.1; 0.0;;] - return (density=const_density, - neighbor_count=neighbor_count, - point_coords=[0.0; wall_distance; 0.0;;], - velocity=const_velocity, + return (; density=const_density, neighbor_count, + point_coords=[0.0; wall_distance; 0.0;;], velocity=const_velocity, pressure=const_pressure) end @@ -651,16 +644,16 @@ viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) - fluid_system = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity, + fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity, acceleration=(0.0, -9.81, 0.0)) boundary_model = BoundaryModelDummyParticles(bnd.density, bnd.mass, - state_equation=state_equation, - viscosity=viscosity, AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation, viscosity) boundary_system = WallBoundarySystem(bnd, boundary_model) @@ -688,14 +681,12 @@ for cut_off_bnd in [true, false] @testset verbose=true "Interpolation Point no boundary - cut_off_bnd = $(cut_off_bnd)" begin - interpolation_walldistance(y) = TrixiParticles.interpolate_points([0.0; - y; - 0.0;;], + interpolation_walldistance(y) = TrixiParticles.interpolate_points([0.0; y; 0.0;;], semi_no_boundary, fluid_system, v_no_bnd, - u_no_bnd, - cut_off_bnd=cut_off_bnd) + u_no_bnd; + cut_off_bnd) # Top outside distance_top_outside = binary_search_outside(ny * particle_spacing, @@ -763,8 +754,8 @@ result_multipoint = TrixiParticles.interpolate_points(multi_point_coords, semi_no_boundary, fluid_system, - v_no_bnd, u_no_bnd, - cut_off_bnd=cut_off_bnd) + v_no_bnd, u_no_bnd; + cut_off_bnd) expected_multi = (density=[666.0, 666.0, 666.0], neighbor_count=[4, 4, 9], point_coords=multi_point_coords, @@ -779,14 +770,12 @@ for cut_off_bnd in [true, false] @testset verbose=true "Interpolation Point boundary - cut_off_bnd = $(cut_off_bnd)" begin - interpolation_walldistance(y) = TrixiParticles.interpolate_points([0.0; - y; - 0.0;;], + interpolation_walldistance(y) = TrixiParticles.interpolate_points([0.0; y; 0.0;;], semi_boundary, fluid_system, v_no_bnd, - u_no_bnd, - cut_off_bnd=cut_off_bnd) + u_no_bnd; + cut_off_bnd) # Top outside distance_top_outside = binary_search_outside(ny * particle_spacing, @@ -871,8 +860,8 @@ result_multipoint = TrixiParticles.interpolate_points(multi_point_coords, semi_no_boundary, fluid_system, - v_no_bnd, u_no_bnd, - cut_off_bnd=cut_off_bnd) + v_no_bnd, u_no_bnd; + cut_off_bnd) expected_multi = (density=[666.0, 666.0, 666.0], neighbor_count=[4, 4, 9], point_coords=multi_point_coords, diff --git a/test/general/semidiscretization.jl b/test/general/semidiscretization.jl index 050581687c..12869fbe59 100644 --- a/test/general/semidiscretization.jl +++ b/test/general/semidiscretization.jl @@ -67,7 +67,11 @@ model_c = BoundaryModelMock(zeros(3)) # FSI without boundary model - structure_system1 = TotalLagrangianSPHSystem(ic, kernel, 1.0, 1.0, 1.0) + structure_system1 = TotalLagrangianSPHSystem(ic; + smoothing_kernel=kernel, + smoothing_length=1.0, + young_modulus=1.0, + poisson_ratio=1.0) error_str = "a boundary model for `TotalLagrangianSPHSystem` must be " * "specified when simulating a fluid-structure interaction." @@ -76,7 +80,11 @@ neighborhood_search=nothing) # FSI with boundary model - structure_system2 = TotalLagrangianSPHSystem(ic, kernel, 1.0, 1.0, 1.0, + structure_system2 = TotalLagrangianSPHSystem(ic; + smoothing_kernel=kernel, + smoothing_length=1.0, + young_modulus=1.0, + poisson_ratio=1.0, boundary_model=model_a) structure_system2 = TrixiParticles.initialize_self_interaction_nhs(structure_system2, nothing, @@ -87,7 +95,11 @@ nothing) # FSI with wrong boundary model - structure_system3 = TotalLagrangianSPHSystem(ic, kernel, 1.0, 1.0, 1.0, + structure_system3 = TotalLagrangianSPHSystem(ic; + smoothing_kernel=kernel, + smoothing_length=1.0, + young_modulus=1.0, + poisson_ratio=1.0, boundary_model=model_b) error_str = "`BoundaryModelDummyParticles` with density calculator " * @@ -97,7 +109,11 @@ neighborhood_search=nothing) # FSI with wrong boundary model - structure_system4 = TotalLagrangianSPHSystem(ic, kernel, 1.0, 1.0, 1.0, + structure_system4 = TotalLagrangianSPHSystem(ic; + smoothing_kernel=kernel, + smoothing_length=1.0, + young_modulus=1.0, + poisson_ratio=1.0, boundary_model=model_c) error_str = "the boundary model was initialized with 3 particles, " * @@ -115,8 +131,10 @@ boundary_model = BoundaryModelDummyParticles(ic.density, ic.mass, SummationDensity(), kernel, 1.0) boundary_system = WallBoundarySystem(ic, boundary_model) - fluid_system = WeaklyCompressibleSPHSystem(ic, SummationDensity(), nothing, - kernel, 1.0) + fluid_system = WeaklyCompressibleSPHSystem(ic; smoothing_kernel=kernel, + smoothing_length=1.0, + density_calculator=SummationDensity(), + state_equation=nothing) error_str = "`WeaklyCompressibleSPHSystem` cannot be used without setting a " * "`state_equation` for all boundary models" diff --git a/test/io/read_vtk.jl b/test/io/read_vtk.jl index adf779ce76..456a0bbc2c 100644 --- a/test/io/read_vtk.jl +++ b/test/io/read_vtk.jl @@ -3,22 +3,27 @@ coordinates = fill(1.0, 2, 12) velocity = fill(2.0, 2, 12) - expected_ic = InitialCondition(; coordinates=coordinates, velocity=velocity, - density=1000.0, pressure=900.0, mass=50.0) + expected_data = InitialCondition(; coordinates, velocity, density=1000.0, + pressure=900.0, particle_spacing=0.1) + + expected_scalar = 3.0 + expected_vector = fill(expected_scalar, nparticles(expected_data)) + scalar_function(system, data, t) = expected_scalar + vector_function(system, data, t) = fill(expected_scalar, nparticles(system)) @testset verbose=true "`InitialCondition`" begin @testset verbose=true "`Float64`" begin - trixi2vtk(expected_ic; filename="tmp_initial_condition_64", + trixi2vtk(expected_data; filename="tmp_initial_condition_64", output_directory=tmp_dir) file = joinpath(tmp_dir, "tmp_initial_condition_64.vtu") - test_ic = vtk2trixi(file) + data = vtk2trixi(file) - @test isapprox(expected_ic.coordinates, test_ic.coordinates, rtol=1e-5) - @test isapprox(expected_ic.velocity, test_ic.velocity, rtol=1e-5) - @test isapprox(expected_ic.density, test_ic.density, rtol=1e-5) - @test isapprox(expected_ic.pressure, test_ic.pressure, rtol=1e-5) - @test eltype(test_ic) === Float64 - @test eltype(test_ic.coordinates) === Float64 + @test isapprox(expected_data.coordinates, data.coordinates, rtol=1e-5) + @test isapprox(expected_data.velocity, data.velocity, rtol=1e-5) + @test isapprox(expected_data.density, data.density, rtol=1e-5) + @test isapprox(expected_data.pressure, data.pressure, rtol=1e-5) + @test all(key -> eltype(data[key]) === Float64, keys(data)) + @test eltype(data.coordinates) === Float64 end @testset verbose=true "`Float32`" begin @@ -31,128 +36,199 @@ trixi2vtk(expected_ic_32; filename="tmp_initial_condition_32", output_directory=tmp_dir) file = joinpath(tmp_dir, "tmp_initial_condition_32.vtu") - test_ic = vtk2trixi(file) + data = vtk2trixi(file) - @test isapprox(expected_ic_32.coordinates, test_ic.coordinates, rtol=1e-5) - @test isapprox(expected_ic_32.velocity, test_ic.velocity, rtol=1e-5) - @test isapprox(expected_ic_32.density, test_ic.density, rtol=1e-5) - @test isapprox(expected_ic_32.pressure, test_ic.pressure, rtol=1e-5) - @test eltype(test_ic) === Float32 - @test eltype(test_ic.coordinates) === Float32 + @test isapprox(expected_ic_32.coordinates, data.coordinates, rtol=1e-5) + @test isapprox(expected_ic_32.velocity, data.velocity, rtol=1e-5) + @test isapprox(expected_ic_32.density, data.density, rtol=1e-5) + @test isapprox(expected_ic_32.pressure, data.pressure, rtol=1e-5) + @test all(key -> eltype(data[key]) === Float32, keys(data)) + @test eltype(data.coordinates) === Float32 end @testset verbose=true "Custom Element Type" begin - trixi2vtk(expected_ic; filename="tmp_initial_condition_custom", + trixi2vtk(expected_data; filename="tmp_initial_condition_64", output_directory=tmp_dir) - file = joinpath(tmp_dir, "tmp_initial_condition_custom.vtu") - test_ic = vtk2trixi(file, element_type=Float32, coordinates_eltype=Float32) - - @test isapprox(expected_ic.coordinates, test_ic.coordinates, rtol=1e-5) - @test isapprox(expected_ic.velocity, test_ic.velocity, rtol=1e-5) - @test isapprox(expected_ic.density, test_ic.density, rtol=1e-5) - @test isapprox(expected_ic.pressure, test_ic.pressure, rtol=1e-5) - @test eltype(test_ic) === Float32 - @test eltype(test_ic.coordinates) === Float32 + file = joinpath(tmp_dir, "tmp_initial_condition_64.vtu") + data = vtk2trixi(file, element_type=Float32, coordinates_eltype=Float32) + + @test isapprox(expected_data.coordinates, data.coordinates, rtol=1e-5) + @test isapprox(expected_data.velocity, data.velocity, rtol=1e-5) + @test isapprox(expected_data.density, data.density, rtol=1e-5) + @test isapprox(expected_data.pressure, data.pressure, rtol=1e-5) + @test all(key -> eltype(data[key]) === Float32, keys(data)) + @test eltype(data.coordinates) === Float32 + end + + @testset verbose=true "Scalar Custom Quantity" begin + trixi2vtk(expected_data; filename="tmp_initial_condition_scalar", + output_directory=tmp_dir, scalar=expected_scalar) + + # Load file containing test data + test_data = vtk2trixi(joinpath(tmp_dir, "tmp_initial_condition_scalar.vtu")) + + @test isapprox(expected_data.coordinates, test_data.coordinates, rtol=1e-5) + @test isapprox(expected_data.velocity, test_data.velocity, rtol=1e-5) + @test isapprox(expected_data.density, test_data.density, rtol=1e-5) + @test isapprox(expected_data.pressure, test_data.pressure, rtol=1e-5) + @test isapprox(expected_scalar, test_data.scalar, rtol=1e-5) + end + + @testset verbose=true "Vector Custom Quantity" begin + trixi2vtk(expected_data; filename="tmp_initial_condition_vector", + output_directory=tmp_dir, + vector=expected_vector) + + # Load file containing test data + test_data = vtk2trixi(joinpath(tmp_dir, "tmp_initial_condition_vector.vtu")) + + @test isapprox(expected_data.coordinates, test_data.coordinates, rtol=1e-5) + @test isapprox(expected_data.velocity, test_data.velocity, rtol=1e-5) + @test isapprox(expected_data.density, test_data.density, rtol=1e-5) + @test isapprox(expected_data.pressure, test_data.pressure, rtol=1e-5) + @test isapprox(expected_vector, test_data.vector, rtol=1e-5) end - @testset verbose=true "Mixed Types" begin - expected_ic_mixed = InitialCondition(; - coordinates=coordinates, - velocity=convert.(Float32, velocity), - density=1000.0f0, pressure=900.0f0, - mass=50.0f0, particle_spacing=0.1f0) - trixi2vtk(expected_ic_mixed; filename="tmp_initial_condition_mixed", + @testset verbose=true "Custom Element Type Mixed" begin + trixi2vtk(expected_data; filename="tmp_initial_condition_64", output_directory=tmp_dir) - file = joinpath(tmp_dir, "tmp_initial_condition_mixed.vtu") - test_ic = vtk2trixi(file) + file = joinpath(tmp_dir, "tmp_initial_condition_64.vtu") + data = vtk2trixi(file, element_type=Float32, coordinates_eltype=Float64) - @test isapprox(expected_ic.coordinates, test_ic.coordinates, rtol=1e-5) - @test isapprox(expected_ic.velocity, test_ic.velocity, rtol=1e-5) - @test isapprox(expected_ic.density, test_ic.density, rtol=1e-5) - @test isapprox(expected_ic.pressure, test_ic.pressure, rtol=1e-5) - @test eltype(test_ic) === Float32 - @test eltype(test_ic.coordinates) === Float64 + @test isapprox(expected_data.coordinates, data.coordinates, rtol=1e-5) + @test isapprox(expected_data.velocity, data.velocity, rtol=1e-5) + @test isapprox(expected_data.density, data.density, rtol=1e-5) + @test isapprox(expected_data.pressure, data.pressure, rtol=1e-5) + @test all(key -> eltype(data[key]) === Float32, + setdiff(keys(data), (:coordinates,))) + @test eltype(data.coordinates) === Float64 end @testset verbose=true "Exact Field Matches" begin - trixi2vtk(expected_ic; filename="tmp_initial_condition_exact_field_match", + trixi2vtk(expected_data; filename="tmp_initial_condition_exact_field_match", output_directory=tmp_dir, - center_of_mass_velocity=fill(42.0, size(expected_ic.velocity))) + center_of_mass_velocity=fill(42.0, size(expected_data.velocity))) file = joinpath(tmp_dir, "tmp_initial_condition_exact_field_match.vtu") test_ic = vtk2trixi(file) - @test isapprox(expected_ic.velocity, test_ic.velocity, rtol=1e-5) + @test isapprox(expected_data.velocity, test_ic.velocity, rtol=1e-5) end end @testset verbose=true "`AbstractFluidSystem`" begin - fluid_system = EntropicallyDampedSPHSystem(expected_ic, - SchoenbergCubicSplineKernel{2}(), - 1.5, 1.5) + fluid_system = EntropicallyDampedSPHSystem(expected_data; + smoothing_kernel=SchoenbergCubicSplineKernel{2}(), + smoothing_length=1.5, + sound_speed=1.5) # Overwrite values because we skip the update step - fluid_system.cache.density .= expected_ic.density + fluid_system.cache.density .= expected_data.density semi = Semidiscretization(fluid_system) # Create random ODE solutions - dvdu_ode = nothing v = fill(2.0, ndims(fluid_system), nparticles(fluid_system)) pressure = fill(3.0, nparticles(fluid_system)) v_ode = vec([v; pressure']) u = fill(1.0, ndims(fluid_system), nparticles(fluid_system)) u_ode = vec(u) + dv_ode = zero(v_ode) + du_ode = zero(u_ode) x = (; v_ode, u_ode) vu_ode = (; x) + dvdu_ode = (; x=(; v_ode=dv_ode, u_ode=du_ode)) - # Write out `AbstractFluidSystem` Simulation-File - trixi2vtk(fluid_system, dvdu_ode, vu_ode, semi, 0.0, - nothing; system_name="tmp_file_fluid", output_directory=tmp_dir, - iter=1) + @testset verbose=true "Scalar Custom Quantity" begin + trixi2vtk(fluid_system, dvdu_ode, vu_ode, semi, 0.0, + nothing; system_name="tmp_file_fluid_scalar", + output_directory=tmp_dir, iter=1, scalar=scalar_function) + + # Load file containing test data + test_data = vtk2trixi(joinpath(tmp_dir, "tmp_file_fluid_scalar_1.vtu")) + + @test isapprox(u, test_data.coordinates, rtol=1e-5) + @test isapprox(v, test_data.velocity, rtol=1e-5) + @test isapprox(pressure, test_data.pressure, rtol=1e-5) + @test isapprox(fluid_system.cache.density, test_data.density, rtol=1e-5) + @test isapprox(expected_scalar, test_data.scalar, rtol=1e-5) + end + + @testset verbose=true "Vector Custom Quantity" begin + trixi2vtk(fluid_system, dvdu_ode, vu_ode, semi, 0.0, + nothing; system_name="tmp_file_fluid_vector", + output_directory=tmp_dir, iter=1, vector=vector_function) - # Load `AbstractFluidSystem` Simulation-File - test = vtk2trixi(joinpath(tmp_dir, "tmp_file_fluid_1.vtu")) + # Load file containing test data + test_data = vtk2trixi(joinpath(tmp_dir, "tmp_file_fluid_vector_1.vtu")) - @test isapprox(u, test.coordinates, rtol=1e-5) - @test isapprox(v, test.velocity, rtol=1e-5) - @test isapprox(pressure, test.pressure, rtol=1e-5) - @test isapprox(fluid_system.cache.density, test.density, rtol=1e-5) + @test isapprox(u, test_data.coordinates, rtol=1e-5) + @test isapprox(v, test_data.velocity, rtol=1e-5) + @test isapprox(pressure, test_data.pressure, rtol=1e-5) + @test isapprox(fluid_system.cache.density, test_data.density, rtol=1e-5) + @test isapprox(fill(expected_scalar, nparticles(fluid_system)), + test_data.vector, rtol=1e-5) + end end @testset verbose=true "`WallBoundarySystem`" begin - boundary_model = BoundaryModelDummyParticles(expected_ic.density, - expected_ic.mass, + boundary_model = BoundaryModelDummyParticles(expected_data.density, + expected_data.mass, SummationDensity(), SchoenbergCubicSplineKernel{2}(), 1.5) # Overwrite values because we skip the update step - boundary_model.pressure .= expected_ic.pressure - boundary_model.cache.density .= expected_ic.density + boundary_model.pressure .= expected_data.pressure + boundary_model.cache.density .= expected_data.density - boundary_system = WallBoundarySystem(expected_ic, boundary_model) + boundary_system = WallBoundarySystem(expected_data, boundary_model) semi = Semidiscretization(boundary_system) # Create dummy ODE solutions - dvdu_ode = nothing v_ode = zeros(ndims(boundary_system) * nparticles(boundary_system)) u_ode = zeros(ndims(boundary_system) * nparticles(boundary_system)) + dv_ode = zero(v_ode) + du_ode = zero(u_ode) x = (; v_ode, u_ode) vu_ode = (; x) + dvdu_ode = (; x=(; v_ode=dv_ode, u_ode=du_ode)) - # Write out `WallBoundarySystem` Simulation-File - trixi2vtk(boundary_system, dvdu_ode, vu_ode, semi, 0.0, - nothing; system_name="tmp_file_boundary", output_directory=tmp_dir, - iter=1) + @testset verbose=true "Scalar Custom Quantity" begin + trixi2vtk(boundary_system, dvdu_ode, vu_ode, semi, 0.0, + nothing; system_name="tmp_file_boundary_scalar", + output_directory=tmp_dir, iter=1, scalar=scalar_function) - # Load `WallBoundarySystem` Simulation-File - test = vtk2trixi(joinpath(tmp_dir, "tmp_file_boundary_1.vtu")) + # Load file containing test data + test_data = vtk2trixi(joinpath(tmp_dir, "tmp_file_boundary_scalar_1.vtu")) + + @test isapprox(boundary_system.coordinates, test_data.coordinates, + rtol=1e-5) + # The velocity is always zero for `WallBoundarySystem` + @test isapprox(zeros(size(test_data.velocity)), test_data.velocity, + rtol=1e-5) + @test isapprox(boundary_model.pressure, test_data.pressure, rtol=1e-5) + @test isapprox(boundary_model.cache.density, test_data.density, rtol=1e-5) + @test isapprox(expected_scalar, test_data.scalar, rtol=1e-5) + end - @test isapprox(boundary_system.coordinates, test.coordinates, rtol=1e-5) - # The velocity is always zero for `WallBoundarySystem` - @test isapprox(zeros(size(test.velocity)), test.velocity, rtol=1e-5) - @test isapprox(boundary_model.pressure, test.pressure, rtol=1e-5) - @test isapprox(boundary_model.cache.density, test.density, rtol=1e-5) + @testset verbose=true "Vector Custom Quantity" begin + trixi2vtk(boundary_system, dvdu_ode, vu_ode, semi, 0.0, + nothing; system_name="tmp_file_boundary_vector", + output_directory=tmp_dir, iter=1, vector=vector_function) + + # Load file containing test data + test_data = vtk2trixi(joinpath(tmp_dir, "tmp_file_boundary_vector_1.vtu")) + + @test isapprox(boundary_system.coordinates, test_data.coordinates, + rtol=1e-5) + # The velocity is always zero for `WallBoundarySystem` + @test isapprox(zeros(size(test_data.velocity)), test_data.velocity, + rtol=1e-5) + @test isapprox(boundary_model.pressure, test_data.pressure, rtol=1e-5) + @test isapprox(boundary_model.cache.density, test_data.density, rtol=1e-5) + @test isapprox(fill(expected_scalar, nparticles(boundary_system)), + test_data.vector, rtol=1e-5) + end end @testset verbose=true "`RigidBodySystem`" begin diff --git a/test/rectangular_patch.jl b/test/rectangular_patch.jl index 42e3ef2e9a..179c453496 100644 --- a/test/rectangular_patch.jl +++ b/test/rectangular_patch.jl @@ -7,8 +7,7 @@ function rectangular_patch(particle_spacing, size; density=1000.0, pressure=0.0, # 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) + ic = RectangularShape(particle_spacing, size, min_corner; density, pressure) perturb!(ic.coordinates, perturbation_factor_position * 0.5 * particle_spacing) diff --git a/test/schemes/boundary/dummy_particles/dummy_particles.jl b/test/schemes/boundary/dummy_particles/dummy_particles.jl index 239f992e67..d6c1bde157 100644 --- a/test/schemes/boundary/dummy_particles/dummy_particles.jl +++ b/test/schemes/boundary/dummy_particles/dummy_particles.jl @@ -10,6 +10,63 @@ @test repr(boundary_model) == expected_repr end + @testset "Pressure clipping" begin + state_equation = StateEquationCole(sound_speed=10.0, + reference_density=1000.0, + exponent=7, + clip_negative_pressure=false) + smoothing_kernel = SchoenbergCubicSplineKernel{2}() + smoothing_length = 0.1 + + boundary_model_clip = BoundaryModelDummyParticles([1000.0], [1.0], + SummationDensity(), + smoothing_kernel, + smoothing_length, + state_equation=state_equation, + clip_negative_pressure=true) + boundary_model_no_clip = BoundaryModelDummyParticles([1000.0], [1.0], + SummationDensity(), + smoothing_kernel, + smoothing_length, + state_equation=state_equation) + + @test TrixiParticles.clip_negative_pressure(boundary_model_clip) + @test !TrixiParticles.clip_negative_pressure(boundary_model_no_clip) + + TrixiParticles.apply_state_equation!(boundary_model_clip, 900.0, 1) + TrixiParticles.apply_state_equation!(boundary_model_no_clip, 900.0, 1) + + @test boundary_model_clip.pressure[1] == 0 + @test boundary_model_no_clip.pressure[1] < 0 + + # Test that clipping behavior is preserved through `adapt_structure`. + adapted_model_clip = TrixiParticles.Adapt.adapt(Array, boundary_model_clip) + adapted_model_no_clip = TrixiParticles.Adapt.adapt(Array, boundary_model_no_clip) + @test TrixiParticles.clip_negative_pressure(adapted_model_clip) + @test !TrixiParticles.clip_negative_pressure(adapted_model_no_clip) + + boundary_model_adami_clip = BoundaryModelDummyParticles([1000.0], [1.0], + AdamiPressureExtrapolation(), + smoothing_kernel, + smoothing_length, + state_equation=state_equation, + clip_negative_pressure=true) + boundary_model_adami_no_clip = BoundaryModelDummyParticles([1000.0], [1.0], + AdamiPressureExtrapolation(), + smoothing_kernel, + smoothing_length, + state_equation=state_equation) + + for model in (boundary_model_adami_clip, boundary_model_adami_no_clip) + model.cache.volume[1] = 1 + model.pressure[1] = -1 + TrixiParticles.compute_adami_density!(model, nothing, nothing, 1) + end + + @test boundary_model_adami_clip.pressure[1] == 0 + @test boundary_model_adami_no_clip.pressure[1] == -1 + end + @testset verbose=true "Viscosity Adami/Bernoulli: Wall Velocity" begin particle_spacing = 0.1 @@ -50,44 +107,40 @@ exponent=7) # Define pressure extrapolation methods to test - boundary_model_adami = BoundaryModelDummyParticles(boundary.density, - boundary.mass, - state_equation=state_equation, + boundary_model_adami = BoundaryModelDummyParticles(boundary.density, boundary.mass, AdamiPressureExtrapolation(), smoothing_kernel, - smoothing_length, - viscosity=viscosity) + smoothing_length; state_equation, + viscosity) boundary_model_bernoulli = BoundaryModelDummyParticles(boundary.density, boundary.mass, - state_equation=state_equation, BernoulliPressureExtrapolation(), smoothing_kernel, - smoothing_length, - viscosity=viscosity) + smoothing_length; + state_equation, viscosity) boundary_systems = [ WallBoundarySystem(boundary, boundary_model_adami), WallBoundarySystem(boundary, boundary_model_bernoulli), - RigidBodySystem(boundary; - boundary_model=boundary_model_adami, - particle_spacing=particle_spacing), - RigidBodySystem(boundary; - boundary_model=boundary_model_bernoulli, - particle_spacing=particle_spacing), - TotalLagrangianSPHSystem(boundary, smoothing_kernel, - smoothing_length, 1e6, 0.3; + RigidBodySystem(boundary; boundary_model=boundary_model_adami, + particle_spacing), + RigidBodySystem(boundary; boundary_model=boundary_model_bernoulli, + particle_spacing), + TotalLagrangianSPHSystem(boundary; smoothing_kernel, + smoothing_length, young_modulus=1e6, + poisson_ratio=0.3, boundary_model=boundary_model_adami), - TotalLagrangianSPHSystem(boundary, smoothing_kernel, - smoothing_length, 1e6, 0.3; + TotalLagrangianSPHSystem(boundary; smoothing_kernel, + smoothing_length, young_modulus=1e6, + poisson_ratio=0.3, boundary_model=boundary_model_bernoulli) ] # Create fluid system - fluid_system = WeaklyCompressibleSPHSystem(fluid, - SummationDensity(), - state_equation, - smoothing_kernel, - smoothing_length) + fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) velocities = [ [0.0; -1.0], @@ -230,15 +283,14 @@ state_equation = StateEquationCole(sound_speed=10, reference_density=257, exponent=7) - tank1 = RectangularTank(particle_spacing, (width, height), (width, height), - density, n_layers=n_layers, - faces=(true, true, true, false)) + tank1 = RectangularTank(particle_spacing, (width, height), (width, height), density; + n_layers, faces=(true, true, true, false)) boundary_model = BoundaryModelDummyParticles(tank1.boundary.density, tank1.boundary.mass, - state_equation=state_equation, AdamiPressureExtrapolation(), - smoothing_kernel, smoothing_length) + smoothing_kernel, smoothing_length; + state_equation) boundary_system = WallBoundarySystem(tank1.boundary, boundary_model) viscosity = boundary_system.boundary_model.viscosity @@ -249,9 +301,10 @@ # Use constant density equal to the reference density of the state equation, # so that the pressure is constant zero. Then we test that the extrapolation also yields zero. @testset "Constant Zero Pressure" begin - fluid_system1 = WeaklyCompressibleSPHSystem(tank1.fluid, SummationDensity(), - state_equation, - smoothing_kernel, smoothing_length) + fluid_system1 = WeaklyCompressibleSPHSystem(tank1.fluid; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) fluid_system1.cache.density .= tank1.fluid.density v_fluid = zeros(2, TrixiParticles.nparticles(fluid_system1)) @@ -285,12 +338,12 @@ @testset "Constant Non-Zero Pressure" begin density = 260 tank2 = RectangularTank(particle_spacing, (width, height), (width, height), - density, n_layers=n_layers, - faces=(true, true, true, false)) + density; n_layers, faces=(true, true, true, false)) - fluid_system2 = WeaklyCompressibleSPHSystem(tank2.fluid, SummationDensity(), - state_equation, - smoothing_kernel, smoothing_length) + fluid_system2 = WeaklyCompressibleSPHSystem(tank2.fluid; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) fluid_system2.cache.density .= tank2.fluid.density v_fluid = zeros(2, TrixiParticles.nparticles(fluid_system2)) @@ -326,14 +379,14 @@ @testset "Hydrostatic Pressure Gradient" begin for flipped_condition in (Val(true), Val(false)) tank3 = RectangularTank(particle_spacing, (width, height), (width, height), - density, acceleration=[0.0, -9.81], - state_equation=state_equation, n_layers=n_layers, - faces=(true, true, true, false)) + density; acceleration=[0.0, -9.81], state_equation, + n_layers, faces=(true, true, true, false)) - fluid_system3 = WeaklyCompressibleSPHSystem(tank3.fluid, SummationDensity(), - state_equation, + fluid_system3 = WeaklyCompressibleSPHSystem(tank3.fluid; smoothing_kernel, smoothing_length, + density_calculator=SummationDensity(), + state_equation, acceleration=[0.0, -9.81]) fluid_system3.cache.density .= tank3.fluid.density v_fluid = zeros(2, TrixiParticles.nparticles(fluid_system3)) @@ -369,8 +422,8 @@ tank_reference = RectangularTank(particle_spacing, (width_reference, height_reference), (width_reference, height_reference), - density, acceleration=[0.0, -9.81], - state_equation=state_equation, n_layers=0, + density; acceleration=[0.0, -9.81], + state_equation, n_layers=0, faces=(true, true, true, false)) # Because it is a pain to deal with the linear indices of the pressure arrays, diff --git a/test/schemes/boundary/dummy_particles/rhs.jl b/test/schemes/boundary/dummy_particles/rhs.jl index 4d64fc61a5..5fe01a743f 100644 --- a/test/schemes/boundary/dummy_particles/rhs.jl +++ b/test/schemes/boundary/dummy_particles/rhs.jl @@ -17,11 +17,11 @@ # Create several neighbor systems to test fluid-neighbor interaction function second_systems(initial_condition, density_calculator, state_equation, smoothing_kernel, smoothing_length) - second_fluid_system = WeaklyCompressibleSPHSystem(initial_condition, - density_calculator, - state_equation, + second_fluid_system = WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, - smoothing_length) + smoothing_length, + density_calculator, + state_equation) # Overwrite `second_fluid_system.pressure` because we skip the update step second_fluid_system.pressure .= initial_condition.pressure @@ -77,8 +77,9 @@ v_boundary_continuity = copy(initial_condition.density') # TLSPH system - structure_system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, 0.0, 0.0, + structure_system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=0.0, + poisson_ratio=0.0, boundary_model=boundary_model_continuity) # Positions of the structure particles are not used here @@ -126,7 +127,7 @@ for seed in 1:3 # A larger number of particles will increase accumulated errors in the # summation. A larger tolerance will have to be used for the tests below. - ic = rectangular_patch(particle_spacing, (3, 3), seed=seed) + ic = rectangular_patch(particle_spacing, (3, 3); seed) # Split initial condition at center particle into two systems center_particle = ceil(Int, TrixiParticles.nparticles(ic) / 2) @@ -146,11 +147,11 @@ ic.pressure[(center_particle + 1):end], ic.particle_spacing) - fluid_system = WeaklyCompressibleSPHSystem(fluid, - density_calculator, - state_equation, + fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, - smoothing_length) + smoothing_length, + density_calculator, + state_equation) n_particles = TrixiParticles.nparticles(fluid_system) # Overwrite `fluid_system.pressure` because we skip the update step diff --git a/test/schemes/boundary/monaghan_kajtar/monaghan_kajtar.jl b/test/schemes/boundary/monaghan_kajtar/monaghan_kajtar.jl index d5c0042c28..ec303dd021 100644 --- a/test/schemes/boundary/monaghan_kajtar/monaghan_kajtar.jl +++ b/test/schemes/boundary/monaghan_kajtar/monaghan_kajtar.jl @@ -22,9 +22,10 @@ fluid = rectangular_patch(particle_spacing, (3, 3), perturbation_factor=0.0, perturbation_factor_position=0.0, offset=(-1.5particle_spacing, 0.0)) - fluid_system = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length) + fluid_system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation) # Use double spacing for the boundary (exactly the opposite of what we would do # in a simulation) to test that forces grow infinitely when a fluid particle diff --git a/test/schemes/boundary/open_boundary/characteristic_variables.jl b/test/schemes/boundary/open_boundary/characteristic_variables.jl index 58a76ae8f1..9d2e9fa03e 100644 --- a/test/schemes/boundary/open_boundary/characteristic_variables.jl +++ b/test/schemes/boundary/open_boundary/characteristic_variables.jl @@ -58,10 +58,11 @@ density, pressure, direction=(sign_ * flow_direction)) - fluid_system = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, + fluid_system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, + smoothing_length, + sound_speed, buffer_size=0, - density_calculator=ContinuityDensity(), - smoothing_length, sound_speed) + density_calculator=ContinuityDensity()) boundary_system = OpenBoundarySystem(boundary_zone; fluid_system, buffer_size=0, @@ -148,9 +149,11 @@ inflow = BoundaryZone(; boundary_face, boundary_type=InFlow(), face_normal, open_boundary_layers=10, density=1.0, particle_spacing) - system_wcsph = WeaklyCompressibleSPHSystem(initial_condition, ContinuityDensity(), - nothing, - SchoenbergCubicSplineKernel{n_dims}(), 1) + system_wcsph = WeaklyCompressibleSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1, + density_calculator=ContinuityDensity(), + state_equation=nothing) open_boundary_wcsph = OpenBoundarySystem(inflow; fluid_system=system_wcsph, buffer_size=0, @@ -158,9 +161,10 @@ @test TrixiParticles.v_nvariables(open_boundary_wcsph) == n_dims - system_edac = EntropicallyDampedSPHSystem(initial_condition, - SchoenbergCubicSplineKernel{n_dims}(), - 1.0, 1.0) + system_edac = EntropicallyDampedSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1.0, + sound_speed=1.0) open_boundary_edac = OpenBoundarySystem(inflow; fluid_system=system_edac, buffer_size=0, diff --git a/test/schemes/boundary/open_boundary/dynamical_pressure.jl b/test/schemes/boundary/open_boundary/dynamical_pressure.jl index 1baee305cd..bd325eb690 100644 --- a/test/schemes/boundary/open_boundary/dynamical_pressure.jl +++ b/test/schemes/boundary/open_boundary/dynamical_pressure.jl @@ -21,7 +21,7 @@ for seed in 1:3 # A larger number of particles will increase accumulated errors in the # summation. A larger tolerance has to be used for the tests below. - ic = rectangular_patch(particle_spacing, (3, 3), seed=seed) + ic = rectangular_patch(particle_spacing, (3, 3); seed) min_coords = vec(minimum(ic.coordinates, dims=2)) .- particle_spacing max_coords = vec(maximum(ic.coordinates, dims=2)) .+ particle_spacing @@ -31,14 +31,16 @@ density=1.0, particle_spacing) bz.initial_condition.mass .= ic.mass - system_wcsph = WeaklyCompressibleSPHSystem(ic, density_calculator, - state_equation, smoothing_kernel, - smoothing_length) + system_wcsph = WeaklyCompressibleSPHSystem(ic; smoothing_kernel, + smoothing_length, + density_calculator, + state_equation) - system_edac = EntropicallyDampedSPHSystem(ic, smoothing_kernel, + system_edac = EntropicallyDampedSPHSystem(ic; smoothing_kernel, + smoothing_length, + sound_speed=0.0, pressure_acceleration=nothing, - density_calculator=density_calculator, - smoothing_length, 0.0) + density_calculator) open_boundary_wcsph = OpenBoundarySystem(bz; fluid_system=system_wcsph, buffer_size=0, @@ -126,9 +128,11 @@ inflow = BoundaryZone(; boundary_face, boundary_type=InFlow(), face_normal, open_boundary_layers=10, density=1.0, particle_spacing) - system_wcsph = WeaklyCompressibleSPHSystem(initial_condition, ContinuityDensity(), - nothing, - SchoenbergCubicSplineKernel{n_dims}(), 1) + system_wcsph = WeaklyCompressibleSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1, + density_calculator=ContinuityDensity(), + state_equation=nothing) open_boundary_wcsph = OpenBoundarySystem(inflow; fluid_system=system_wcsph, buffer_size=0, @@ -138,9 +142,10 @@ @test TrixiParticles.v_nvariables(open_boundary_wcsph) == n_dims + 1 # EDAC with `SummationDensity` - system_edac_1 = EntropicallyDampedSPHSystem(initial_condition, - SchoenbergCubicSplineKernel{n_dims}(), - 1.0, 1.0) + system_edac_1 = EntropicallyDampedSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1.0, + sound_speed=1.0) open_boundary_edac_1 = OpenBoundarySystem(inflow; fluid_system=system_edac_1, buffer_size=0, @@ -150,9 +155,10 @@ @test TrixiParticles.v_nvariables(open_boundary_edac_1) == n_dims + 2 # EDAC with `ContinuityDensity` - system_edac_2 = EntropicallyDampedSPHSystem(initial_condition, - SchoenbergCubicSplineKernel{n_dims}(), - 1.0, 1.0, + system_edac_2 = EntropicallyDampedSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1.0, + sound_speed=1.0, density_calculator=ContinuityDensity()) open_boundary_edac_2 = OpenBoundarySystem(inflow; fluid_system=system_edac_2, diff --git a/test/schemes/boundary/open_boundary/mirroring.jl b/test/schemes/boundary/open_boundary/mirroring.jl index be8228ad6d..d9e41ee0a2 100644 --- a/test/schemes/boundary/open_boundary/mirroring.jl +++ b/test/schemes/boundary/open_boundary/mirroring.jl @@ -49,8 +49,8 @@ smoothing_length = 1.5 * particle_spacing smoothing_kernel = WendlandC2Kernel{ndims(domain_fluid)}() - fluid_system = EntropicallyDampedSPHSystem(domain_fluid, smoothing_kernel, - smoothing_length, 1.0) + fluid_system = EntropicallyDampedSPHSystem(domain_fluid; smoothing_kernel, + smoothing_length, sound_speed=1.0) fluid_system.cache.density .= domain_fluid.density @@ -145,8 +145,8 @@ smoothing_length = 1.5 * particle_spacing smoothing_kernel = WendlandC2Kernel{ndims(domain_fluid)}() - fluid_system = EntropicallyDampedSPHSystem(domain_fluid, smoothing_kernel, - smoothing_length, 1.0) + fluid_system = EntropicallyDampedSPHSystem(domain_fluid; smoothing_kernel, + smoothing_length, sound_speed=1.0) fluid_system.cache.density .= domain_fluid.density @@ -213,8 +213,8 @@ smoothing_length = 1.5 * particle_spacing smoothing_kernel = WendlandC2Kernel{ndims(domain_fluid)}() - fluid_system = EntropicallyDampedSPHSystem(domain_fluid, smoothing_kernel, - smoothing_length, 1.0) + fluid_system = EntropicallyDampedSPHSystem(domain_fluid; smoothing_kernel, + smoothing_length, sound_speed=1.0) fluid_system.cache.density .= 1000.0 if i == 2 @@ -226,8 +226,8 @@ inflow = BoundaryZone(; boundary_face=face_in, boundary_type=InFlow(), face_normal=(i == 2 ? [1.0, 0.0] : [1.0, 0.0, 0.0]), - open_boundary_layers=open_boundary_layers, density=1000.0, - particle_spacing, average_inflow_velocity=true) + open_boundary_layers, density=1000.0, particle_spacing, + average_inflow_velocity=true) open_boundary_in = OpenBoundarySystem(inflow; fluid_system, boundary_model=BoundaryModelMirroringTafuni(), buffer_size=0) @@ -269,8 +269,9 @@ smoothing_length = 1.2 * particle_spacing smoothing_kernel = WendlandC2Kernel{2}() - fluid_system = EntropicallyDampedSPHSystem(domain_fluid, smoothing_kernel, - smoothing_length, 1.0) + fluid_system = EntropicallyDampedSPHSystem(domain_fluid; smoothing_kernel, + smoothing_length, + sound_speed=1.0) fluid_system.cache.density .= domain_fluid.density @@ -348,10 +349,11 @@ smoothing_kernel = WendlandC2Kernel{2}() # Use a temporary fluid system just to interpolate the pressure - interpolation_system = WeaklyCompressibleSPHSystem(entire_domain, - ContinuityDensity(), - nothing, smoothing_kernel, - smoothing_length) + interpolation_system = WeaklyCompressibleSPHSystem(entire_domain; + smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation=nothing) interpolation_system.pressure .= entire_domain.pressure semi = Semidiscretization(interpolation_system) @@ -551,9 +553,11 @@ inflow = BoundaryZone(; boundary_face, boundary_type=InFlow(), face_normal, open_boundary_layers=10, density=1.0, particle_spacing) - system_wcsph = WeaklyCompressibleSPHSystem(initial_condition, ContinuityDensity(), - nothing, - SchoenbergCubicSplineKernel{n_dims}(), 1) + system_wcsph = WeaklyCompressibleSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1, + density_calculator=ContinuityDensity(), + state_equation=nothing) open_boundary_wcsph = OpenBoundarySystem(inflow; fluid_system=system_wcsph, buffer_size=0, @@ -561,10 +565,10 @@ @test TrixiParticles.v_nvariables(open_boundary_wcsph) == n_dims - system_edac_1 = EntropicallyDampedSPHSystem(initial_condition, - SchoenbergCubicSplineKernel{n_dims}(), - 1.0, - 1.0) + system_edac_1 = EntropicallyDampedSPHSystem(initial_condition; + smoothing_kernel=SchoenbergCubicSplineKernel{n_dims}(), + smoothing_length=1.0, + sound_speed=1.0) open_boundary_edac_1 = OpenBoundarySystem(inflow; fluid_system=system_edac_1, buffer_size=0, diff --git a/test/schemes/boundary/open_boundary/open_boundary.jl b/test/schemes/boundary/open_boundary/open_boundary.jl index 3500490263..80b4da4e8f 100644 --- a/test/schemes/boundary/open_boundary/open_boundary.jl +++ b/test/schemes/boundary/open_boundary/open_boundary.jl @@ -16,8 +16,8 @@ include("pressure_model.jl") smoothing_length = 1.3 * particle_spacing smoothing_kernel = WendlandC2Kernel{ndims(fluid)}() - fluid_system = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, smoothing_length, - 1.0) + fluid_system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, + smoothing_length, sound_speed=1.0) fluid_system.cache.density .= fluid.density # Use a smaller cross-sectional area to test user-defined area functionality @@ -26,9 +26,9 @@ include("pressure_model.jl") sample_points = RectangularShape(particle_spacing, (1, round(Int, n_particles_y / 2)), (0.0, 0.5), density=1.0).coordinates - zone = BoundaryZone(; boundary_face=([0.0, 0.0], [0.0, 2.0]), - face_normal=(-1.0, 0.0), open_boundary_layers=10, density=1000.0, - particle_spacing, sample_points=sample_points, + zone = BoundaryZone(; boundary_face=([0.0, 0.0], [0.0, 2.0]), face_normal=(-1.0, 0.0), + open_boundary_layers=10, density=1000.0, particle_spacing, + sample_points, reference_velocity=(pos, t) -> velocity_function(pos)) open_boundary = OpenBoundarySystem(zone; fluid_system, diff --git a/test/schemes/boundary/open_boundary/pressure_model.jl b/test/schemes/boundary/open_boundary/pressure_model.jl index c0e1baffe7..9d348e5627 100644 --- a/test/schemes/boundary/open_boundary/pressure_model.jl +++ b/test/schemes/boundary/open_boundary/pressure_model.jl @@ -129,9 +129,9 @@ # # The solution is obtained using simple Euler integration over the time interval `tspan`. # Reference pressure values are evaluated at discrete time points (`validation_times`): - # params_RCR = (R_2=R2, R_1=R1, C=C, q_func=pulsatile_flow, dt=dt) + # params_RCR = (; R_2=R2, R_1=R1, C, q_func=pulsatile_flow, dt) # sol_RCR = solve(ODEProblem(pressure_RCR_ode!, [p0], tspan, params_RCR), Euler(), - # dt=dt, adaptive=false) + # dt, adaptive=false) # validation_times = collect(range(7T, 8T, step=50 * dt)) # pressures_ref = vec(stack(sol_RCR(validation_times))) # diff --git a/test/schemes/fluid/rhs.jl b/test/schemes/fluid/rhs.jl index ea008db6cc..20e7e6330a 100644 --- a/test/schemes/fluid/rhs.jl +++ b/test/schemes/fluid/rhs.jl @@ -58,23 +58,24 @@ "IISPH" ] if system_name == "WCSPH" - system = WeaklyCompressibleSPHSystem(fluid, + system = WeaklyCompressibleSPHSystem(fluid; + smoothing_kernel, + smoothing_length, density_calculator, state_equation, - smoothing_kernel, - smoothing_length; pressure_acceleration) elseif system_name == "EDAC" - system = EntropicallyDampedSPHSystem(fluid, + system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, - smoothing_length, 0.0; + smoothing_length, + sound_speed=0.0, density_calculator, pressure_acceleration) elseif system_name == "IISPH" - system = ImplicitIncompressibleSPHSystem(fluid, + system = ImplicitIncompressibleSPHSystem(fluid; smoothing_kernel, smoothing_length, - 1000.0, + reference_density=1000.0, time_step=0.001) end @@ -130,18 +131,21 @@ for seed in 1:3 # A larger number of particles will increase accumulated errors in the # summation. A larger tolerance has to be used for the tests below. - fluid = rectangular_patch(particle_spacing, (3, 3), seed=seed) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, density_calculator, - state_equation, smoothing_kernel, - smoothing_length) - - system_edac = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, + fluid = rectangular_patch(particle_spacing, (3, 3); seed) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator, + state_equation) + + system_edac = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, + smoothing_length, + sound_speed=0.0, pressure_acceleration=nothing, - density_calculator=density_calculator, - smoothing_length, 0.0) + density_calculator) - system_iisph = ImplicitIncompressibleSPHSystem(fluid, smoothing_kernel, - smoothing_length, 1000.0, + system_iisph = ImplicitIncompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + reference_density=1000.0, time_step=0.001) n_particles = TrixiParticles.nparticles(system_edac) diff --git a/test/schemes/fluid/surface_normal_sph.jl b/test/schemes/fluid/surface_normal_sph.jl index 2c761253a4..5eb8a81704 100644 --- a/test/schemes/fluid/surface_normal_sph.jl +++ b/test/schemes/fluid/surface_normal_sph.jl @@ -29,10 +29,10 @@ function create_boundary_system(coordinates, particle_spacing, state_equation, k boundary_model = BoundaryModelDummyParticles(wall.density, wall.mass, - state_equation=state_equation, AdamiPressureExtrapolation(), kernel, - smoothing_length, + smoothing_length; + state_equation, correction=nothing, reference_particle_spacing=particle_spacing) @@ -49,10 +49,8 @@ function create_rigid_boundary_system(coordinates, particle_spacing, state_equat rigid_model = BoundaryModelDummyParticles(wall_system.initial_condition.density, wall_system.initial_condition.mass, - AdamiPressureExtrapolation(), - kernel, - smoothing_length, - state_equation=state_equation, + AdamiPressureExtrapolation(), kernel, + smoothing_length; state_equation, correction=nothing, reference_particle_spacing=particle_spacing) @@ -69,21 +67,18 @@ function create_fluid_system(coordinates, velocity, mass, density, particle_spac smoothing_kernel=SchoenbergCubicSplineKernel{NDIMS}()) tspan = (0.0, 0.01) - fluid = InitialCondition(coordinates=coordinates, - velocity=velocity, - mass=mass, - density=density, - particle_spacing=particle_spacing) + fluid = InitialCondition(; coordinates, velocity, mass, density, particle_spacing) state_equation = StateEquationCole(sound_speed=10.0, reference_density=1000.0, exponent=1) - system = WeaklyCompressibleSPHSystem(fluid, SummationDensity(), state_equation, - smoothing_kernel, smoothing_length; - surface_normal_method=surface_normal_method, + system = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, smoothing_length, + density_calculator=SummationDensity(), + state_equation, + surface_normal_method, reference_particle_spacing=particle_spacing, - surface_tension=surface_tension) + surface_tension) if wall boundary_system = if boundary_system_type == :wall @@ -163,31 +158,24 @@ end density = sphere_ic.density wall_system, wall_boundary, wall_semi, - wall_ode = create_fluid_system(coordinates, velocity, mass, density, - particle_spacing, + wall_ode = create_fluid_system(coordinates, velocity, mass, density, particle_spacing, SurfaceTensionMorris(surface_tension_coefficient=0.072); - NDIMS=NDIMS, - smoothing_length=smoothing_length, - smoothing_kernel=smoothing_kernel, + NDIMS, smoothing_length, smoothing_kernel, surface_normal_method=ColorfieldSurfaceNormal(interface_threshold=0.1, ideal_density_threshold=0.9), - wall=true, walldistance=2.0, - boundary_system_type=:wall) + wall=true, walldistance=2.0, boundary_system_type=:wall) rigid_system, rigid_boundary, rigid_semi, - rigid_ode = create_fluid_system(coordinates, velocity, mass, density, - particle_spacing, + rigid_ode = create_fluid_system(coordinates, velocity, mass, density, particle_spacing, SurfaceTensionMorris(surface_tension_coefficient=0.072); - NDIMS=NDIMS, - smoothing_length=smoothing_length, - smoothing_kernel=smoothing_kernel, + NDIMS, smoothing_length, smoothing_kernel, surface_normal_method=ColorfieldSurfaceNormal(interface_threshold=0.1, ideal_density_threshold=0.9), wall=true, walldistance=2.0, boundary_system_type=:rigid) - compute_and_test_surface_values(wall_system, wall_semi, wall_ode; NDIMS=NDIMS) - compute_and_test_surface_values(rigid_system, rigid_semi, rigid_ode; NDIMS=NDIMS) + compute_and_test_surface_values(wall_system, wall_semi, wall_ode; NDIMS) + compute_and_test_surface_values(rigid_system, rigid_semi, rigid_ode; NDIMS) @test isapprox(rigid_boundary.boundary_model.cache.initial_colorfield, wall_boundary.boundary_model.cache.initial_colorfield, @@ -227,18 +215,15 @@ end # wall is placed 2.0 away so that it doesn't have much influence on the result system, bnd_system, semi, - ode = create_fluid_system(coordinates, velocity, mass, - density, + ode = create_fluid_system(coordinates, velocity, mass, density, particle_spacing, SurfaceTensionMorris(surface_tension_coefficient=0.072); - NDIMS=NDIMS, - smoothing_length=smoothing_length, - smoothing_kernel=smoothing_kernel, + NDIMS, smoothing_length, smoothing_kernel, surface_normal_method=ColorfieldSurfaceNormal(interface_threshold=0.1, ideal_density_threshold=0.9), wall=true, walldistance=2.0) - compute_and_test_surface_values(system, semi, ode; NDIMS=NDIMS) + compute_and_test_surface_values(system, semi, ode; NDIMS) nparticles = size(coordinates, 2) expected_normals = zeros(NDIMS, nparticles) @@ -330,18 +315,15 @@ end density = sphere_ic.density system, bnd_system, semi, - ode = create_fluid_system(coordinates, velocity, mass, - density, + ode = create_fluid_system(coordinates, velocity, mass, density, particle_spacing, SurfaceTensionAkinci(surface_tension_coefficient=0.072); - NDIMS=NDIMS, - smoothing_length=smoothing_length, - smoothing_kernel=smoothing_kernel, + NDIMS, smoothing_length, smoothing_kernel, surface_normal_method=ColorfieldSurfaceNormal(interface_threshold=0.1, ideal_density_threshold=0.9), wall=true, walldistance=2.0) - compute_and_test_surface_values(system, semi, ode; NDIMS=NDIMS) + compute_and_test_surface_values(system, semi, ode; NDIMS) nparticles = size(coordinates, 2) expected_normals = zeros(NDIMS, nparticles) @@ -417,16 +399,13 @@ end # Create fluid system (no wall) system, bnd_system, semi, - ode = create_fluid_system(coordinates, velocity, mass, - density, particle_spacing, + ode = create_fluid_system(coordinates, velocity, mass, density, particle_spacing, SurfaceTensionMorris(surface_tension_coefficient=0.072); - NDIMS=NDIMS, - smoothing_length=1.5 * - particle_spacing, - wall=false, walldistance=0.0) + NDIMS, smoothing_length=1.5 * particle_spacing, wall=false, + walldistance=0.0) # Compute surface normals - compute_and_test_surface_values(system, semi, ode; NDIMS=NDIMS) + compute_and_test_surface_values(system, semi, ode; NDIMS) # Threshold to decide if a particle is "on" a boundary # (half the spacing is typical, adjust as needed) diff --git a/test/schemes/fluid/surface_tension.jl b/test/schemes/fluid/surface_tension.jl index 5dccbdb803..7fe8abbd97 100644 --- a/test/schemes/fluid/surface_tension.jl +++ b/test/schemes/fluid/surface_tension.jl @@ -98,10 +98,7 @@ mass = ones(2) density = ones(2) - ic = InitialCondition(coordinates=coords, - velocity=velocity, - mass=mass, - density=density, + ic = InitialCondition(; coordinates=coords, velocity, mass, density, particle_spacing=1.0) # 2. Define Density Calculator, State Equation, and Kernel @@ -113,11 +110,10 @@ smoothing_length = 0.5 # 3. Create the WeaklyCompressibleSPHSystem with Surface Tension - system = WeaklyCompressibleSPHSystem(ic, - density_calc, - eq_state, - kernel, - smoothing_length; + system = WeaklyCompressibleSPHSystem(ic; smoothing_kernel=kernel, + smoothing_length, + density_calculator=density_calc, + state_equation=eq_state, surface_tension=SurfaceTensionMomentumMorris(surface_tension_coefficient=1.0), surface_normal_method=ColorfieldSurfaceNormal(interface_threshold=0.1, ideal_density_threshold=0.9), diff --git a/test/schemes/fluid/viscosity.jl b/test/schemes/fluid/viscosity.jl index d4ead2cbcc..9163bbb588 100644 --- a/test/schemes/fluid/viscosity.jl +++ b/test/schemes/fluid/viscosity.jl @@ -18,9 +18,10 @@ @testset verbose=true "`ArtificialViscosityMonaghan`" begin viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) @@ -41,10 +42,11 @@ end @testset verbose=true "`ViscosityMorris`" begin nu = 7e-3 - viscosity = ViscosityMorris(nu=nu) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity) + viscosity = ViscosityMorris(; nu) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) @@ -71,9 +73,10 @@ end @testset verbose=true "`ViscosityAdami`" begin viscosity = ViscosityAdami(nu=7e-3) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) @@ -100,10 +103,11 @@ end @testset verbose=true "`ViscosityMorrisSGS`" begin nu = 7e-3 - viscosity = ViscosityMorrisSGS(nu=nu) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity) + viscosity = ViscosityMorrisSGS(; nu) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) @@ -131,9 +135,10 @@ end @testset verbose=true "`ViscosityAdamiSGS`" begin viscosity = ViscosityAdamiSGS(nu=7e-3) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length, viscosity=viscosity) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) @@ -178,9 +183,10 @@ a=2.0, n=1.0, epsilon=0.01) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length; viscosity=viscosity) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) @@ -204,9 +210,10 @@ a=2.0, n=0.3, epsilon=0.01) - system_wcsph = WeaklyCompressibleSPHSystem(fluid, ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length; viscosity=viscosity) + system_wcsph = WeaklyCompressibleSPHSystem(fluid; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation, viscosity) grad_kernel = TrixiParticles.smoothing_kernel_grad(system_wcsph, pos_diff, distance, 1) diff --git a/test/schemes/fluid/weakly_compressible_sph/density_diffusion.jl b/test/schemes/fluid/weakly_compressible_sph/density_diffusion.jl index 9e2c82a0f6..7dafc0377e 100644 --- a/test/schemes/fluid/weakly_compressible_sph/density_diffusion.jl +++ b/test/schemes/fluid/weakly_compressible_sph/density_diffusion.jl @@ -2,13 +2,7 @@ @testset verbose=true "DensityDiffusionAntuono" begin # Use `@trixi_testset` to isolate the mock functions in a separate namespace @trixi_testset "show" begin - # Mock initial condition - initial_condition = Val(:initial_condition) - Base.ndims(::Val{:initial_condition}) = 2 - Base.eltype(::Val{:initial_condition}) = Float64 - TrixiParticles.nparticles(::Val{:initial_condition}) = 15 - - density_diffusion = DensityDiffusionAntuono(delta=0.1, initial_condition) + density_diffusion = DensityDiffusionAntuono(delta=0.1) @test repr(density_diffusion) == "DensityDiffusionAntuono(0.1)" end diff --git a/test/schemes/fluid/weakly_compressible_sph/state_equation.jl b/test/schemes/fluid/weakly_compressible_sph/state_equation.jl index f86abd47f6..e454478c37 100644 --- a/test/schemes/fluid/weakly_compressible_sph/state_equation.jl +++ b/test/schemes/fluid/weakly_compressible_sph/state_equation.jl @@ -43,9 +43,9 @@ background_pressures = [0.0, 10_000.0, 100_000.0, 200_000.0] for background_pressure in background_pressures - state_equation = StateEquationCole(sound_speed=10.0, exponent=7, + state_equation = StateEquationCole(; sound_speed=10.0, exponent=7, reference_density=1000.0, - background_pressure=background_pressure) + background_pressure) @test state_equation(1000.0) == background_pressure @test state_equation(1001.0) > background_pressure + 10 # No pressure clipping @@ -155,7 +155,7 @@ # Work with pressures in ATM ATM = 101_325.0 - state_equation = StateEquationIdealGas(; sound_speed, gamma=gamma, + state_equation = StateEquationIdealGas(; sound_speed, gamma, reference_density=rest_density, background_pressure=1ATM) diff --git a/test/schemes/structure/total_lagrangian_sph/rhs.jl b/test/schemes/structure/total_lagrangian_sph/rhs.jl index ce498b4db2..e0abb48e4a 100644 --- a/test/schemes/structure/total_lagrangian_sph/rhs.jl +++ b/test/schemes/structure/total_lagrangian_sph/rhs.jl @@ -160,8 +160,9 @@ smoothing_kernel = SchoenbergCubicSplineKernel{2}() initial_condition = InitialCondition(; coordinates, mass, density) - system = TotalLagrangianSPHSystem(initial_condition, - smoothing_kernel, smoothing_length, E, nu) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu) tspan = (0.0, 1.0) names = ["CPU code", "GPU code emulated on the CPU"] diff --git a/test/setups/rectangular_shape.jl b/test/setups/rectangular_shape.jl index 7c2fd6875b..4e2419487f 100644 --- a/test/setups/rectangular_shape.jl +++ b/test/setups/rectangular_shape.jl @@ -142,10 +142,9 @@ n_particles_per_dimension = (2, 5) @testset "Loop Order :y_first" begin - shape = RectangularShape(particle_spacing, - n_particles_per_dimension, (0.0, 0.0), - acceleration=(0.0, -1.0), - state_equation=state_equation) + shape = RectangularShape(particle_spacing, n_particles_per_dimension, + (0.0, 0.0); acceleration=(0.0, -1.0), + state_equation) @test shape.pressure ≈ vec(pressure) @test shape.density == @@ -155,21 +154,18 @@ end @testset "Loop Order :x_first" begin - shape = RectangularShape(particle_spacing, - n_particles_per_dimension, (0.0, 0.0), - acceleration=(0.0, -1.0), - state_equation=state_equation, - loop_order=:x_first) + shape = RectangularShape(particle_spacing, n_particles_per_dimension, + (0.0, 0.0); acceleration=(0.0, -1.0), + state_equation, loop_order=:x_first) # Transpose `pressure` @test shape.pressure ≈ vec(pressure') end @testset "Positive Acceleration" begin - shape = RectangularShape(particle_spacing, - n_particles_per_dimension, (0.0, 0.0), - acceleration=(0.0, 1.0), - state_equation=state_equation) + shape = RectangularShape(particle_spacing, n_particles_per_dimension, + (0.0, 0.0); acceleration=(0.0, 1.0), + state_equation) @test shape.pressure ≈ vec(reverse(pressure)) @test shape.density == @@ -181,10 +177,8 @@ @testset "Horizontal Gravity" begin n_particles_per_dimension = (5, 2) - shape = RectangularShape(particle_spacing, - n_particles_per_dimension, (0.0, 0.0), - acceleration=(-1.0, 0.0), - state_equation=state_equation) + shape = RectangularShape(particle_spacing, n_particles_per_dimension, + (0.0, 0.0); acceleration=(-1.0, 0.0), state_equation) @test shape.pressure ≈ 1.0 * vec(pressure') @test shape.density == @@ -289,9 +283,9 @@ end permute!(acceleration_, permutation) shape = RectangularShape(particle_spacing, - Tuple(n_particles_per_dimension_), - (0.0, 0.0, 0.0), density=1000.0, - loop_order=loop_order, acceleration=acceleration_) + Tuple(n_particles_per_dimension_), (0.0, 0.0, 0.0); + density=1000.0, loop_order, + acceleration=acceleration_) # Permute pressure with acceleration permutation permuted1 = permutedims(pressure, permutation) @@ -349,10 +343,9 @@ end acceleration_ = collect(acceleration) permute!(acceleration_, permutation) - shape = RectangularShape(particle_spacing, - Tuple(n_particles_per_dimension_), (0.0, 0.0, 0.0), - acceleration=acceleration_, - state_equation=state_equation) + shape = RectangularShape(particle_spacing, Tuple(n_particles_per_dimension_), + (0.0, 0.0, 0.0); acceleration=acceleration_, + state_equation) @test shape.pressure ≈ vec(permutedims(pressure, permutation)) density = TrixiParticles.inverse_state_equation.(Ref(state_equation), diff --git a/test/systems/dem_system.jl b/test/systems/dem_system.jl index 3816677598..746366d095 100644 --- a/test/systems/dem_system.jl +++ b/test/systems/dem_system.jl @@ -11,7 +11,7 @@ contact_model = HertzContactModel(1.0e10, 0.3) # Construct the DEM system. - system = DEMSystem(initial_condition, contact_model, acceleration=(0.0, 10.0)) + system = DEMSystem(initial_condition; contact_model, acceleration=(0.0, 10.0)) # Expected compact representation. show_compact = "DEMSystem{2}(InitialCondition{Float64, Float64}(), HertzContactModel: elastic_modulus = 1.0e10, poissons_ratio = 0.3, damping_coefficient = 0.0001) with 2 particles" @@ -44,7 +44,7 @@ end contact_model = LinearContactModel(200000.0) # Construct the DEM system. - system = DEMSystem(initial_condition, contact_model, acceleration=(0.0, 10.0)) + system = DEMSystem(initial_condition; contact_model, acceleration=(0.0, 10.0)) # Expected compact representation. show_compact = "DEMSystem{2}(InitialCondition{Float64, Float64}(), LinearContactModel: normal_stiffness = 200000.0, damping_coefficient = 0.0001) with 2 particles" diff --git a/test/systems/edac_system.jl b/test/systems/edac_system.jl index ac8a424853..ce04cd6774 100644 --- a/test/systems/edac_system.jl +++ b/test/systems/edac_system.jl @@ -24,7 +24,7 @@ initial_condition = InitialCondition(; coordinates, mass, density) - system = EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, + system = EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, sound_speed) @test system isa EntropicallyDampedSPHSystem{NDIMS} @@ -36,17 +36,16 @@ @test system.viscosity === nothing @test system.nu_edac == (0.5 * smoothing_length * sound_speed) / 8 @test system.acceleration == [0.0 for _ in 1:NDIMS] - error_str1 = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str1) EntropicallyDampedSPHSystem(initial_condition, + @test_throws ArgumentError(error_str1) EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, sound_speed, acceleration=(0.0)) error_str2 = "smoothing kernel dimensionality must be $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str2) EntropicallyDampedSPHSystem(initial_condition, - smoothing_kernel2, + @test_throws ArgumentError(error_str2) EntropicallyDampedSPHSystem(initial_condition; + smoothing_kernel=smoothing_kernel2, smoothing_length, sound_speed) end @@ -79,8 +78,8 @@ smoothing_length = 0.362 sound_speed = 10.0 - system = EntropicallyDampedSPHSystem(setup, smoothing_kernel, smoothing_length, - sound_speed) + system = EntropicallyDampedSPHSystem(setup; smoothing_kernel, + smoothing_length, sound_speed) @test system isa EntropicallyDampedSPHSystem{NDIMS} @test system.initial_condition == setup @@ -105,7 +104,7 @@ sound_speed = 10.0 error_str = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str) EntropicallyDampedSPHSystem(setup, + @test_throws ArgumentError(error_str) EntropicallyDampedSPHSystem(setup; smoothing_kernel, smoothing_length, sound_speed, @@ -125,7 +124,7 @@ sound_speed = 10.0 initial_condition = InitialCondition(; coordinates, mass, density) - system = EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, + system = EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, sound_speed) show_compact = "EntropicallyDampedSPHSystem{2}(SummationDensity(), nothing, nothing, Val{:smoothing_kernel}(), [0.0, 0.0], nothing, nothing) with 2 particles" @@ -161,7 +160,7 @@ sound_speed = 10.0 initial_condition = InitialCondition(; coordinates, mass, density, pressure) - system = EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, + system = EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, sound_speed) u0 = zeros(TrixiParticles.u_nvariables(system), @@ -187,7 +186,7 @@ initial_condition = InitialCondition(; coordinates, velocity, mass, density, pressure) - system = EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, + system = EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, sound_speed) v0 = zeros(TrixiParticles.v_nvariables(system), @@ -204,7 +203,7 @@ initial_condition = InitialCondition(; coordinates, velocity, mass, density, pressure=pressure_function) - system = EntropicallyDampedSPHSystem(initial_condition, smoothing_kernel, + system = EntropicallyDampedSPHSystem(initial_condition; smoothing_kernel, smoothing_length, sound_speed) v0 = zeros(TrixiParticles.v_nvariables(system), @@ -224,10 +223,10 @@ transport_velocity = [nothing, TransportVelocityAdami(background_pressure=10000.0)] names = ["No TVF", "TransportVelocityAdami"] @testset "$(names[i])" for i in eachindex(transport_velocity) - system = EntropicallyDampedSPHSystem(fluid, smoothing_kernel, + system = EntropicallyDampedSPHSystem(fluid; smoothing_kernel, + smoothing_length, sound_speed=0.0, shifting_technique=transport_velocity[i], - average_pressure_reduction=true, - smoothing_length, 0.0) + average_pressure_reduction=true) semi = Semidiscretization(system) TrixiParticles.initialize_neighborhood_searches!(semi) diff --git a/test/systems/iisph_system.jl b/test/systems/iisph_system.jl index 082b607e18..2bcd740552 100644 --- a/test/systems/iisph_system.jl +++ b/test/systems/iisph_system.jl @@ -48,15 +48,10 @@ smoothing_length = 0.362 initial_condition = InitialCondition(; coordinates, mass, density) - system = ImplicitIncompressibleSPHSystem(initial_condition, - smoothing_kernel, - smoothing_length, - reference_density, - omega=omega, - max_error=max_error, - min_iterations=min_iterations, - max_iterations=max_iterations, - time_step=time_step) + system = ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, reference_density, + omega, max_error, min_iterations, + max_iterations, time_step) # Constructor copies input fields, applies defaults, and respects the requested dimensionality @test system isa ImplicitIncompressibleSPHSystem{NDIMS} @@ -76,32 +71,32 @@ # A too-short acceleration vector triggers dimension validation error_str1 = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str1) ImplicitIncompressibleSPHSystem(initial_condition, + @test_throws ArgumentError(error_str1) ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, - density, + reference_density=density, acceleration=(0.0), time_step=0.001) # Smoothing kernel dimensionality must match the problem dimension error_str2 = "smoothing kernel dimensionality must be $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str2) ImplicitIncompressibleSPHSystem(initial_condition, - smoothing_kernel2, + @test_throws ArgumentError(error_str2) ImplicitIncompressibleSPHSystem(initial_condition; + smoothing_kernel=smoothing_kernel2, smoothing_length, reference_density, time_step=0.001) # Reference density must be positive error_str3 = "`reference_density` must be a positive number" - @test_throws ArgumentError(error_str3) ImplicitIncompressibleSPHSystem(initial_condition, + @test_throws ArgumentError(error_str3) ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, - 0.0, + reference_density=0.0, time_step=0.001) # max_error is a percentage and must be in (0, 100] error_str4 = "`max_error` is given in percentage, so it must be a number between 0 and 100" - @test_throws ArgumentError(error_str4) ImplicitIncompressibleSPHSystem(initial_condition, + @test_throws ArgumentError(error_str4) ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, @@ -110,7 +105,7 @@ # min_iterations must be strictly positive error_str5 = "`min_iterations` must be a positive number" - @test_throws ArgumentError(error_str5) ImplicitIncompressibleSPHSystem(initial_condition, + @test_throws ArgumentError(error_str5) ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, @@ -119,7 +114,7 @@ # min_iterations must not exceed max_iterations error_str6 = "`min_iterations` must be smaller or equal to `max_iterations`" - @test_throws ArgumentError(error_str6) ImplicitIncompressibleSPHSystem(initial_condition, + @test_throws ArgumentError(error_str6) ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, @@ -128,12 +123,12 @@ time_step=0.001) # time_step must be strictly positive - error_str7 = "`time_step must be a positive number" - @test_throws ArgumentError(error_str6) ImplicitIncompressibleSPHSystem(initial_condition, + error_str7 = "`time_step` must be a positive number" + @test_throws ArgumentError(error_str7) ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, - min_iterations=10, + min_iterations=1, max_iterations=5, time_step=0) end @@ -169,7 +164,7 @@ density_calculator = SummationDensity() - system = ImplicitIncompressibleSPHSystem(setup, + system = ImplicitIncompressibleSPHSystem(setup; smoothing_kernel, smoothing_length, reference_density, @@ -202,7 +197,7 @@ # Acceleration vector length validation also applies to setup-based constructors error_str = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str) ImplicitIncompressibleSPHSystem(setup, + @test_throws ArgumentError(error_str) ImplicitIncompressibleSPHSystem(setup; smoothing_kernel, smoothing_length, reference_density, @@ -223,7 +218,7 @@ smoothing_length = 0.362 initial_condition = InitialCondition(; coordinates, mass, density) - system = ImplicitIncompressibleSPHSystem(initial_condition, + system = ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, @@ -261,7 +256,7 @@ smoothing_length = 0.362 initial_condition = InitialCondition(; coordinates, mass, density) - system = ImplicitIncompressibleSPHSystem(initial_condition, + system = ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, time_step=0.001) @@ -287,7 +282,7 @@ initial_condition = InitialCondition(; coordinates, velocity, mass, density) # SummationDensity (is always in use) - system = ImplicitIncompressibleSPHSystem(initial_condition, + system = ImplicitIncompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, reference_density, @@ -316,8 +311,10 @@ pressure_a = [0.8] ic_a = InitialCondition(; coordinates, velocity, mass=mass_a, density=density_a, pressure=pressure_a) - system = ImplicitIncompressibleSPHSystem(ic_a, smoothing_kernel, - smoothing_length, 6.0, + system = ImplicitIncompressibleSPHSystem(ic_a; + smoothing_kernel, + smoothing_length, + reference_density=6.0, time_step=0.5) mass_b = [3.0] @@ -325,8 +322,10 @@ pressure_b = [1.2] ic_b = InitialCondition(; coordinates, velocity, mass=mass_b, density=density_b, pressure=pressure_b) - neighbor_system = ImplicitIncompressibleSPHSystem(ic_b, smoothing_kernel, - smoothing_length, 5.0, + neighbor_system = ImplicitIncompressibleSPHSystem(ic_b; + smoothing_kernel, + smoothing_length, + reference_density=5.0, time_step=0.5) system.sum_d_ij_pj[:, 1] .= (0.4, -0.2) @@ -363,8 +362,10 @@ pressure_a = [0.8] ic_a = InitialCondition(; coordinates, velocity, mass=mass_a, density=density_a, pressure=pressure_a) - system = ImplicitIncompressibleSPHSystem(ic_a, smoothing_kernel, - smoothing_length, 6.0, + system = ImplicitIncompressibleSPHSystem(ic_a; + smoothing_kernel, + smoothing_length, + reference_density=6.0, time_step=0.5) system.sum_d_ij_pj[:, 1] .= (0.4, -0.2) @@ -429,9 +430,12 @@ 0.0 0.2] velocity = zeros(2, 2) ic = InitialCondition(; coordinates, velocity, mass, density, pressure) - system_pressure = ImplicitIncompressibleSPHSystem(ic, smoothing_kernel, - smoothing_length, 1000.0, - omega=0.4, time_step=0.5) + system_pressure = ImplicitIncompressibleSPHSystem(ic; + smoothing_kernel, + smoothing_length, + reference_density=1000.0, + omega=0.4, + time_step=0.5) system_pressure.predicted_density .= [990.0, 1010.0] system_pressure.sum_term .= [5.0, -2.0] system_pressure.a_ii .= [0.5, 1.0e-10] @@ -463,9 +467,12 @@ 0.0 0.2] velocity = zeros(2, 2) ic = InitialCondition(; coordinates, velocity, mass, density, pressure) - system_iters = ImplicitIncompressibleSPHSystem(ic, smoothing_kernel, - smoothing_length, 1000.0, - omega=0.6, max_error=0.25, + system_iters = ImplicitIncompressibleSPHSystem(ic; + smoothing_kernel, + smoothing_length, + reference_density=1000.0, + omega=0.6, + max_error=0.25, min_iterations=3, max_iterations=7, time_step=0.25) diff --git a/test/systems/rigid_system.jl b/test/systems/rigid_system.jl index a1ea2b6de9..3f768db542 100644 --- a/test/systems/rigid_system.jl +++ b/test/systems/rigid_system.jl @@ -15,10 +15,8 @@ smoothing_kernel, smoothing_length) - system = RigidBodySystem(initial_condition; - boundary_model=boundary_model, - acceleration=(0.0, -9.81), - particle_spacing=0.1) + system = RigidBodySystem(initial_condition; boundary_model, + acceleration=(0.0, -9.81), particle_spacing=0.1) @test ndims(system) == 2 @test system.initial_condition == initial_condition @@ -59,8 +57,7 @@ smoothing_kernel, smoothing_length) - system = RigidBodySystem(initial_condition; - boundary_model=boundary_model, + system = RigidBodySystem(initial_condition; boundary_model, acceleration=(0.0, -9.81)) @test !haskey(system.cache, :contact_manifold_count) @@ -97,7 +94,7 @@ smoothing_kernel, smoothing_length) - system = RigidBodySystem(initial_condition; boundary_model=boundary_model) + system = RigidBodySystem(initial_condition; boundary_model) v = zeros(TrixiParticles.v_nvariables(system), TrixiParticles.n_integrated_particles(system)) @@ -122,7 +119,7 @@ source_terms = (coords, velocity, density, pressure, t) -> SVector(density, pressure) - system = RigidBodySystem(initial_condition; source_terms=source_terms) + system = RigidBodySystem(initial_condition; source_terms) semi = Semidiscretization(system, neighborhood_search=nothing) system = semi.systems[1] ode = semidiscretize(semi, (0.0, 0.0); reset_threads=false) @@ -427,8 +424,7 @@ smoothing_kernel, smoothing_length) - rigid_system = RigidBodySystem(initial_condition; - boundary_model=boundary_model) + rigid_system = RigidBodySystem(initial_condition; boundary_model) semi = Semidiscretization(rigid_system) ode = semidiscretize(semi, (0.0, 0.01)) v_ode, u_ode = ode.u0.x @@ -455,9 +451,10 @@ smoothing_length = 0.12 state_equation = StateEquationCole(; sound_speed=10.0, reference_density=1000.0, exponent=7.0) - fluid_system = WeaklyCompressibleSPHSystem(rigid_ic, SummationDensity(), - state_equation, smoothing_kernel, - smoothing_length) + fluid_system = WeaklyCompressibleSPHSystem(rigid_ic; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) @test_throws ArgumentError Semidiscretization(fluid_system, rigid_system) @@ -467,11 +464,11 @@ smoothing_length) rigid_system_with_dummy = RigidBodySystem(rigid_ic; boundary_model=rigid_boundary_model) - fluid_with_surface_tension = WeaklyCompressibleSPHSystem(rigid_ic, - SummationDensity(), - state_equation, + fluid_with_surface_tension = WeaklyCompressibleSPHSystem(rigid_ic; smoothing_kernel, - smoothing_length; + smoothing_length, + density_calculator=SummationDensity(), + state_equation, surface_tension=SurfaceTensionMorris(surface_tension_coefficient=0.072), reference_particle_spacing=0.1) @@ -493,16 +490,15 @@ exponent=1.0) function run_setup(boundary_kind) - fluid_ic = InitialCondition(coordinates=reshape([0.0, 0.0], 2, 1), + fluid_ic = InitialCondition(; coordinates=reshape([0.0, 0.0], 2, 1), velocity=zeros(2, 1), mass=[particle_volume * fluid_density], - density=[fluid_density], - particle_spacing=particle_spacing) + density=[fluid_density], particle_spacing) - fluid_system = WeaklyCompressibleSPHSystem(fluid_ic, SummationDensity(), + fluid_system = WeaklyCompressibleSPHSystem(fluid_ic; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), state_equation, - smoothing_kernel, - smoothing_length; surface_tension=SurfaceTensionAkinci(surface_tension_coefficient=0.05), reference_particle_spacing=particle_spacing) @@ -510,28 +506,22 @@ boundary_model = BoundaryModelDummyParticles([fluid_density], [particle_volume * fluid_density], AdamiPressureExtrapolation(), - smoothing_kernel, - smoothing_length, - state_equation=state_equation, + smoothing_kernel, smoothing_length; + state_equation, reference_particle_spacing=particle_spacing) boundary_system = if boundary_kind == :wall - wall_ic = InitialCondition(coordinates=boundary_coordinates, + wall_ic = InitialCondition(; coordinates=boundary_coordinates, velocity=zeros(2, 1), mass=[particle_volume * fluid_density], - density=[fluid_density], - particle_spacing=particle_spacing) - WallBoundarySystem(wall_ic, boundary_model, - adhesion_coefficient=adhesion_coefficient) + density=[fluid_density], particle_spacing) + WallBoundarySystem(wall_ic, boundary_model; adhesion_coefficient) else - rigid_ic = InitialCondition(coordinates=boundary_coordinates, + rigid_ic = InitialCondition(; coordinates=boundary_coordinates, velocity=zeros(2, 1), mass=[particle_volume * rigid_density], - density=[rigid_density], - particle_spacing=particle_spacing) - RigidBodySystem(rigid_ic; - boundary_model=boundary_model, - adhesion_coefficient=adhesion_coefficient) + density=[rigid_density], particle_spacing) + RigidBodySystem(rigid_ic; boundary_model, adhesion_coefficient) end semi = Semidiscretization(fluid_system, boundary_system) @@ -595,33 +585,30 @@ boundary_model = BoundaryModelDummyParticles(fill(fluid_density, 2), fill(particle_volume * fluid_density, - 2), - AdamiPressureExtrapolation(), - smoothing_kernel, - smoothing_length, - state_equation=state_equation, + 2), AdamiPressureExtrapolation(), + smoothing_kernel, smoothing_length; + state_equation, reference_particle_spacing=particle_spacing) function run_setup(fluid_positions) - rigid_ic = InitialCondition(coordinates=[-0.5 0.5 - 0.0 0.0], + rigid_ic = InitialCondition(; coordinates=[-0.5 0.5 + 0.0 0.0], velocity=zeros(2, 2), mass=fill(particle_volume * rigid_density, 2), - density=fill(rigid_density, 2), - particle_spacing=particle_spacing) - rigid_system = RigidBodySystem(rigid_ic; - boundary_model=boundary_model, + density=fill(rigid_density, 2), particle_spacing) + rigid_system = RigidBodySystem(rigid_ic; boundary_model, acceleration=(0.0, 0.0)) fluid_systems = map(fluid_positions) do position - fluid_ic = InitialCondition(coordinates=reshape(collect(position), 2, 1), + fluid_ic = InitialCondition(; coordinates=reshape(collect(position), 2, 1), velocity=zeros(2, 1), mass=[particle_volume * fluid_density], - density=[fluid_density], - particle_spacing=particle_spacing) + density=[fluid_density], particle_spacing) - WeaklyCompressibleSPHSystem(fluid_ic, SummationDensity(), state_equation, - smoothing_kernel, smoothing_length) + WeaklyCompressibleSPHSystem(fluid_ic; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) end semi = Semidiscretization(fluid_systems..., rigid_system) @@ -671,43 +658,34 @@ boundary_model = BoundaryModelDummyParticles([fluid_density], [particle_volume * fluid_density], AdamiPressureExtrapolation(), - smoothing_kernel, - smoothing_length, - state_equation=state_equation, + smoothing_kernel, smoothing_length; + state_equation, reference_particle_spacing=particle_spacing) - rigid_ic = InitialCondition(coordinates=reshape([0.0, 0.0], 2, 1), + rigid_ic = InitialCondition(; coordinates=reshape([0.0, 0.0], 2, 1), velocity=zeros(2, 1), mass=[particle_volume * rigid_density], - density=[rigid_density], - particle_spacing=particle_spacing) - rigid_system = RigidBodySystem(rigid_ic; - boundary_model=boundary_model, - acceleration=(0.0, 0.0)) + density=[rigid_density], particle_spacing) + rigid_system = RigidBodySystem(rigid_ic; boundary_model, acceleration=(0.0, 0.0)) - open_boundary_ic = InitialCondition(coordinates=reshape([1.5, 0.0], 2, 1), + open_boundary_ic = InitialCondition(; coordinates=reshape([1.5, 0.0], 2, 1), velocity=zeros(2, 1), mass=[particle_volume * fluid_density], - density=[fluid_density], - particle_spacing=particle_spacing) + density=[fluid_density], particle_spacing) - fluid_support_ic = InitialCondition(coordinates=reshape([10.0, 10.0], 2, 1), + fluid_support_ic = InitialCondition(; coordinates=reshape([10.0, 10.0], 2, 1), velocity=zeros(2, 1), mass=[particle_volume * fluid_density], - density=[fluid_density], - particle_spacing=particle_spacing) - fluid_system = WeaklyCompressibleSPHSystem(fluid_support_ic, SummationDensity(), - state_equation, - smoothing_kernel, - smoothing_length) + density=[fluid_density], particle_spacing) + fluid_system = WeaklyCompressibleSPHSystem(fluid_support_ic; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) boundary_face = ([2.0, -0.5], [2.0, 0.5]) - zone = BoundaryZone(; boundary_face, face_normal=(1.0, 0.0), - density=fluid_density, - particle_spacing=particle_spacing, - initial_condition=open_boundary_ic, - open_boundary_layers=1, - boundary_type=InFlow()) + zone = BoundaryZone(; boundary_face, face_normal=(1.0, 0.0), density=fluid_density, + particle_spacing, initial_condition=open_boundary_ic, + open_boundary_layers=1, boundary_type=InFlow()) open_boundary_system = OpenBoundarySystem(zone; fluid_system, boundary_model=BoundaryModelDynamicalPressureZhang(), @@ -963,20 +941,13 @@ @test_throws ArgumentError RigidContactModel(; normal_stiffness=1.0, contact_distance=-1.0) - rigid_system = RigidBodySystem(rigid_ic; - acceleration=(0.0, 0.0), - contact_model=contact_model) - rigid_system_with_boundary = RigidBodySystem(rigid_ic; - acceleration=(0.0, 0.0), - boundary_model=boundary_model, - contact_model=contact_model) - rigid_system_custom_manifolds = RigidBodySystem(rigid_ic; - acceleration=(0.0, 0.0), - contact_model=contact_model, - max_manifolds=3) - rigid_system_without_contact = RigidBodySystem(rigid_ic; - acceleration=(0.0, 0.0), - boundary_model=boundary_model) + rigid_system = RigidBodySystem(rigid_ic; acceleration=(0.0, 0.0), contact_model) + rigid_system_with_boundary = RigidBodySystem(rigid_ic; acceleration=(0.0, 0.0), + boundary_model, contact_model) + rigid_system_custom_manifolds = RigidBodySystem(rigid_ic; acceleration=(0.0, 0.0), + contact_model, max_manifolds=3) + rigid_system_without_contact = RigidBodySystem(rigid_ic; acceleration=(0.0, 0.0), + boundary_model) @test haskey(rigid_system.cache, :contact_manifold_count) @test rigid_system.contact_model.normal_stiffness ≈ contact_model.normal_stiffness @test rigid_system.contact_model.normal_damping ≈ contact_model.normal_damping @@ -1000,9 +971,7 @@ @test iszero(TrixiParticles.compact_support(boundary_system, rigid_system)) @test iszero(TrixiParticles.compact_support(rigid_system_without_contact, boundary_system)) - @test_throws ArgumentError RigidBodySystem(rigid_ic; - contact_model=contact_model, - max_manifolds=0) + @test_throws ArgumentError RigidBodySystem(rigid_ic; contact_model, max_manifolds=0) system_meta_data = Dict{String, Any}() TrixiParticles.add_system_data!(system_meta_data, rigid_system) @@ -1024,9 +993,8 @@ SummationDensity(), smoothing_kernel, smoothing_length) - kick_rigid_system = RigidBodySystem(rigid_ic; - acceleration=(0.0, 0.0), - contact_model=contact_model) + kick_rigid_system = RigidBodySystem(rigid_ic; acceleration=(0.0, 0.0), + contact_model) kick_boundary_system = WallBoundarySystem(boundary_ic, kick_boundary_model) kick_semi = Semidiscretization(kick_rigid_system, kick_boundary_system) kick_ode = semidiscretize(kick_semi, (0.0, 0.01)) @@ -1090,9 +1058,8 @@ 0.04) short_support_boundary = WallBoundarySystem(boundary_ic, short_support_boundary_model) - far_rigid_system = RigidBodySystem(far_rigid_ic; - acceleration=(0.0, 0.0), - contact_model=contact_model) + far_rigid_system = RigidBodySystem(far_rigid_ic; acceleration=(0.0, 0.0), + contact_model) short_support_semi = Semidiscretization(far_rigid_system, short_support_boundary) short_support_ode = semidiscretize(short_support_semi, (0.0, 0.01)) short_support_v_ode, short_support_u_ode = short_support_ode.u0.x diff --git a/test/systems/tlsph_system.jl b/test/systems/tlsph_system.jl index 8cb261f2d2..c98e8d17d9 100644 --- a/test/systems/tlsph_system.jl +++ b/test/systems/tlsph_system.jl @@ -23,9 +23,9 @@ initial_condition = InitialCondition(; coordinates, mass, density=material_densities) - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, E, nu, - boundary_model=boundary_model) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu, boundary_model) @test system isa TotalLagrangianSPHSystem @test ndims(system) == NDIMS @@ -62,9 +62,9 @@ initial_condition = InitialCondition(; coordinates, mass, density=material_densities) - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, E, nu, - boundary_model=boundary_model) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu, boundary_model) show_compact = "TotalLagrangianSPHSystem{2}(Val{:smoothing_kernel}(), " * "[0.0, 0.0], Val{:boundary_model}(), nothing, nothing) with 2 particles" @@ -88,9 +88,9 @@ E = [1.2, 3.4] nu = [0.2, 0.4] - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, E, nu, - boundary_model=boundary_model) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu, boundary_model) show_box = """ ┌──────────────────────────────────────────────────────────────────────────────────────────────────┐ @@ -222,8 +222,9 @@ smoothing_length) initial_condition = InitialCondition(; coordinates, mass, density) - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, 1.0, 1.0) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=1.0, + poisson_ratio=1.0) semi = DummySemidiscretization() TrixiParticles.initialize!(system, semi) @@ -316,9 +317,9 @@ initial_condition = InitialCondition(; coordinates, mass, density=material_densities) - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, E, nu, - boundary_model=boundary_model) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu, boundary_model) u0 = zeros(TrixiParticles.u_nvariables(system), TrixiParticles.n_integrated_particles(system)) @@ -343,9 +344,9 @@ initial_condition = InitialCondition(; coordinates, velocity, mass, density=material_densities) - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, E, nu, - boundary_model=boundary_model) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu, boundary_model) v0 = zeros(TrixiParticles.v_nvariables(system), TrixiParticles.n_integrated_particles(system)) @@ -367,8 +368,9 @@ initial_condition = InitialCondition(; coordinates, velocity, mass, density=material_densities) - system = TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, - smoothing_length, E, nu) + system = TotalLagrangianSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, young_modulus=E, + poisson_ratio=nu) # Initialize deformation_grad and pk1_rho2 with arbitrary values for particle in TrixiParticles.eachparticle(system) diff --git a/test/systems/wcsph_system.jl b/test/systems/wcsph_system.jl index 7c034e7757..89217f1d84 100644 --- a/test/systems/wcsph_system.jl +++ b/test/systems/wcsph_system.jl @@ -30,10 +30,11 @@ smoothing_length = 0.362 initial_condition = InitialCondition(; coordinates, mass, density) - system = WeaklyCompressibleSPHSystem(initial_condition, + system = WeaklyCompressibleSPHSystem(initial_condition; + smoothing_kernel, + smoothing_length, density_calculator, - state_equation, smoothing_kernel, - smoothing_length) + state_equation) @test system isa WeaklyCompressibleSPHSystem{NDIMS} @test system.initial_condition == initial_condition @@ -44,25 +45,24 @@ @test TrixiParticles.initial_smoothing_length(system) == smoothing_length @test system.viscosity === nothing @test system.acceleration == [0.0 for _ in 1:NDIMS] - if density_calculator isa SummationDensity @test length(system.cache.density) == size(coordinates, 2) end error_str1 = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str1) WeaklyCompressibleSPHSystem(initial_condition, - density_calculator, - state_equation, + @test_throws ArgumentError(error_str1) WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, smoothing_length, + density_calculator, + state_equation, acceleration=(0.0)) error_str2 = "smoothing kernel dimensionality must be $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str2) WeaklyCompressibleSPHSystem(initial_condition, + @test_throws ArgumentError(error_str2) WeaklyCompressibleSPHSystem(initial_condition; + smoothing_kernel=smoothing_kernel2, + smoothing_length, density_calculator, - state_equation, - smoothing_kernel2, - smoothing_length) + state_equation) end end end @@ -121,17 +121,18 @@ if density_calculator isa ContinuityDensity && corr isa ShepardKernelCorrection error_str = "`ShepardKernelCorrection` cannot be used with `ContinuityDensity`" - @test_throws ArgumentError(error_str) WeaklyCompressibleSPHSystem(setup, - density_calculator, - state_equation, + @test_throws ArgumentError(error_str) WeaklyCompressibleSPHSystem(setup; smoothing_kernel, smoothing_length, + density_calculator, + state_equation, correction=corr) continue end - system = WeaklyCompressibleSPHSystem(setup, density_calculator, - state_equation, smoothing_kernel, + system = WeaklyCompressibleSPHSystem(setup; smoothing_kernel, smoothing_length, + density_calculator, + state_equation, correction=corr) @test system isa WeaklyCompressibleSPHSystem{NDIMS} @@ -169,11 +170,11 @@ density_calculators error_str = "`acceleration` must be of length $NDIMS for a $(NDIMS)D problem" - @test_throws ArgumentError(error_str) WeaklyCompressibleSPHSystem(setup, - density_calculator, - state_equation, + @test_throws ArgumentError(error_str) WeaklyCompressibleSPHSystem(setup; smoothing_kernel, smoothing_length, + density_calculator, + state_equation, acceleration=(0.0)) end end @@ -193,11 +194,9 @@ density_diffusion = Val(:density_diffusion) initial_condition = InitialCondition(; coordinates, mass, density) - system = WeaklyCompressibleSPHSystem(initial_condition, - density_calculator, - state_equation, smoothing_kernel, - smoothing_length, - density_diffusion=density_diffusion) + system = WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, density_calculator, + state_equation, density_diffusion) show_compact = "WeaklyCompressibleSPHSystem{2}(SummationDensity(), nothing, Val{:state_equation}(), Val{:smoothing_kernel}(), nothing, Val{:density_diffusion}(), nothing, nothing, nothing, [0.0, 0.0], nothing) with 2 particles" @test repr(system) == show_compact @@ -232,10 +231,9 @@ density_calculator = SummationDensity() initial_condition = InitialCondition(; coordinates, mass, density) - system = WeaklyCompressibleSPHSystem(initial_condition, - density_calculator, - state_equation, smoothing_kernel, - smoothing_length) + system = WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, density_calculator, + state_equation) u0 = zeros(TrixiParticles.u_nvariables(system), TrixiParticles.n_integrated_particles(system)) @@ -257,10 +255,10 @@ initial_condition = InitialCondition(; coordinates, velocity, mass, density) # SummationDensity - system = WeaklyCompressibleSPHSystem(initial_condition, - SummationDensity(), - state_equation, smoothing_kernel, - smoothing_length) + system = WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, + density_calculator=SummationDensity(), + state_equation) v0 = zeros(TrixiParticles.v_nvariables(system), TrixiParticles.n_integrated_particles(system)) @@ -275,10 +273,10 @@ @test TrixiParticles.current_pressure(v0, system) == system.pressure # ContinuityDensity - system = WeaklyCompressibleSPHSystem(initial_condition, - ContinuityDensity(), - state_equation, smoothing_kernel, - smoothing_length) + system = WeaklyCompressibleSPHSystem(initial_condition; smoothing_kernel, + smoothing_length, + density_calculator=ContinuityDensity(), + state_equation) v0 = zeros(TrixiParticles.v_nvariables(system), TrixiParticles.n_integrated_particles(system)) diff --git a/test/test_util.jl b/test/test_util.jl index 12ead6e7a9..dc1a102753 100644 --- a/test/test_util.jl +++ b/test/test_util.jl @@ -1,6 +1,8 @@ using Test using TrixiTest: @trixi_test_nowarn using TrixiParticles +# Required to load the extension that provides `SymplecticPositionVerlet`. +using OrdinaryDiffEqSymplecticRK using TrixiParticles: PointNeighbors using TrixiParticles.Adapt using LinearAlgebra diff --git a/test/validation/validation.jl b/test/validation/validation.jl index 01a376dbea..efe3bedbb6 100644 --- a/test/validation/validation.jl +++ b/test/validation/validation.jl @@ -100,9 +100,6 @@ n_particles_plate_y=3) [ r"┌ Info: The desired tank length in y-direction.*\n", r"└ New tank length in y-direction is set to.*\n", - r"┌ Warning: keyword `n_clamped_particles` is deprecated.*\n", - r"│ caller = ip:0x0\n", - r"└ @ Core :-1\n", r"\[ Info: To create the self-interaction neighborhood search.*\n" ] diff --git a/validation/dam_break_2d/setup_marrone_2011.jl b/validation/dam_break_2d/setup_marrone_2011.jl index ca4a88b7c3..9d4e5a2ef8 100644 --- a/validation/dam_break_2d/setup_marrone_2011.jl +++ b/validation/dam_break_2d/setup_marrone_2011.jl @@ -78,11 +78,10 @@ if use_edac state_equation = nothing tank_edac = RectangularTank(particle_spacing, initial_fluid_size, tank_size, - fluid_density, - n_layers=boundary_layers, spacing_ratio=spacing_ratio, + fluid_density; n_layers=boundary_layers, spacing_ratio, acceleration=(0.0, -gravity), state_equation=nothing) - fluid_system = EntropicallyDampedSPHSystem(tank_edac.fluid, smoothing_kernel, + fluid_system = EntropicallyDampedSPHSystem(tank_edac.fluid; smoothing_kernel, smoothing_length, sound_speed, viscosity=viscosity_fluid, density_calculator=ContinuityDensity(), @@ -114,12 +113,9 @@ saving_paper = SolutionSavingCallback(save_times=[0.0, 1.5, 2.36, 3.0, 5.7, 6.45 sqrt(gravity / H), prefix="marrone_times") -trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"), - fluid_particle_spacing=particle_spacing, - boundary_density_calculator=boundary_density_calculator, - state_equation=state_equation, - solution_prefix="validation_" * method * "_" * formatted_string, - tspan=tspan, fluid_system=fluid_system, - update_strategy=nothing, - extra_callback=postprocessing_cb, +trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "dam_break_2d.jl"); + fluid_particle_spacing=particle_spacing, boundary_density_calculator, + state_equation, + solution_prefix="validation_" * method * "_" * formatted_string, tspan, + fluid_system, update_strategy=nothing, extra_callback=postprocessing_cb, extra_callback2=saving_paper) diff --git a/validation/dam_break_2d/validation_dam_break_2d.jl b/validation/dam_break_2d/validation_dam_break_2d.jl index 22f563e245..52c78a26ad 100644 --- a/validation/dam_break_2d/validation_dam_break_2d.jl +++ b/validation/dam_break_2d/validation_dam_break_2d.jl @@ -27,14 +27,12 @@ update_strategy = nothing # ========================================================================================== # ==== WCSPH simulation +# `sound_speed`, `alpha`, and `tspan` are used by De Courcy et al. (2024). trixi_include(@__MODULE__, - joinpath(validation_dir(), "dam_break_2d", - "setup_marrone_2011.jl"), - use_edac=false, update_strategy=update_strategy, - particles_per_height=resolution, - sound_speed=50 * sqrt(9.81 * 0.6), # This is used by De Courcy et al. (2024) - alpha=0.01, # This is used by De Courcy et al. (2024) - tspan=(0.0, 7 / sqrt(9.81 / 0.6))) # This is used by De Courcy et al. (2024) + joinpath(validation_dir(), "dam_break_2d", "setup_marrone_2011.jl"); + use_edac=false, update_strategy, particles_per_height=resolution, + sound_speed=50 * sqrt(9.81 * 0.6), alpha=0.01, + tspan=(0.0, 7 / sqrt(9.81 / 0.6))) reference_file_wcsph_name = joinpath(validation_dir(), "dam_break_2d", "validation_reference_wcsph_$formatted_string.json") @@ -56,14 +54,12 @@ error_wcsph_P2 = interpolated_mse(reference_data["pressure_P2_fluid_1"]["time"], # ========================================================================================== # ==== EDAC simulation +# `sound_speed`, `alpha`, and `tspan` are used by De Courcy et al. (2024). trixi_include(@__MODULE__, - joinpath(validation_dir(), "dam_break_2d", - "setup_marrone_2011.jl"), - use_edac=true, update_strategy=update_strategy, - particles_per_height=resolution, - sound_speed=50 * sqrt(9.81 * 0.6), # This is used by De Courcy et al. (2024) - alpha=0.01, # This is used by De Courcy et al. (2024) - tspan=(0.0, 7 / sqrt(9.81 / 0.6))) # This is used by De Courcy et al. (2024) + joinpath(validation_dir(), "dam_break_2d", "setup_marrone_2011.jl"); + use_edac=true, update_strategy, particles_per_height=resolution, + sound_speed=50 * sqrt(9.81 * 0.6), alpha=0.01, + tspan=(0.0, 7 / sqrt(9.81 / 0.6))) reference_file_edac_name = joinpath(validation_dir(), "dam_break_2d", "validation_reference_edac_$formatted_string.json") diff --git a/validation/hydrostatic_water_column_2d/validation.jl b/validation/hydrostatic_water_column_2d/validation.jl index 81fe978cc8..8982e22585 100644 --- a/validation/hydrostatic_water_column_2d/validation.jl +++ b/validation/hydrostatic_water_column_2d/validation.jl @@ -11,7 +11,7 @@ include("../validation_util.jl") # ========================================================================================== using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK using JSON # ========================================================================================== @@ -51,12 +51,9 @@ function run_simulation(method; n_particles_plate_y, tspan) kinetic_energy) trixi_include(@__MODULE__, - joinpath(examples_dir(), "fsi", "hydrostatic_water_column_2d.jl"), - use_edac=method.use_edac, - n_particles_plate_y=n_particles_plate_y, - update_strategy=SerialUpdate(), - tspan=tspan, - prefix=pp_filename, + joinpath(examples_dir(), "fsi", "hydrostatic_water_column_2d.jl"); + use_edac=method.use_edac, n_particles_plate_y, + update_strategy=SerialUpdate(), tspan, prefix=pp_filename, extra_callback=pp) # `@invokelatest` is required with Julia 1.12 @@ -69,9 +66,7 @@ errors = Dict{Symbol, Tuple{Float64, Float64}}() for method in methods pp_filename, - _ = run_simulation(method; - n_particles_plate_y=n_particles_plate_y, - tspan=tspan) + _ = run_simulation(method; n_particles_plate_y, tspan) # Load the run JSON file and add the analytical solution as a single point. run_filename = joinpath("out", pp_filename * ".json") diff --git a/validation/lid_driven_cavity_2d/validation_lid_driven_cavity_2d.jl b/validation/lid_driven_cavity_2d/validation_lid_driven_cavity_2d.jl index b805667d4e..33405f1ef5 100644 --- a/validation/lid_driven_cavity_2d/validation_lid_driven_cavity_2d.jl +++ b/validation/lid_driven_cavity_2d/validation_lid_driven_cavity_2d.jl @@ -51,8 +51,8 @@ function interpolated_velocity(system::TrixiParticles.AbstractFluidSystem, TrixiParticles.CSV.write(output_directory * "/interpolated_velocities.csv", df) else - df = TrixiParticles.DataFrame(pos=collect(LinRange(0.0, 1.0, n_particles_xy)), - counter=1, vy_y=vy_y, vy_x=vy_x, vx_y=vx_y, vx_x=vx_x) + df = TrixiParticles.DataFrame(; pos=collect(LinRange(0.0, 1.0, n_particles_xy)), + counter=1, vy_y, vy_x, vx_y, vx_x) TrixiParticles.CSV.write(output_directory * "/interpolated_velocities.csv", df) CAPTURE_STARTED[] = true @@ -74,20 +74,17 @@ for reynolds_number in reynolds_numbers, name_density_calculator, "validation_run_lid_driven_cavity_2d_nparticles_$(n_particles_xy)x$(n_particles_xy)_Re_$Re") - saving_callback = SolutionSavingCallback(dt=0.02, output_directory=output_directory) + saving_callback = SolutionSavingCallback(; dt=0.02, output_directory) CAPTURE_STARTED[] = false - pp_callback = PostprocessCallback(; dt=0.02, - interpolated_velocity=interpolated_velocity, + pp_callback = PostprocessCallback(; dt=0.02, interpolated_velocity, filename="interpolated_velocities", write_file_interval=0) # Import variables into scope - trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "lid_driven_cavity_2d.jl"), - wcsph=wcsph, density_calculator=density_calculator, - saving_callback=saving_callback, tspan=tspan, pp_callback=pp_callback, - particle_spacing=particle_spacing, reynolds_number=reynolds_number) + trixi_include(@__MODULE__, joinpath(examples_dir(), "fluid", "lid_driven_cavity_2d.jl"); + wcsph, density_calculator, saving_callback, tspan, pp_callback, + particle_spacing, reynolds_number) file = joinpath(output_directory, "interpolated_velocities.csv") diff --git a/validation/oscillating_beam_2d/plot_oscillating_beam_results.jl b/validation/oscillating_beam_2d/plot_oscillating_beam_results.jl index 72de1a3013..1e24c633f0 100644 --- a/validation/oscillating_beam_2d/plot_oscillating_beam_results.jl +++ b/validation/oscillating_beam_2d/plot_oscillating_beam_results.jl @@ -63,7 +63,7 @@ for file_name in input_files interpolated_mse(ref.time, ref.Uy, data["time"], displacements) label = "$label_prefix dp = $(@sprintf("%.8f", particle_spacing_)) mse=$(@sprintf("%.8f", mse_results))" - lines!(ax, times, displacements, label=label) + lines!(ax, times, displacements; label) end end end diff --git a/validation/oscillating_beam_2d/validation_oscillating_beam_2d.jl b/validation/oscillating_beam_2d/validation_oscillating_beam_2d.jl index f5f96111ca..fa9c6fdc2d 100644 --- a/validation/oscillating_beam_2d/validation_oscillating_beam_2d.jl +++ b/validation/oscillating_beam_2d/validation_oscillating_beam_2d.jl @@ -12,7 +12,7 @@ include("../validation_util.jl") using TrixiParticles -using OrdinaryDiffEq +using OrdinaryDiffEqLowStorageRK using JSON tspan = (0, 10) @@ -25,9 +25,8 @@ tspan = (0, 10) n_particles_beam_y = 5 # Overwrite `sol` assignment to skip time integration -trixi_include(@__MODULE__, - joinpath(examples_dir(), "structure", "oscillating_beam_2d.jl"), - n_particles_y=n_particles_beam_y, sol=nothing, tspan=tspan, +trixi_include(@__MODULE__, joinpath(examples_dir(), "structure", "oscillating_beam_2d.jl"); + n_particles_y=n_particles_beam_y, sol=nothing, tspan, penalty_force=PenaltyForceGanzenmueller(alpha=0.01)) pp_callback = PostprocessCallback(; deflection_x, deflection_y, dt=0.01, diff --git a/validation/taylor_green_vortex_2d/validation_taylor_green_vortex_2d.jl b/validation/taylor_green_vortex_2d/validation_taylor_green_vortex_2d.jl index 20292524da..afe2f6cb13 100644 --- a/validation/taylor_green_vortex_2d/validation_taylor_green_vortex_2d.jl +++ b/validation/taylor_green_vortex_2d/validation_taylor_green_vortex_2d.jl @@ -91,22 +91,17 @@ for density_calculator in density_calculators, perturbation in perturb_coordinat output_directory = joinpath("out_tgv", name_density_calculator * name_perturbation, wcsph ? "wcsph" : "edac", "validation_run_taylor_green_vortex_2d_nparticles_$(n_particles_xy)x$(n_particles_xy)") - saving_callback = SolutionSavingCallback(dt=0.02, - output_directory=output_directory, + saving_callback = SolutionSavingCallback(; dt=0.02, output_directory, p_avg=diff_p_loc_p_avg) - pp_callback = PostprocessCallback(; dt=0.02, - L1v=compute_l1v_error, - L1p=compute_l1p_error, - output_directory=output_directory, - filename="errors", - write_csv=true, write_file_interval=1) + pp_callback = PostprocessCallback(; dt=0.02, L1v=compute_l1v_error, + L1p=compute_l1p_error, output_directory, + filename="errors", write_csv=true, + write_file_interval=1) # Import variables into scope trixi_include(@__MODULE__, - joinpath(examples_dir(), "fluid", "taylor_green_vortex_2d.jl"), - density_calculator=density_calculator, - perturb_coordinates=perturbation, wcsph=wcsph, - particle_spacing=particle_spacing, reynolds_number=reynolds_number, - tspan=tspan, saving_callback=saving_callback, pp_callback=pp_callback) + joinpath(examples_dir(), "fluid", "taylor_green_vortex_2d.jl"); + density_calculator, perturb_coordinates=perturbation, wcsph, + particle_spacing, reynolds_number, tspan, saving_callback, pp_callback) end