Repository navigation
Conversation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… feature_monitor
|
Nice addition! This complements the terminal tool from #2879 (su2live) well: SU2_MON covers the windowed case, and su2live covers headless runs over SSH, where there’s no display and often no PyQt5/matplotlib. It also classifies the run (converging with an ETA, stalled, limit-cycling, diverging). Once this is in, would you be open to a follow-up PR adding a terminal counterpart in bin/? I could do it as a single stdlib-only script next to monitor.py, or as a --terminal mode of SU2_MON, whichever you prefer. |
rois1995
left a comment
There was a problem hiding this comment.
Please address the three inline findings before merging.
The monitor also needs installation entries: neither SU2_MON nor monitor.py is included in the Meson install paths, so the normal prefix/bin installation does not contain the new command. Please install both with the launcher’s executable permission and relative module path preserved.
Please add small manufactured-history tests covering the header formats, sparse iteration values, reset/cache behavior, incremental append, and incomplete lines, plus a short dependency and launch note.
Validation: the exact reader and plotting methods were exercised with a real Matplotlib Agg canvas. Ten checks passed; four failing behavior assertions reproduced the three inline issues. Installation was checked statically.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Parse the separate VARIABLES line of TECPLOT histories, plot and filter against the iteration column, advance the reader version on reset, add manufactured-history tests, and install SU2_MON and monitor.py with meson. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ith 'import' and 'import from'' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
|
Meson: monitor.py and SU2_MON are installed to bindir from SU2_PY/meson.build, and the launcher keeps its executable bit and relative path. |
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… feature_monitor
|
@rois1995 anything left? |
rois1995
left a comment
There was a problem hiding this comment.
The original reproductions now pass. Please address the remaining P2 inline findings before approval; the P3 comments are smaller plotting corrections.
| self.btn_time.setEnabled(has) | ||
| self.btn_time.setChecked(has) |
There was a problem hiding this comment.
[P2] Do not auto-select a constant Time_Iter column
Steady SU2 histories also contain Time_Iter, with every value equal to zero. After the idle timer disables the checkbox, selecting such a file makes this code check “Time iterations” automatically. With the default start=1, both plots are empty. An existing solver-generated steady history gives 0 points in time mode and 10 in inner mode.
Please keep inner iterations as the default, or require an advancing time counter before selecting time mode automatically. The reproducer exercises the real reader/plot methods and this method with a checkbox stand-in.
| "PyQt5.QtWidgets", | ||
| "matplotlib.backends.backend_qt5agg", | ||
| ): | ||
| sys.modules.setdefault(module, unittest.mock.MagicMock()) |
There was a problem hiding this comment.
[P2] Import unittest.mock explicitly before using it
A fresh python3 SU2_PY/tests/test_monitor.py exits here with AttributeError: module 'unittest' has no attribute 'mock', before running any tests. Importing unittest alone does not load its mock submodule.
Please add import unittest.mock. Preloading that import in the runner lets all seven tests pass, so this has a one-line fix.
|
|
||
|
|
||
| def cleanName(name): | ||
| return name.replace("VARIABLES=", "").replace('"', "").replace(" ", "") |
There was a problem hiding this comment.
[P2] Remove the VARIABLES prefix after normalizing whitespace
For the supported inline legacy header VARIABLES = "Inner_Iter","rms[Rho]",..., the first replacement does not match because there are spaces around =. The final cleaned name is VARIABLES=Inner_Iter, so the reader misses the counter and silently falls back to row indices. Recorded iterations 0,10,20 become 0,1,2 again.
Please remove spaces and quotes before removing the VARIABLES= prefix. Add a sparse-iteration assertion to the existing legacy-header fixture.
| if zone.startswith(b"ZONE") and zone.endswith(b"\n"): | ||
| offset = f.tell() | ||
| elif zone and not zone.endswith(b"\n") and b"ZONE".startswith(zone): | ||
| return |
There was a problem hiding this comment.
[P3] Wait for the full optional ZONE line
If the optional line currently ends at ZONE T="Conv without a newline, b"ZONE".startswith(zone) is false because zone is longer than ZONE. The reader commits its header offset before this metadata line. Completing the line and appending numeric rows then leaves the reader stuck at the ZONE text, with zero rows loaded.
Please defer any incomplete line that begins with ZONE, while preserving the existing check for a partially written keyword.
| if byTime and self.hasTime(): | ||
| keep[:-1] &= counter[1:] != counter[:-1] | ||
| rows = np.flatnonzero(keep) | ||
| rows = rows[rows >= 1] |
There was a problem hiding this comment.
[P3] Keep the first record when it passes the iteration filter
This unconditional row-index filter drops a valid first record even when its recorded iteration meets start. For an unsteady restart with one row at each Time_Iter=100,101, rowsFrom(1, byTime=True) returns only 101. A one-row restarted history stays empty.
Please remove the rows >= 1 filter. The preceding counter >= start already implements the requested iteration threshold.
| ax.set_xlabel( | ||
| "time iterations" if byTime and self.reader.hasTime() else "iterations" | ||
| ) |
There was a problem hiding this comment.
[P3] Update the x-axis label when the counter mode changes
Switching “Time iterations” changes the x values, but it does not change the selected series, so rebuild remains false. The x-axis label therefore stays “iterations” after switching to time mode, or “time iterations” after switching back.
Please set the x-axis label outside the series-rebuild conditional so it follows the current counter mode.
|
Thanks, the original reproductions now pass, and the installation entries and dependency/launch note are present. I found three remaining issues to fix before approval and detailed them inline, along with three lower-priority corrections. Please also add the monitor tests to an automated test command so the standalone import failure is caught. The four GitHub Actions workflows are green; CodeFactor still reports failure, whose cause I have not established. |

Proposed Changes
Give a brief overview of your contribution here in a few sentences.
SU2_MON, a python based monitor to view residuals, in case you do not want to view the real time residuals in paraview.
[and my most recent pre-commit is also fixing a bunch of empty lines in unrelated python files]
related to #2879
PR Checklist
Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.
pre-commit run --allto format old commits.