PDEStudio.jl
PDEStudio.jl is an interactive, Makie-driven graphical frontend for the real-time visualization and exploration of Partial Differential Equation (PDE) simulations.
It is built directly on top of its numerical backend PDEStudioCore.jl (reexported, so using PDEStudio is enough) and turns its simulation data into responsive 1D, 2D and 3D visualizations. It features a hierarchical editor, CSV-based presets for both the look and the physics of a study, and a rendering engine that handles Eulerian grids and Lagrangian particle systems.
PDE simulations often have to run on servers. There are two ways to work with remote machines:
Headless Mode: The backend
PDEStudioCoreruns and stores simulations on its own, so it can createPDEStudio-compatible data on the server, which you then copy for local exploration withGLMakie. This gives the best performance, but can mean large data transfers.
Web Mode:
PDEStudiois Makie-backend agnostic, so you can useWGLMakie(powered byBonito) to serve the studio from the server to a web browser. This greatly reduces data transfer, at the cost of performance and latency.
๐จ Interactive Architecture
The studio is built around a central, reactive state manager that links the live simulation data to the Makie render loop.
- Eulerian & Lagrangian Support: Rendering primitives adapt to the data: grid-based heatmaps, surfaces and volumes, or point-based scatter plots. Data stored in the other representation is converted on the fly.
- Hierarchical Editor: Shared parameters, method parameters, the parameter sweep, the active methods, UI styles, export settings and display names, all in one Category โ Scope โ Parameter editor (see Advanced Editors).
- Dynamic Layouts: Multi-plot comparisons (methods, components, time steps or any swept parameter), linked or decoupled axes and detached legends.
- Any Sweep: Swept parameters can be numbers or anything else (scheme names, tuples, โฆ); non-numeric sweeps get index sliders that display the swept value.
๐พ Serialization & Presets
PDEStudio.jl stores its state in plain CSV files (Category, Scope, Parameter, Value, RFC 4180).
| File | What it holds | Created with |
|---|---|---|
| Export CSV | Everything: physics, look, sweep, git commits, Julia versions, bundled sources | Export (next to every figure/animation) |
| Visual Preset | The look only (layout, axes, camera, labels, UI styles) | Save Presets, save_plot_preset |
| Simulation Preset | The physics only (shared/method parameters, active methods, sweep, functions) | Save Sim Preset, save_sim_preset |
Visual presets apply to any simulation; simulation presets swap the physics while the look stays as it is. See Presets.
- Readable & Editable: Keys are written as their raw backend names (
animation_FPS,sim_func_name), values in Julia literal syntax (Float64[0.2, 0.5],:upwind). Display labels never appear in files, so renaming a label does not affect saved states. - Type-Preserving Parsing: Values are read back with the safe literal parser
str2valinto the type they were saved as (vectors, tuples, symbols, dictionaries, โฆ). Text stays text. - Drag-and-Drop: Drop a CSV onto the studio window (or type its path or file name into the filename box and click the load button) to recreate a saved state.
Security Note: CSV values are parsed safely; no code in a value is ever evaluated. However, an export CSV can bundle source files (the
sourcesof aSimulationConfig, copied next to the export), and loading such a CSV executes those files to restore the solvers. Only load exports you trust. Presets never contain source files.
๐ฌ Exporting & Animations
The export pipeline renders a pristine copy of the plot, independent of the interactive window.
- Static Frames: High-DPI
.png/.jpg, and vector.pdf,.svgand.epsvia CairoMakie, with optional rasterization of heavy 3D plots. - Animations:
.mp4,.webm,.mkvor.gif, sweeping any slider (time, a physical dimension or a swept parameter) with a locked camera, a custom frame rate and duration.
See File Operations for the details.
๐ ๏ธ Main API Functions
| Function | Purpose |
|---|---|
launch_plotter() | Builds the studio window and its reactive listeners; returns the Figure. |
set_sim_config!(config) | Binds a SimulationConfig (or a CSV: set_sim_config!("name.csv")). Also the baseline for Reset Simulation. |
force_simulation() | Runs the bound configuration (same as clicking Run Simulation). |
set_plot_preset!(name) | Applies a built-in or saved visual preset; set_plot_preset!() restores the default look. |
save_plot_preset(name) | Saves the current look as a visual preset. |
save_sim_preset(name) | Saves the bound simulation as a simulation preset. |
set_sim_preset!(name) | Applies a simulation preset (replace or patch). |
reset_sim_config!() | Restores the configuration last bound with set_sim_config!. |
set_mode!(:eulerian / :lagrangian) | Switches between grid and particle rendering. |
set_allowed_dims!(dims), set_max_params!(n) | Structural limits: the physical dimensions and the number of parameter sliders. |
set_resolution!(dim, n) | Display resolution of a dimension (data is resampled for display). |
reset_plotter!(), reset_manager!() | Closes the window / resets the whole studio without restarting Julia. |
๐ Basic Workflow
using PDEStudio # reexports PDEStudioCore
using GLMakie # or WGLMakie for browser rendering
# 1. The physics (see the PDEStudioCore documentation)
shared = create_param_dict(:N => 100, :cfl => 0.5, :sim_func_name => :my_solver)
methods = create_method_dict(:upwind => create_param_dict(:scheme => "upwind"),
:lax_friedrichs => create_param_dict(:scheme => "lax_friedrichs"))
config = SimulationConfig(shared, methods, [:upwind, :lax_friedrichs]; # active methods (`defaults`)
varied = create_varied_dict(:cfl => [0.3, 0.5, 0.8]),
reference = :my_exact_solution)
# 2. Launch and display the studio
fig = launch_plotter()
display(fig)
# 3. Bind the physics and run it (or click "Run Simulation")
set_sim_config!(config)
force_simulation()A complete, runnable script is examples/advection_1d.jl.
โ๏ธ Advanced Workflow (Custom Macros & Web Servers)
For extensive experiment libraries or remote servers, PDEStudio can be wrapped in custom macros for rapid deployment.
Below is a pattern that configures a Bonito web server for WGLMakie, resolves configuration paths, backs up executed configurations for reproducibility, and binds the physics to the studio in a single macro call.
using PDEStudio
using WGLMakie
using Bonito
# 1. Configure the Web Server for Remote Viewing
Bonito.configure_server!(
listen_url = "0.0.0.0",
listen_port = 9384
)
WGLMakie.activate!()
# 2. Build a one-click macro to load, archive, and plot your experiments
macro plot(name)
return quote
# Launch studio
fig = Base.invokelatest(() -> launch_plotter())
# Resolve path and archive the config
path = joinpath(@__DIR__, "Configs", $(esc(name)) * ".jl")
cp(path, joinpath(@__DIR__, "Archive", $(esc(name)) * "_backup.jl"), force=true)
# Load physics and trigger rendering
config = include(path)
set_sim_config!(config)
force_simulation()
fig
end
end
# Usage:
# julia> @plot "Euler2D_Shock"If the configuration file is listed in the config's sources (SimulationConfig(...; sources = [path])), every export copies it next to the exported CSV (<name>_source_1.jl, โฆ). Loading that CSV later runs the copy (its last expression should be the SimulationConfig) and so recreates the experiment, solvers included. Afterwards the configuration keeps pointing at the original file while it exists (later runs pick up your edits) and falls back to the bundled copy otherwise.