Troubleshooting
This page documents common failure modes encountered in AortaCFD simulations, their root causes, and recommended solutions.
Mesh Generation Failures
"No cells in mesh"
Cause: The scale_factor in config.json does not match the STL file units. The geometry is either too large (extends beyond the background mesh domain) or too small (collapsed to a point).
Solution: Verify the STL units and set the correct scale factor:
| STL Units | scale_factor |
|---|---|
| Millimetres | 0.001 |
| Centimetres | 0.01 |
| Metres | 1.0 |
"locationInMesh outside domain"
Cause: The automatically computed interior point lies outside the geometry, typically because the STL surface is not watertight (gaps between patches).
Solution:
- Verify that all patches form a closed surface:
surfaceCheck constant/triSurface/wall_aorta.stl - Check for gaps between inlet/outlet patches and the wall patch in ParaView
- AortaCFD auto-computes the interior point via ray-casting; a non-watertight geometry causes this to fail
"Boundary layer failure" or low layer coverage
Cause: Prismatic layers cannot fit on small patches (especially outlet patches) or in regions of high surface curvature.
Solution:
Reducing num_layers from 5 to 3 and increasing min_thickness from 0.1 to 0.2 often resolves layer generation failures. AortaCFD automatically retries with relaxed settings if the initial attempt fails.
checkMesh reports high non-orthogonality or skewness
Cause: Complex geometry (tight curvatures, small branches) or misaligned geometry with the coordinate system.
Solution:
- AortaCFD aligns geometry via PCA automatically; verify alignment is correct
- Increase
cells_per_diameter(finer mesh often improves quality metrics) - Use the
regenerate-numericsstep to adapt numerical schemes to the mesh quality: - If quality is very poor, switch to the
robustprofile
Solver Failures
"PIMPLE: Not converged" every timestep
Cause: The residual target is below the convergence floor created by explicit pressure relaxation. The solver burns all outer iterations without reaching the target.
Solution:
- Use the
robustprofile (relaxed residual targets that sit above the floor): - Or increase the residual tolerance in the configuration
deltaT collapses to very small values (1e-100)
Cause: The PIMPLE outer loop diverges, typically during diastolic backflow. Adaptive time-stepping reduces deltaT to maintain stability, eventually collapsing.
Solution:
- Enable backflow stabilisation (should be on by default):
- Use the
robustprofile - Check mesh quality -- high skewness near outlets exacerbates backflow instability
"Floating point exception" (NaN)
Cause: The solution contains NaN values, typically from division by zero in the pressure equation or unphysical velocity magnitudes.
Solution:
- Check mesh quality:
cat logs/log.checkMesh - Verify inlet data: ensure the CSV waveform has no negative flow rates at the start
- Try a different
cells_per_diameter(both too coarse and too fine can cause issues) - Ensure
scale_factoris correct (wrong scaling produces extreme velocities)
"FOAM FATAL ERROR: cannot find file"
Cause: A required OpenFOAM dictionary or field file is missing, typically because the case step was not run or was run with a different configuration.
Solution:
This regenerates all OpenFOAM dictionaries without affecting the mesh.
Boundary Condition Issues
Unphysical pressure values (> 200 mmHg or < 40 mmHg)
Cause: Incorrect Windkessel parameters, typically from wrong blood pressure values or extreme outlet geometries.
Solution:
- Verify
systolic_pressureanddiastolic_pressurein config (should be in mmHg) - Check the
reports/inlet_audit.jsonfor the computed mean flow rate -- is it physiologically reasonable? - Check each outlet's R, C, Z values in
0/p-- very large R produces high pressure
No flow at outlets
Cause: The outlet patches may not be correctly identified in the geometry configuration.
Solution:
- Verify that
outlet_keywords_orderedin config matches the STL filenames - Open the mesh in ParaView and confirm that outlet patches exist and are correctly positioned
Post-Processing Issues
TAWSS/OSI not computed (zero values)
Cause: Runtime field averaging was not enabled, or the simulation did not run long enough to accumulate averaging data.
Solution:
- Ensure hemodynamics runtime functions are enabled:
- Minimum simulation duration:
(skip_cycles + 1) * cardiac_cycle_period - Re-run post-processing:
python run_patient.py --postprocess <run_path>
Maximum WSS is unrealistically high (> 100 Pa)
Cause: Mesh artifacts at refinement boundaries or sharp geometric features produce single-cell WSS spikes. This is expected.
Solution: Use percentile-based metrics (P95, P99) instead of maximum values. AortaCFD reports these automatically. The maximum is included for reference but should not be used for clinical interpretation.
Restarting a Crashed Simulation
# Check available time directories
ls output/<case>/run_xxx/openfoam/ | grep "^0\." | sort -g | tail -5
# Re-run solver (automatically restarts from latest saved time)
python run_patient.py <case> --update output/<case>/run_xxx --steps solver
If the crash occurs at a specific simulation time repeatedly, consider:
- Switching to the
robustprofile for the remainder of the simulation - Reducing
maxCoin the configuration - Enabling or increasing backflow stabilisation (
betaT: 0.3 to 0.5)
Diagnostic Commands
# Check mesh quality
cat output/<case>/run_xxx/openfoam/logs/log.checkMesh
# Check solver convergence
tail -50 output/<case>/run_xxx/openfoam/logs/log.solver
# Count PIMPLE iterations per timestep
grep "PIMPLE: Converged in" logs/log.solver | awk '{print $NF}' | sort | uniq -c
# Check inlet audit
cat output/<case>/run_xxx/reports/inlet_audit.json
# View full resolved configuration
cat output/<case>/run_xxx/reports/merged_config.json
Found an issue or have a suggestion for this page?
Open a GitHub issue