Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
93 changes: 93 additions & 0 deletions docs/literate/src/tut_visualization.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# # [Visualizing particle data with Plots.jl](@id tut_visualization)
Comment thread
efaulhaber marked this conversation as resolved.

# In this tutorial, we run the two-dimensional vortex street from
# [`examples/fluid/vortex_street_2d.jl`](https://github.com/trixi-framework/TrixiParticles.jl/blob/main/examples/fluid/vortex_street_2d.jl)
# and visualize the particle data with [`Plots.jl`](https://github.com/juliaplots/plots.jl).

using TrixiParticles
using Plots
#src # Reset GR's process-wide color table, which can be exhausted by earlier tutorials.
Plots.closeall() # hide

# The example defines the particle spacing as `particle_spacing_factor * cylinder_diameter`.
# We deliberately use a very coarse particle resolution. This makes the distinction between
# the discrete particles and the interpolated field in the next section clear.
# To remove visual clutter, we disable the info callback.
# Since we visualize with Plots.jl, we also disable the saving callback.
trixi_include(@__MODULE__,
joinpath(examples_dir(), "fluid", "vortex_street_2d.jl");
particle_spacing_factor=0.2,
info_callback=nothing, saving_callback=nothing);
nothing # hide

# ## Visualizing discrete particles

# SPH stores the solution on moving particles. The standard plotting recipe provides the
# quickest way to inspect their distribution at the final time. We color the fluid particles
# by the magnitude of the velocity stored on each particle.
v_ode, _ = sol.u[end].x
Comment thread
efaulhaber marked this conversation as resolved.
v_fluid = TrixiParticles.wrap_v(v_ode, fluid_system, semi)

active_particles = TrixiParticles.eachparticle(fluid_system)
particle_velocity = TrixiParticles.current_velocity(v_fluid,
fluid_system)[:, active_particles]
particle_velocity_magnitude = vec(sqrt.(sum(abs2, particle_velocity; dims=1)))

particle_plot = plot(sol; zcolor=particle_velocity_magnitude, color=:viridis,
Comment thread
efaulhaber marked this conversation as resolved.
Outdated
xlims=(0.25, 1.8), ylims=(0.1, 0.9), legend=false,
xlabel="x", ylabel="y", colorbar=true, colorbar_title="|v|",
size=(900, 450))
plot!(particle_plot; dpi=200) # hide
savefig(particle_plot, "tut_visualization_particles.png") # hide
nothing # hide

# ![Particle visualization of the vortex street](tut_visualization_particles.png)

# ## Interpolating particle data onto a regular grid

# Smoothed particle hydrodynamics (SPH) represents a continuous (smoothed) field
# by a discrete set of particles. While visualizing individual particles is straightforward
# and often sufficient, in order to visualize the actual field approximation,
# the particle data must be interpolated.
#
# Importantly, interpolation does not add physical resolution: features that are not resolved
# by the particles cannot be recovered by choosing a finer interpolation grid.
# It simply visualizes the SPH approximation instead of only the interpolation points.
Comment thread
efaulhaber marked this conversation as resolved.

# [`interpolate_plane_2d`](@ref) constructs regularly spaced sample points between two corners
# and uses the SPH kernel to reconstruct the requested fields there. The interpolation spacing
# is one quarter of the particle spacing, so the plot contains many more pixels than
# the simulation contains particles.
interpolation_min = [0.0, 0.0]
interpolation_max = domain_size
interpolation_spacing = particle_spacing / 4

interpolated = interpolate_plane_2d(interpolation_min, interpolation_max,
interpolation_spacing, semi, fluid_system, sol)
interpolated_velocity_magnitude = vec(sqrt.(sum(abs2, interpolated.velocity; dims=1)))
nothing # hide

# The returned named tuple also contains `pressure`, `density`, `neighbor_count`, and
# `computed_density`. Here we visualize the magnitude of the interpolated velocity.
interpolated_plot = scatter(interpolated.point_coords[1, :],
interpolated.point_coords[2, :];
marker_z=interpolated_velocity_magnitude,
color=:viridis,
marker=:square, markerstrokewidth=0, markersize=2.5,
aspect_ratio=:equal, size=(900, 450),
xlims=(0.25, 1.8), ylims=(0.1, 0.9), xlabel="x", ylabel="y",
label=nothing, colorbar_title="|v|")
plot!(interpolated_plot; dpi=200) # hide
savefig(interpolated_plot, "tut_visualization_interpolated_velocity.png") # hide
nothing # hide

# ![Interpolated velocity magnitude](tut_visualization_interpolated_velocity.png)

# Compared with the visibly discrete particle distribution, the interpolated field shows
Comment thread
efaulhaber marked this conversation as resolved.
# much more detail, representing the continuous SPH approximation of the solution.

# To write the same reconstruction as a VTI image for ParaView, replace the interpolation call
# above with [`interpolate_plane_2d_vtk`](@ref):
interpolate_plane_2d_vtk(interpolation_min, interpolation_max, interpolation_spacing,
Comment thread
efaulhaber marked this conversation as resolved.
semi, fluid_system, sol; filename="vortex_street_velocity")
nothing # hide
18 changes: 13 additions & 5 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@ function copy_file(filename, replaces...;
write(new_file, content)
end

tutorials_output_dir = joinpath("docs", "src", "tutorials")
rm(tutorials_output_dir; recursive=true, force=true)
mkpath(tutorials_output_dir)

Literate.markdown(joinpath("docs", "literate", "src", "tut_setup.jl"),
joinpath("docs", "src", "tutorials"))
tutorials_output_dir)
Literate.markdown(joinpath("docs", "literate", "src", "tut_custom_kernel.jl"),
joinpath("docs", "src", "tutorials"))
tutorials_output_dir)
Literate.markdown(joinpath("docs", "literate", "src", "tut_rigid_body_fsi.jl"),
joinpath("docs", "src", "tutorials"))
tutorials_output_dir)
Literate.markdown(joinpath("docs", "literate", "src", "tut_packing.jl"),
joinpath("docs", "src", "tutorials"))
tutorials_output_dir)
Literate.markdown(joinpath("docs", "literate", "src", "tut_visualization.jl"),
tutorials_output_dir)

copy_file("AUTHORS.md",
"in the [LICENSE.md](LICENSE.md) file" => "under [License](@ref)")
Expand Down Expand Up @@ -87,7 +93,9 @@ makedocs(sitename="TrixiParticles.jl",
"Setting up your simulation from scratch" => joinpath("tutorials",
"tut_setup.md"),
"Modifying or extending components of TrixiParticles.jl within a simulation file" => joinpath("tutorials",
"tut_custom_kernel.md")
"tut_custom_kernel.md"),
"Visualizing particle data with Plots.jl" => joinpath("tutorials",
"tut_visualization.md")
],
"Fluid-Structure Interaction" => [
"Fluid-structure interaction with rigid bodies" => joinpath("tutorials",
Expand Down
17 changes: 16 additions & 1 deletion docs/src/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

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. [Particle packing tutorial](tutorials/tut_packing.md): build a body-fitted particle configuration for complex geometries.
3. [Visualizing particle data with Plots.jl](tutorials/tut_visualization.md): compare discrete particle plots with interpolated fields on a Cartesian grid.
4. [Particle packing tutorial](tutorials/tut_packing.md): build a body-fitted particle configuration for complex geometries.

## Tutorials

Expand Down Expand Up @@ -38,6 +39,20 @@ directly in the file you run.
- Focus: `trixi_include`, custom kernels, rapid iteration
- Choose this if: you want to prototype changes without cloning and modifying the package

### [Visualizing particle data with Plots.jl](tutorials/tut_visualization.md)

```@raw html
<img src="../tutorials/tut_visualization_interpolated_velocity.png"
alt="Velocity from a coarse vortex-street simulation interpolated onto a regular grid"
style="max-width: 360px; width: 100%; border-radius: 12px;" />
```

Compare the velocity carried by moving SPH particles with its kernel reconstruction on a
Cartesian grid in a deliberately coarse vortex-street simulation.

- Focus: particle plots, plane interpolation, regular-grid visualization
- Choose this if: you want to postprocess particle data or export a smooth field for plotting

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

```@raw html
Expand Down
3 changes: 3 additions & 0 deletions docs/src/visualization.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Visualization

For instructions on how to visualize simulation data in Julia, see the tutorial on
[visualizing particle data with Plots.jl](@ref tut_visualization).

## Export VTK files
You can export particle data as VTK files by using the [`SolutionSavingCallback`](@ref).
All [predefined examples](examples.md) already use this callback to export VTK files to the `out`
Expand Down
Loading