Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions docs/literate/src/tut_2d_geometry.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# # [Setting up a 2D simulation from geometry files](@id tut_2d_geometry)

# In this tutorial, we build two genuine 2D setups from geometry files:
# 1. a curved pipe, where one geometry file defines the outer wall envelope and a second
# one defines the empty channel cut out of it,
Comment on lines +4 to +5
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also create the curved pipe with RoundSphere(; start_angle, end_angle).
Of course, only if the curvature is a sector of a circle.

# 2. a dam-break basin with a coastline profile, where one geometry file defines the
# filled coastline wall together with the seawall on the right.
#
# For a real 2D setup, we use 2D geometry formats such as `.asc` or `.dxf`.
# STL files are surface meshes and therefore naturally lead to thin 3D setups instead.

# First, we import TrixiParticles.jl together with
# [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl)
# and [Plots.jl](https://docs.juliaplots.org/stable/).
using TrixiParticles
using OrdinaryDiffEq
using Plots

# ## Resolution

# We use the same particle spacing for the fluid and for the wall geometries.
particle_spacing = 0.03
fluid_density = 1000.0
gravity = 9.81
sound_speed = 10.0
state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density,
exponent=7)
nothing # hide

# ## Loading 2D geometry files

# The following helper loads a closed 2D geometry file and samples particles in its interior:
# 1. load the polygon with [`load_geometry`](@ref),
# 2. fill the polygon with [`ComplexShape`](@ref).
#
# This creates a true 2D solid region instead of a hollow shell around the polygon edges.
function solid_from_geometry_file(file; particle_spacing, density)
geometry = load_geometry(file)
solid = ComplexShape(geometry; particle_spacing, density,
grid_offset=0.5particle_spacing)

return (; geometry, solid)
end

# ## A curved pipe from two filled geometries

# The pipe wall is a solid L-shaped region with a channel cut out of it:
# 1. one geometry file describes the outer pipe envelope,
# 2. one geometry file describes the empty channel,
# 3. the `setdiff` operation subtracts the channel from the solid envelope.
pipe_outer_file = pkgdir(TrixiParticles, "examples", "preprocessing", "data",
"curved_pipe_outer_2d.asc")
pipe_channel_file = pkgdir(TrixiParticles, "examples", "preprocessing", "data",
"curved_pipe_channel_2d.asc")

pipe_outer = solid_from_geometry_file(pipe_outer_file; particle_spacing,
density=fluid_density)
pipe_channel = load_geometry(pipe_channel_file)

pipe_setup = (; wall=setdiff(pipe_outer.solid, pipe_channel),
outer_geometry=pipe_outer.geometry,
channel_geometry=pipe_channel)

# ## A dam-break basin with a coastline profile

# In the second setup, a single 2D geometry file defines a filled coastline wall:
# the beach profile on top, a finite wall thickness below it, and the seawall on the right.
coast_file = pkgdir(TrixiParticles, "examples", "preprocessing", "data",
"coastline_profile_2d.asc")
coast = solid_from_geometry_file(coast_file; particle_spacing, density=fluid_density)

# The geometry file gives the coastline bed and the right wall as a solid region.
# We add the left wall explicitly as a rectangular particle block and place a
# 1.5x taller rectangular dam-break water column next to it.
left_wall = RectangularShape(particle_spacing, (5, 50), (0.0, -0.12),
density=fluid_density)
reservoir = RectangularShape(particle_spacing, (28, 42), (0.15, 0.03),
acceleration=(0.0, -gravity),
state_equation=state_equation)
coast_setup = (; geometry=coast.geometry,
wall=union(coast.solid, left_wall),
fluid=setdiff(reservoir, coast.geometry))

p_pipe = plot(pipe_setup.wall, label="wall", title="Curved pipe",
markerstrokewidth=0, markersize=4)
plot!(p_pipe, showaxis=false, aspect_ratio=:equal,
xlims=(-0.03, 1.23), ylims=(-0.03, 1.23))

p_coast = plot(coast_setup.fluid, coast_setup.wall,
labels=["fluid" "wall"], title="Coastline dam break",
markerstrokewidth=0, markersize=3)
plot!(p_coast, showaxis=false, aspect_ratio=:equal,
xlims=(0.0, 2.75), ylims=(-0.15, 1.35))

plot(p_pipe, p_coast, layout=(1, 2), size=(900, 360))
savefig("tut_2d_geometry_plot.png"); # hide
# ![2D geometry based initial conditions](tut_2d_geometry_plot.png)

# ## Building the simulation systems

# To keep the example focused, we continue with the coastline setup.
# From this point on, the simulation setup is the same as in other 2D simulation files.
setup = coast_setup
tspan = (0.0, 0.03)
nothing # hide

# We define the state equation, smoothing kernel, and viscosity for a
# weakly compressible SPH simulation.
smoothing_length = 1.2 * particle_spacing
smoothing_kernel = SchoenbergCubicSplineKernel{2}()
viscosity = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0)

fluid_density_calculator = ContinuityDensity()
density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1)

fluid_system = WeaklyCompressibleSPHSystem(setup.fluid, fluid_density_calculator,
state_equation, smoothing_kernel,
smoothing_length, viscosity=viscosity,
density_diffusion=density_diffusion,
acceleration=(0.0, -gravity))
nothing # hide

# For the wall, we reuse the combined solid wall particles created above.
boundary_model = BoundaryModelDummyParticles(setup.wall.density, setup.wall.mass,
state_equation=state_equation,
AdamiPressureExtrapolation(),
smoothing_kernel, smoothing_length)
boundary_system = WallBoundarySystem(setup.wall, boundary_model)
nothing # hide

# ## Semidiscretization

# With fluid and wall particles defined, we can build the
# [`Semidiscretization`](@ref TrixiParticles.Semidiscretization) exactly as in other tutorials.
semi = Semidiscretization(fluid_system, boundary_system)
ode = semidiscretize(semi, tspan)
nothing # hide

# ## Time integration

# The setup is now complete.
# To start the simulation, run for example
# ```julia
# callbacks = CallbackSet(InfoCallback(interval=10))
# sol = solve(ode, RDPK3SpFSAL35(), save_everystep=false, callback=callbacks)
# ```
# This is the same final step as in [the basic setup tutorial](@ref tut_setup).
callbacks = CallbackSet(InfoCallback(interval=10))
nothing # hide

sol = solve(ode, RDPK3SpFSAL35(), save_everystep=false, callback=callbacks) #!md

# For more accurate body-fitted particles around sharper features, you can also
# apply the [particle packing workflow](@ref tut_packing) to the 2D geometry files
# before starting the simulation.
4 changes: 4 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Literate.markdown(joinpath("docs", "literate", "src", "tut_custom_kernel.jl"),
joinpath("docs", "src", "tutorials"))
Literate.markdown(joinpath("docs", "literate", "src", "tut_packing.jl"),
joinpath("docs", "src", "tutorials"))
Literate.markdown(joinpath("docs", "literate", "src", "tut_2d_geometry.jl"),
joinpath("docs", "src", "tutorials"))

copy_file("AUTHORS.md",
"in the [LICENSE.md](LICENSE.md) file" => "under [License](@ref)")
Expand Down Expand Up @@ -87,6 +89,8 @@ makedocs(sitename="TrixiParticles.jl",
"tut_custom_kernel.md")
],
"Preprocessing" => [
"Setting up a 2D simulation from geometry files" => joinpath("tutorials",
"tut_2d_geometry.md"),
"Particle packing tutorial" => joinpath("tutorials",
"tut_packing.md")
]
Expand Down
70 changes: 65 additions & 5 deletions docs/src/tutorial.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,68 @@
# Tutorials

## General
- [Setting up your simulation from scratch](tutorials/tut_setup.md)
- [Modifying or extending components of TrixiParticles.jl within a simulation file](tutorials/tut_custom_kernel.md)
Choose a tutorial based on the task in front of you.

## Preprocessing
- [Particle packing tutorial](tutorials/tut_packing.md)
> New to TrixiParticles.jl? Start with [Setting up your simulation from scratch](tutorials/tut_setup.md).

## Recommended Path

1. [Setting up your simulation from scratch](tutorials/tut_setup.md): learn the structure of a simulation file and run a complete WCSPH example.
2. [Modifying or extending components of TrixiParticles.jl within a simulation file](tutorials/tut_custom_kernel.md): replace selected parts of an existing setup without cloning the package.
3. [Setting up a 2D simulation from geometry files](tutorials/tut_2d_geometry.md): load 2D geometry files, turn them into filled wall regions, and combine them with standard 2D fluid blocks.
4. [Particle packing tutorial](tutorials/tut_packing.md): build a body-fitted particle configuration for complex geometries.

## Tutorials

### [Setting up your simulation from scratch](tutorials/tut_setup.md)

```@raw html
<img src="../tutorials/tut_setup_plot_tank.png"
alt="Rectangular tank setup used in the first tutorial"
style="max-width: 360px; width: 100%; border-radius: 12px;" />
```

Build a complete weakly compressible SPH dam break setup from particle spacing through semidiscretization, callbacks, and time integration.

- Focus: initial conditions, systems, semidiscretization, callbacks
- Choose this if: you want the full workflow from a minimal example

### [Modifying or extending components of TrixiParticles.jl within a simulation file](tutorials/tut_custom_kernel.md)

```@raw html
<img src="../tutorials/tut_custom_kernel_plot2.png"
alt="Kernel comparison plot from the custom kernel tutorial"
style="max-width: 360px; width: 100%; border-radius: 12px;" />
```

Start from an existing simulation and replace pieces such as the smoothing kernel directly in the file you run.

- Focus: `trixi_include`, custom kernels, rapid iteration
- Choose this if: you want to prototype changes without rewriting a full setup

### [Setting up a 2D simulation from geometry files](tutorials/tut_2d_geometry.md)

```@raw html
<img src="../tutorials/tut_2d_geometry_plot.png"
alt="2D pipe and coastline geometries converted to wall and fluid particles"
style="max-width: 360px; width: 100%; border-radius: 12px;" />
```

Load 2D geometry files, fill them with particles using `ComplexShape`, and build genuine 2D setups such as a curved pipe and a coastline dam break.

- Focus: `load_geometry`, `ComplexShape`, `setdiff`, 2D `Polygon`s
- Choose this if: you want a true 2D setup from line-based geometry data

### [Particle packing tutorial](tutorials/tut_packing.md)

```@raw html
<img src="https://github.com/user-attachments/assets/0f7aba29-3cf7-4ec1-8c95-841e72fe620d"
alt="Packed particle configuration for a complex geometry"
style="max-width: 360px; width: 100%; border-radius: 12px;" />
```

Go from a geometry file to a packed particle distribution using signed distance fields together with boundary and interior sampling.

- Focus: geometry import, signed distance fields, boundary sampling, `ParticlePackingSystem`
- Choose this if: you need body-fitted particles for complex shapes

See also [Getting started](getting_started.md) and [Examples](examples.md).
20 changes: 20 additions & 0 deletions examples/preprocessing/data/coastline_profile_2d.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ASCII
0.18 -0.12 0
2.68 -0.12 0
2.68 1.08 0
2.62 0.66 0
2.53 0.52 0
2.42 0.40 0
2.30 0.42 0
2.18 0.33 0
2.05 0.24 0
1.92 0.26 0
1.78 0.18 0
1.62 0.11 0
1.46 0.14 0
1.28 0.06 0
1.05 0.02 0
0.82 0.05 0
0.55 0.03 0
0.18 0.03 0
0.18 -0.12 0
20 changes: 20 additions & 0 deletions examples/preprocessing/data/curved_pipe_channel_2d.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ASCII
0.00 0.12 0
0.60 0.12 0
0.72423 0.13646 0
0.84000 0.18431 0
0.93941 0.26059 0
1.01569 0.36000 0
1.06354 0.47577 0
1.08 0.60 0
1.08 1.20 0
0.72 1.20 0
0.72 0.60 0
0.71591 0.56894 0
0.70392 0.54000 0
0.68485 0.51515 0
0.66000 0.49608 0
0.63106 0.48409 0
0.60 0.48 0
0.00 0.48 0
0.00 0.12 0
14 changes: 14 additions & 0 deletions examples/preprocessing/data/curved_pipe_outer_2d.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# ASCII
0.00 0.00 0
0.60 0.00 0
0.75529 0.02044 0
0.90000 0.08038 0
1.02426 0.17574 0
1.11962 0.30000 0
1.17956 0.44471 0
1.20 0.60 0
1.20 1.20 0
0.60 1.20 0
0.60 0.60 0
0.00 0.60 0
0.00 0.00 0
Loading