Skip to content

This page is generated from doc/user-guide.org. The direct Org HTML export is available as user-guide.html.

Table of Contents

  1. Introduction
  2. Requirements
  3. Installation
    1. Pre-built App Bundle (recommended)
    2. From Source
    3. Obtaining the Solver Library (source installs only)
  4. Launching the Application
  5. The Main Window
    1. Layout Overview
    2. Toolbar Actions
    3. Menu Actions
  6. Configuring a Simulation
    1. Configuration Tabs Overview
    2. Grid Tab
    3. Time Tab
    4. Physics Tab
    5. Schemes Tab
    6. IC / BCs Tab
    7. Output Tab
    8. Checkpoint Tab
    9. Resetting to Defaults
  7. Running a Simulation
    1. Starting a Run
    2. Live Plot Updates
    3. Log Panel
    4. Stopping a Run
    5. After the Run
  8. Working with Namelist Files
    1. Saving a Namelist
    2. Opening a Namelist
    3. Namelist Format
  9. Exporting Results
    1. Save Figure
    2. Load Result
  10. Application Settings
  11. Troubleshooting
  12. 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 shared library included — no separate build or install step is needed. When running from source you must supply the solver shared library yourself (see Obtaining the Solver Library).

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 shared library and all runtime dependencies are included.

From source:

  • Python ≥ 3.10
  • PySide6 ≥ 6.6
  • matplotlib ≥ 3.8
  • numpy ≥ 1.24
  • The compiled solver shared library (libcfd_solver.dylib, libcfd_solver.so, or cfd_solver.dll) at a known absolute path or in the default sibling ../cfd-solver/build/abi/ layout

Installation

Download the latest release from the GitHub Releases page:

  • macOScfd-solver-gui-arm64.dmg (Apple Silicon) or cfd-solver-gui-x86_64.dmg (Intel). Open the DMG, drag cfd-solver-gui.app to Applications, and double-click to launch.
  • Linuxcfd-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

  • Windowscfd-solver-gui-windows-x86_64.zip. Extract the archive and run cfd-solver-gui.exe from the extracted cfd-solver-gui/ folder.

The solver shared library is bundled inside the app; no further configuration is required.

From Source

# Create the project-local runtime environment from the repo root
uv python install
uv sync --no-dev

uv is the recommended and supported workflow for source installs. If you prefer pip, a basic source install still works with pip install . followed by cfd-gui.

Migration note: the old pip install '.[dev]' / pip install '.[docs]' / pip install '.[bundle]' extras no longer exist. Use uv sync for the contributor toolchain and uv sync --no-dev --group bundle for packaging-only dependencies.

If you are contributing to the project, run uv sync instead of uv sync --no-dev so the test, lint, and documentation tools are available.

If you are a contributor, also install the pre-commit hooks once per clone:

uv sync
uv run pre-commit install

Obtaining the Solver Library (source installs only)

When running from source the GUI starts a local Python worker that loads the solver shared library directly. Build the solver from its own repository so that one of libcfd_solver.dylib, libcfd_solver.so, or cfd_solver.dll exists. The GUI searches the stored library path, CFD_SOLVER_LIB, and the default sibling ../cfd-solver/build/abi/{release,debug} locations, preferring the release bundle when both are present.

On Windows, source builds of the solver currently target the MSYS2 UCRT64 environment. Build the solver from that shell, then either set CFD_SOLVER_LIB or use Solver → Set Solver Library… to point the GUI at the absolute .dll path.

If you place the shared library somewhere other than the default sibling build tree, use Solver → Set Solver Library… to point the GUI at it explicitly.

Launching the Application

uv run cfd-gui            # installed script inside the project .venv
uv run python -m cfd_gui  # run as module (useful in development)

On first launch the GUI checks for a bundled solver library, then consults the stored library path, CFD_SOLVER_LIB, and the sibling ../cfd-solver/build/abi/{release,debug} locations. When a library path is available, the status bar shows "Library: <filename>". If not, the status bar shows "Library: (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] Library: libcfd_solver │
└────────────────────────────────────────────────────────┘
  • Config Editor (left): tabbed form with all solver parameters, plus a Jump to parameter box above the tabs for quick navigation by label or namelist key. 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 library 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

File menu:

  • Open NML … (Ctrl+O)
  • Save NML … (Ctrl+S)
  • Save Figure … — export the current plot
  • Load Result … — load a result.dat or snapshot.dat file 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 Library … — browse for the shared library file

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.

The Jump to parameter box above the tabs accepts either the visible label or the underlying namelist key (for example time_stop or output_file). Choosing a match switches to the correct tab and focuses that widget.

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
weno_cu6 6th CU-style 6-point WENO variant
weno7 7th WENO-JS7
weno9 9th WENO-JS9
weno11 11th WENO-JS11
mp5 5th MP5: monotonicity-preserving
teno5 5th TENO5: targeted ENO

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 library setting.

Running a Simulation

Starting a Run

Click ▶ Run (or Ctrl+R). The GUI:

  1. Reads all parameter widgets.
  2. Creates a durable run directory under the application's data area (.../runs/YYYYMMDD-HHMMSS[-NN]/) and writes input.nml there.
  3. Creates run_manifest.json and events.jsonl in the same run directory.
  4. Starts a local run-manager worker, which then loads the solver shared library, creates a session, and points it at input.nml.
  5. Updates the status bar to show "Running …" and displays an indeterminate progress bar.

Once the worker begins receiving progress from the solver session, 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 worker emits a new in-memory solution_frame event:

  • 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 copied directly out of the solver session.

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, library path, run status, file save confirmations). Lines prefixed with [runner] are local run-manager diagnostics. All other lines come from the tailed solver log.

Log verbosity is controlled by the Verbosity parameter (Output Tab).

Stopping a Run

Click ■ Stop (or Ctrl+.) to request that the run stop:

  1. The GUI sends a structured stop request to the local run manager.
  2. The worker stops advancing the solver session and writes the current result.dat for inspection.

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:

  1. Loads the final output file from the run directory (by default result.dat) and updates the plot.
  2. Restores the Run/Stop buttons.
  3. 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
PDF 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 library: stored in QSettings under solver/library_path. Bundled apps pin this to the packaged shared library; source installs auto-detect from the sibling ../cfd-solver/build/abi/ tree and can also honor CFD_SOLVER_LIB. Override at any time via Solver → Set Solver Library …. 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

"Library: (not set)" in the status bar

The auto-detection on startup did not find a bundled library, a stored solver/library_path, CFD_SOLVER_LIB, or the sibling ../cfd-solver/build/abi/ output. Use Solver → Set Solver Library … to select the library manually.

"Failed to initialize solver library" in the log

The configured library path is wrong or the library is missing dependent runtime files. Use Solver → Set Solver Library … to correct it. On Linux/macOS, ensure the bundled .so / .dylib dependencies live next to the solver library. On Windows, ensure you selected cfd_solver.dll rather than a directory or archive.

The plot does not update during a run

The worker has not yet emitted a live solution_frame. Common causes:

  • The solver has not reached the first live-update stride yet.
  • Snapshot freq or Print freq is set high, so updates are sparse.
  • The solver exited or errored before producing the first usable frame.

Check the run directory path in the log, confirm run.log (or solver_stdout.log when file logging is disabled) is advancing, and inspect events.jsonl for progress events.

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

The worker uses snapshot_freq when it is positive and otherwise falls back to print_freq to decide how often to emit live frames. Setting either value higher reduces copy-out 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