This page is generated from
doc/user-guide.org. The direct Org HTML export is available asuser-guide.html.
Table of Contents¶
- Introduction
- Requirements
- Installation
- Launching the Application
- The Main Window
- Configuring a Simulation
- Running a Simulation
- Working with Namelist Files
- Exporting Results
- Application Settings
- Troubleshooting
- Keyboard Shortcuts Reference
Introduction¶
cfd-solver-gui is a graphical frontend for the cfd-solver 1D Euler
equation solver. It lets you:
- Configure all solver parameters through a tabbed form — no manual file editing required.
- Launch the solver and watch the solution evolve in real time through a 4-panel plot (density, velocity, pressure, internal energy).
- Save, load, and share Fortran namelist configuration files.
- Export publication-quality figures directly from the plot panel.
Pre-built app bundles (macOS .dmg, Linux tarball, Windows .zip) ship
with the solver binary included — no separate build or install step is
needed. When running from source you must supply the euler_1d binary
yourself (see
Obtaining the Solver Binary).
For developer documentation see doc/developer-guide.org.
This file is the authoritative end-user manual; README.md is only the short
orientation and quickstart.
Requirements¶
Pre-built app bundle (DMG / tarball / zip): no prerequisites — the solver binary and all runtime libraries are included.
From source:
- Python ≥ 3.10
- PySide6 ≥ 6.6
- matplotlib ≥ 3.8
- numpy ≥ 1.24
- The compiled solver binary (
euler_1d/cfd-solver, or.exevariants on Windows) somewhere on$PATHor at a known absolute path
Installation¶
Pre-built App Bundle (recommended)¶
Download the latest release from the GitHub Releases page:
- macOS —
cfd-solver-gui-arm64.dmg(Apple Silicon) orcfd-solver-gui-x86_64.dmg(Intel). Open the DMG, dragcfd-solver-gui.apptoApplications, and double-click to launch. -
Linux —
cfd-solver-gui-linux-x86_64.tar.gz. Extract and run:tar -xzf cfd-solver-gui-linux-x86_64.tar.gz ./cfd-solver-gui/cfd-solver-gui
-
Windows —
cfd-solver-gui-windows-x86_64.zip. Extract the archive and runcfd-solver-gui.exefrom the extractedcfd-solver-gui/folder.
The euler_1d solver binary (euler_1d.exe on Windows) is bundled inside
the app; no further configuration is required.
From Source¶
# Install from the repo root
pip install .
# Development install (editable, with test/lint tools)
pip install -e '.[dev]'
If you are a contributor, also install the pre-commit hooks once per clone:
pre-commit install
Obtaining the Solver Binary (source installs only)¶
When running from source the GUI drives the Fortran solver as an external
subprocess. Build the solver from its own repository and install the
resulting binary as euler_1d or cfd-solver somewhere on your $PATH
(use the .exe names on Windows). Refer to the solver repository's build
instructions.
On Windows, source builds of the solver currently target the MSYS2 UCRT64
environment. Build the solver from that shell, then either keep the binary on
PATH there or use Solver → Set Solver Binary… to point the GUI at the
absolute .exe path.
If you place the binary somewhere other than $PATH (e.g. a project-specific
directory), use Solver → Set Solver Binary… to point the GUI at it
explicitly.
Launching the Application¶
cfd-gui # installed script
python -m cfd_gui # run as module (useful in development)
On first launch the GUI searches $PATH for euler_1d or cfd-solver
(euler_1d.exe / cfd-solver.exe on Windows, in that order) for source
installs. In packaged app bundles, the bundled solver is selected
automatically. When a solver path is available, the status bar shows
"Solver: <filename>". If not, the status bar shows "Solver: (not set)"
— see Application Settings to configure it.
The Main Window¶
Layout Overview¶
┌────────────────────────────────────────────────────────┐ │ Toolbar: ▶ Run │ ■ Stop │ Open │ Save │ Reset │ Clear │ ├──────────┬─────────────────────────────────────────────┤ │ │ │ │ Config │ Plot Canvas │ │ Editor │ (4-panel) │ │ (tabs) │ │ │ │ │ ├──────────┴─────────────────────────────────────────────┤ │ Log panel │ ├────────────────────────────────────────────────────────┤ │ Status bar [progress] Solver: euler_1d │ └────────────────────────────────────────────────────────┘
- Config Editor (left): tabbed form with all solver parameters. Drag the vertical splitter to resize.
- Plot Canvas (right): 4-panel matplotlib figure with navigation toolbar.
- Log panel (bottom): solver stdout/stderr plus GUI status messages (marked
with
[gui]). - Status bar (bottom edge): shows current iteration/time during a run, a progress bar, and the active solver binary name.
Toolbar Actions¶
| Action | Shortcut | Description |
|---|---|---|
| ▶ Run | Ctrl+R | Start a solver run with current parameters |
| ■ Stop | Ctrl+. | Request stop for the running solver |
| Open NML … | Ctrl+O | Load parameters from a .nml file |
| Save NML … | Ctrl+S | Save current parameters to a .nml file |
| Reset Defaults | (none) | Reset all widgets to built-in defaults |
| Clear Plot | (none) | Clear both numerical and exact solution lines |
Menu Actions¶
File menu:
- Open NML … (Ctrl+O)
- Save NML … (Ctrl+S)
- Save Figure … — export the current plot
- Load Result … — load a
result.datorsnapshot.datfile into the plot - Quit (Ctrl+Q)
View menu:
- Larger (Ctrl+=) — increase font size by 1 pt
- Smaller (Ctrl+-) — decrease font size by 1 pt
- Reset Font Size (Ctrl+0) — restore the platform default size
Solver menu:
- Run (Ctrl+R)
- Stop (Ctrl+.)
- Set Solver Binary … — browse for the solver executable
Help menu:
- About
Configuring a Simulation¶
Configuration Tabs Overview¶
The config editor has seven tabs, each corresponding to a Fortran namelist group:
| Tab | Namelist group | Contents summary |
|---|---|---|
| Grid | &grid |
Number of cells, domain extents |
| Time | &time_ctrl |
Start/stop times, time step, CFL |
| Physics | &physics |
Ratio of specific heats (γ) |
| Schemes | &schemes |
Flux, reconstruction, time integration |
| IC / BCs | &initial_condition |
Problem preset, left/right states, BCs |
| Output | &output |
Output files, print frequency, live snapshot |
| Checkpoint | &checkpoint |
Checkpoint write frequency, restart |
Hover over any widget to see a tooltip describing the parameter.
Grid Tab¶
| Parameter | Default | Description |
|---|---|---|
| Cells | 500 | Number of uniform grid cells |
| x left | 0.0 m | Left boundary x-coordinate |
| x right | 1.0 m | Right boundary x-coordinate |
Practical guidance: 200–500 cells is adequate for exploring schemes. Use 1 000–2 000 for publication-quality results. Very high cell counts (> 10 000) will slow the live plot update noticeably.
Time Tab¶
| Parameter | Default | Description |
|---|---|---|
| Δt [s] | 1.0e-4 | Fixed time step (used only when CFL = 0) |
| t start [s] | 0.0 | Simulation start time |
| t stop [s] | 0.15 | Simulation stop time |
| CFL | 0.0 | CFL number: > 0 = adaptive Δt, 0 = fixed Δt |
| LAPACK banded solve | on | Use LAPACK dgbsv for backward Euler |
When CFL > 0, the solver computes Δt adaptively at each step; the fixed Δt
widget is ignored. The LAPACK toggle only has effect when beuler is
selected as the time scheme.
Physics Tab¶
| Parameter | Default | Description |
|---|---|---|
| γ | 1.4 | Ratio of specific heats \(c_p / c_v\) |
The default 1.4 is correct for diatomic ideal gases (air, nitrogen, oxygen) at moderate temperatures. Use 5/3 ≈ 1.667 for monatomic gases. The minimum allowed value is 1.001.
Schemes Tab¶
Flux scheme — the numerical flux function at cell interfaces:
| Value | Description |
|---|---|
| lax_friedrichs | Lax–Friedrichs: very diffusive, very robust |
| steger_warming | Steger–Warming flux vector splitting |
| van_leer | van Leer FVS |
| ausm_plus | AUSM+: low-diffusion, good for viscous-like problems |
| hll | HLL: two-wave approximate Riemann solver |
| hllc | HLLC: HLL with contact restoration; good all-purpose choice |
| roe | Roe's linearised Riemann solver |
Reconstruction scheme — spatial accuracy of left/right state extrapolation:
| Value | Order | Description |
|---|---|---|
| upwind1 | 1st | First-order upwind; most diffusive |
| upwind2 | 2nd | Second-order upwind |
| central2 | 2nd | Second-order central |
| muscl | 2nd | MUSCL with TVD limiter (see Limiter below) |
| eno3 | 3rd | Third-order ENO |
| weno5 | 5th | Classic WENO-JS5 (default) |
| weno5z | 5th | WENO-Z5: improved smoothness indicators |
| weno7 | 7th | WENO-JS7 |
| mp5 | 5th | MP5: monotonicity-preserving |
| teno5 | 5th | TENO5: targeted ENO |
| linear_weno | varies | Linear (non-adaptive) WENO weights |
Time integrator:
| Value | Stage | Order | Description |
|---|---|---|---|
| euler | 1 | 1 | Forward Euler (first order) |
| ssprk22 | 2 | 2 | Strong-stability-preserving RK2 (Heun) |
| rk3 | 3 | 3 | Standard three-stage RK3 (default) |
| rk4 | 4 | 4 | Classic four-stage RK4 |
| ssprk54 | 5 | 4 | SSP-RK5(4): high-order SSP |
| beuler | 1 | 1 | Backward Euler (implicit) |
| bdf2 | 2 | 2 | Second-order BDF (implicit) |
Characteristic projection: auto (recommended for shocked flows), yes (always), or
no (never). Characteristic decomposition reduces spurious oscillations at
shocks; auto activates it when the flux scheme or reconstruction warrants it.
MUSCL limiter: only active when recon_scheme = muscl.
| Value | Description |
|---|---|
| minmod | Most dissipative; safest |
| superbee | Least dissipative; may over-compress |
| mc | Monotonised central |
| van_leer | Van Leer smooth limiter |
| koren | Koren: third-order in smooth regions |
Positivity limiter: Zhang–Shu limiter ensuring ρ > 0 and p > 0. For FDS (approximate Riemann) fluxes only.
Hybrid reconstruction: activates a shock sensor that switches between linear (smooth regions) and nonlinear WENO (near shocks). Control with the Hybrid sensor and Sensor threshold widgets.
IC / BCs Tab¶
Problem type — initial condition preset:
| Value | Description |
|---|---|
| sod | Sod shock tube: classic Riemann problem |
| shu_osher | Shu–Osher: shock interacting with a density wave |
| smooth_wave | Smooth sinusoidal density wave (for accuracy studies) |
| linear_advection | Passive scalar advection test |
| woodward_colella | Woodward–Colella blast wave: two strong shocks |
| lax | Lax problem: moderate Riemann problem |
| acoustic_pulse | Gaussian acoustic pulse in a uniform background |
| from_file | Read initial condition from a data file (see IC file below) |
| udf | User-defined Fortran subroutine (see UDF source below) |
Left / right primitive state (for Riemann-type problems):
| Parameter | Default | Description |
|---|---|---|
| ρ left | 1.0 kg/m³ | Left-state density |
| u left | 0.0 m/s | Left-state velocity |
| p left | 1.0 Pa | Left-state pressure |
| ρ right | 0.125 kg/m³ | Right-state density |
| u right | 0.0 m/s | Right-state velocity |
| p right | 0.1 Pa | Right-state pressure |
| x diaphragm | 0.5 m | Initial discontinuity location |
IC file: path to a 4-column data file (x rho u p) used when
problem_type = from_file. Enable Interpolate IC to allow linear
interpolation when the file's grid differs from the simulation grid.
UDF source file: path to a Fortran source file providing the udf_ic subroutine,
used when problem_type = udf.
Boundary condition types (bc_left / bc_right):
| Value | Description |
|---|---|
| dirichlet | Fixed primitive state from rho/u/p_left(right) |
| inflow | Supersonic inflow from rho/u/p_left(right) |
| outflow | Zero-order extrapolation (supersonic outflow) |
| reflecting | Velocity sign flip (solid wall) |
| periodic | Wrap-around (must be set on both boundaries) |
| nonreflecting | Non-reflecting (absorbing) BC; see NRBC below |
Non-reflecting BC parameters (visible when either boundary is nonreflecting):
| Parameter | Default | Description |
|---|---|---|
| p ref left/right | 1.0 Pa | Far-field reference pressure |
| σ NRBC | 0.0 | Relaxation: 0 = fully non-reflecting, 1 = Dirichlet |
| NRBC mode | pressure | pressure (simple) or characteristic (full wave decomp) |
| u ref left/right | 0.0 m/s | Far-field velocity (characteristic mode only) |
| ρ ref left/right | 1.0 | Far-field density (characteristic mode only) |
| σ entropy | 0.0 | Entropy wave relaxation (characteristic mode only) |
Output Tab¶
| Parameter | Default | Description |
|---|---|---|
| Output file | result.dat | Filename for the final solution (relative to CWD) |
| Print freq | 50 | Print residual to log every N iterations (≥ 1) |
| Timing | off | Print wall-clock performance table at end of run |
| Verbosity | 3 | 0 = silent, 1 = errors only, 2 = warnings, 3 = info, 4 = debug |
| Log file | run.log | Write solver log to this file (empty = disabled) |
| Snapshot freq | 0 (auto) | Write live snapshot every N iters; 0 = GUI auto-sets |
| Snapshot file | snapshot.dat | Path for the live snapshot file |
Note on Snapshot frequency: when the widget is left at 0, the GUI rewrites
the run's namelist to use max(1, print_freq) before launch so live plotting
stays available. The widget value itself remains unchanged in the editor.
Choose a larger positive value if you want fewer plot updates; 0 is the
GUI's "automatic live-update" mode, not a "disable snapshots" mode.
Checkpoint Tab¶
| Parameter | Default | Description |
|---|---|---|
| Checkpoint freq | 0 | Write checkpoint every N iterations (0 = disabled) |
| Checkpoint base | checkpoint | Base filename for checkpoint files |
| Restart file | (empty) | Checkpoint file to resume from; empty = fresh start |
Checkpointing allows long runs to be interrupted and resumed. Set
Checkpoint freq to a positive value, stop the run (or let it finish
naturally), then set Restart file to the saved checkpoint before the next
run.
Resetting to Defaults¶
Click Reset Defaults in the toolbar to return every parameter to its built-in default value. This does not affect the solver binary setting.
Running a Simulation¶
Starting a Run¶
Click ▶ Run (or Ctrl+R). The GUI:
- Reads all parameter widgets.
- Creates a durable run directory under the application's data area
(
.../runs/YYYYMMDD-HHMMSS[-NN]/) and writesinput.nmlthere. - Creates
run_manifest.jsonandevents.jsonlin the same run directory. - Starts a local run-manager worker, which then spawns the solver binary with
input.nmlas its argument. - Updates the status bar to show "Running …" and displays an indeterminate progress bar.
Once the solver begins writing snapshots, the status bar switches to
"iter=N t=T.TTTeee" and the progress bar fills proportionally to
(sim_time / time_stop).
Live Plot Updates¶
While the solver runs, the four plot panels update whenever the run manager
detects a new complete snapshot file (by default snapshot.dat):
- Density — ρ [kg/m³]
- Velocity — u [m/s]
- Pressure — p [Pa]
- Internal energy — e [J/kg], derived as e = p / (ρ · (γ − 1))
Orange dots (Numerical): the current numerical solution read from
snapshot.dat.
Blue line (Exact): during Sod runs with t > 0, the GUI computes the exact
Riemann solution from the current left/right states, \gamma, and diaphragm
position. For other problem types, no exact overlay is shown.
Use the matplotlib navigation toolbar (above the plot) to zoom, pan, or reset the view during the run.
Log Panel¶
The log panel shows solver output in real time. Lines prefixed with [gui]
are messages from the GUI itself (working directory path, binary path, run
status, file save confirmations). Lines prefixed with [runner] are local
run-manager diagnostics. All other lines come directly from the solver's
stdout/stderr.
Log verbosity is controlled by the Verbosity parameter (Output Tab).
Stopping a Run¶
Click ■ Stop (or Ctrl+.) to request that the run stop:
- The GUI sends a structured stop request to the local run manager.
- The worker asks the solver process to terminate.
- If the solver does not exit within 3 seconds, the worker force-kills it.
Any snapshot data already in the plot at stop time remains visible. The run directory (and any partial results in it) is preserved.
After the Run¶
When the solver exits normally, the GUI:
- Loads the final output file from the run directory (by default
result.dat) and updates the plot. - Restores the Run/Stop buttons.
- Shows the solver exit message in the status bar and log panel.
The run directory path was logged at run start — use it to inspect or copy
output files manually. The same directory also contains run_manifest.json
and events.jsonl for a machine-readable record of the run.
Working with Namelist Files¶
Saving a Namelist¶
Use Save NML … (Ctrl+S) to write the current widget values to a .nml
file. The file is compact: it only contains parameters that differ from their
built-in defaults, plus a fixed set of always-included keys (n_cell,
time_stop, flux_scheme, recon_scheme, time_scheme, problem_type,
output_file).
Opening a Namelist¶
Use Open NML … (Ctrl+O) to load a .nml file. The GUI parses the file
and updates all matching widgets. Unknown keys are silently ignored. Keys
not present in the file revert to built-in defaults.
The GUI is compatible with namelists from the cfd-solver repository's
example/ directory, even if they contain parameters not in the current
schema.
Namelist Format¶
Fortran namelist files look like:
! Comment lines start with !
&grid
n_cell = 200,
x_right = 1.0,
/
&schemes
flux_scheme = 'hllc',
recon_scheme = 'weno5',
time_scheme = 'rk3',
/
Key rules:
- Group names:
&name…/. - Key-value pairs:
key = value,(trailing comma optional). - Booleans:
.true./.false.(or.t./.f.). - Floats: standard (
1.5) or Fortran scientific (1.5d-3). - Strings: single or double quoted (
'hllc'or"hllc").
Exporting Results¶
Save Figure¶
Use File → Save Figure … to export the current 4-panel plot. Supported formats:
| Format | Notes |
|---|---|
| Vector; best for publications | |
| PNG | Raster at 300 DPI |
| SVG | Vector; good for web or Inkscape |
The figure is saved with bbox_inches'tight'= to minimise white space.
The matplotlib navigation toolbar (zoom/pan controls) affects what is visible in the export; zoom in before saving to focus on a region of interest.
Load Result¶
Use File → Load Result … to load any result.dat or snapshot.dat file
into the Numerical (orange) series. Expected format: 4 columns (x,
rho, u, p), with an optional # iter=… header line (which is skipped).
Loading a file replaces the current numerical curve for inspection. It does not create a second comparison overlay, and starting a new run clears the plot before the run's own snapshots/results are rendered.
Application Settings¶
Solver binary: stored in QSettings under solver/binary. Bundled apps
pin this to the packaged solver; source installs auto-detect from $PATH
on first launch and save the discovered path. Override at any time via
Solver → Set Solver Binary …. To force re-detection, clear this setting by
deleting the settings file (see below).
Font size: stored in QSettings under appearance/font_size. Adjusted
at runtime via View → Larger / Smaller / Reset Font Size (or the keyboard
shortcuts). The platform default is 13 pt on macOS and 10 pt on Linux/Windows;
valid range is 8–20 pt. The choice persists across restarts.
Last-used directories: the directory of the last Open NML / Save NML
dialog is remembered separately (paths/last_nml_dir) so subsequent dialogs
open in the right place.
Run directories: run artifacts are stored under the application's writable
data location in a runs/ subdirectory. This location is derived from the
platform-standard app data path and is not itself stored in QSettings.
Settings file locations:
| Platform | Location |
|---|---|
| Linux | ~/.config/cfd-solver-gui/cfd-solver-gui.conf |
| macOS | ~/Library/Preferences/com.cfd-solver-gui.plist |
| Windows | HKEY_CURRENT_USER\Software\cfd-solver-gui |
To reset all settings: delete the file (Linux/macOS) or remove the registry key (Windows), then restart the application.
Troubleshooting¶
"Solver: (not set)" in the status bar
The auto-detection on startup did not find euler_1d or cfd-solver on
$PATH. Use Solver → Set Solver Binary … to select the executable manually.
"Failed to start solver" in the log
The configured binary path is wrong or the file is not executable. Use
Solver → Set Solver Binary … to correct it. On Linux/macOS, ensure the
binary has execute permission (chmod +x euler_1d). On Windows, ensure you
selected the solver .exe rather than a directory or archive.
The plot does not update during a run
The worker has not yet observed a new complete snapshot file. Common causes:
- The solver has not reached the first snapshot yet.
- Snapshot freq is set to a large positive value, so updates are sparse.
- The solver exited or errored before producing the first usable snapshot.
- Snapshot file points somewhere unexpected.
Check the run directory path in the log, confirm the snapshot file exists, and
look for a valid # iter=… t=… header followed by four numeric columns.
The run completes instantly with a non-zero exit code
The solver encountered an error. Read the log panel carefully — solver error messages appear there. Common causes: invalid namelist parameter value, missing IC file, out-of-bounds CFL.
Poor performance with large cell counts
snapshot_freq controls how often the solver writes snapshot data. If the
widget is left at 0, the GUI uses print_freq for the run. Setting either
value higher reduces disk I/O and plot update overhead at the cost of less
frequent live updates.
Namelist parse error on Open NML
The GUI parser handles scalar values only. Namelist files with array literals
(a = 1, 2, 3) or continuation lines will not parse correctly. Check the
error message displayed in the dialog for the offending line.
Keyboard Shortcuts Reference¶
| Shortcut | Action |
|---|---|
| Ctrl+R | Run the solver |
| Ctrl+. | Stop the solver |
| Ctrl+O | Open NML … (load namelist file) |
| Ctrl+S | Save NML … (save namelist file) |
| Ctrl+Q | Quit the application |
| Ctrl+= | Increase font size |
| Ctrl+- | Decrease font size |
| Ctrl+0 | Reset font size to default |