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 Binary (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 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 .exe variants on Windows) somewhere on $PATH or at a known absolute path

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 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

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 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:

  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 spawns the solver binary with input.nml as its argument.
  5. 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:

  1. The GUI sends a structured stop request to the local run manager.
  2. The worker asks the solver process to terminate.
  3. 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:

  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 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