.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_how_to/example_extract_residuals.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_how_to_example_extract_residuals.py: Extract solver residuals to a CSV ================================= ``residuals(mesh)`` returns a workflow seeded with an ``AggregatedDataSet`` that contains one row per ``(field, solver, metric, iteration)`` tuple. This is what you pipe into ``@postProcess.Table("residuals.csv")`` to log solver performance without running ``simpleFoam`` with ``solverPerformance`` enabled separately. Residuals are populated by the running solver — a freshly loaded mesh has an empty ``solverPerformanceDict``, so this how-to demonstrates the API shape. Run it after a few solver steps for non-empty output. .. GENERATED FROM PYTHON SOURCE LINES 17-19 Open the case ------------- .. GENERATED FROM PYTHON SOURCE LINES 19-41 .. code-block:: Python import os import subprocess import pyOFTools.patch_pybfoam # noqa: F401 from pyOFTools import clone_example CASE = clone_example("damBreak") subprocess.run( ["./Allrun"], cwd=CASE, check=True, env={**os.environ}, capture_output=True, text=True, ) from pybFoam import Time, fvMesh time = Time(str(CASE.parent), CASE.name) mesh = fvMesh(time) .. GENERATED FROM PYTHON SOURCE LINES 42-44 Build and inspect the residual workflow --------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 44-58 .. code-block:: Python from pyOFTools.builders import residuals wf = residuals(mesh) dataset = wf.compute() print(f"residuals returned {len(dataset.values)} rows") if dataset.values: print("headers:", dataset.headers) for row in dataset.grouped_values[:5]: print(" ", row) else: print("(empty — solverPerformanceDict has not been populated by a solver run)") .. rst-class:: sphx-glr-script-out .. code-block:: none residuals returned 0 rows (empty — solverPerformanceDict has not been populated by a solver run) .. GENERATED FROM PYTHON SOURCE LINES 59-76 In-situ usage ------------- In practice, this is what the decorator looks like: .. code-block:: python from pyOFTools.postprocessor import PostProcessorBase from pyOFTools.builders import residuals postProcess = PostProcessorBase() @postProcess.Table("residuals.csv") def solver_residuals(mesh): return residuals(mesh) The CSV gets one row per field per inner iteration per write step — long format, trivial to pivot with pandas. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 10.574 seconds) .. _sphx_glr_download_auto_how_to_example_extract_residuals.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_extract_residuals.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_extract_residuals.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_extract_residuals.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_