Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Analyze results with Python

Read a downloaded result archive with Python to extract histories, final monitored quantities, and cell-centred VTU fields.

Install the plotting and VTU dependencies if they are not already available:

python -m pip install matplotlib meshio

Read the manifest and history

Point the script at the extracted result directory:

import csv
import json
from pathlib import Path

result_directory = Path("results/baseline")

manifest = json.loads(
    (result_directory / "simulation_manifest.json").read_text(encoding="utf-8")
)
print("status:", manifest["status"])
print("files:", ", ".join(manifest["successful_files"]))

with (result_directory / "iteration_info.csv").open(newline="", encoding="utf-8") as file:
    rows = list(csv.DictReader(file))

if not rows:
    raise RuntimeError("The result has no SIMPLE iteration history")

A dry run has no physical iteration history, so handle its empty CSV separately.

Extract final monitored quantities

Monitor and CTM columns carry stable prefixes, while their suffixes come from the names and component tags in the request:

final_row = rows[-1]
final_quantities = {
    name: float(value)
    for name, value in final_row.items()
    if value
    and (name.startswith("monitor_") or name.startswith("junction_temperature_"))
}

for name, value in sorted(final_quantities.items()):
    print(f"{name}: {value:g}")

Keep the terminal status and iteration number beside these values when building a design-comparison table.

Plot residual and monitor histories

import matplotlib.pyplot as plt

iterations = [int(row["iteration"]) for row in rows]
columns = [
    name
    for name in rows[0]
    if name.startswith("residual_") or name.startswith("monitor_")
]

for name in columns:
    values = [float(row[name]) if row[name] else float("nan") for row in rows]
    plt.plot(iterations, values, label=name)

plt.xlabel("SIMPLE iteration")
plt.legend()
plt.tight_layout()
plt.show()

Plot residuals separately on a logarithmic axis when their scale hides the monitor histories.

Read cell fields

Use Meshio to preserve the exported cell data without applying point interpolation:

import meshio
import numpy as np

fluid = meshio.read(result_directory / "fluid.vtu")

temperature = np.concatenate(
    [block.reshape(-1) for block in fluid.cell_data["temperature"]]
)
velocity = np.concatenate(fluid.cell_data["velocity"], axis=0)
speed = np.linalg.norm(velocity, axis=1)

print("fluid temperature range:", temperature.min(), temperature.max())
print("maximum cell-centred speed:", speed.max())

solid.vtu uses the same access pattern, but only temperature in conducting solids is a resolved field. Insulating temperatures and solid flow fields are placeholders; CTM cells contain the final lumped junction temperature.

See also