flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
profiles_from_ckpt.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""Turn a `run_channel_18.py` CHECKPOINT into the profiles NPZ, without waiting for a chunk to end.
3
4The running sums live in the checkpoint (`acc_*`), so the campaign can be read at any moment —
5which is the point: `stats.npz` is only written when a chunk finishes, and a chunk is hours.
6
7 python profiles_from_ckpt.py runs/prod/ckpt.npz [--out stats_now.npz]
8
9It reuses `run_channel_18.py`'s own `profiles()` so there is one definition of what the profiles
10are; that import needs `peclet.flow` on the path (any build — the transformation touches no solver
11state).
12"""
13import os
14import sys
15
16import numpy as np
17
18CK = sys.argv[1] if len(sys.argv) > 1 else "runs/prod/ckpt.npz"
19OUT = sys.argv[sys.argv.index("--out") + 1] if "--out" in sys.argv else "stats_now.npz"
20
21z = np.load(CK)
22ny = int(z["ny"])
23sys.argv = [sys.argv[0], "--ny", str(ny)] # the driver reads its constants from argv
24sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
25import run_channel_18 as R # noqa: E402
26
27acc = R.new_acc()
28for k in R.KEYS:
29 acc[k] = np.array(z["acc_" + k])
30acc["_n"] = float(z["acc_n"])
31acc["_t0"] = float(z["acc_t0"])
32acc["_t1"] = float(z["acc_t1"])
33if acc["_n"] <= 0:
34 raise SystemExit(f"{CK}: no samples accumulated yet (still inside the discarded transient)")
35
36pr = R.profiles(acc)
37t = float(z["t"])
38np.savez(OUT, **{k: np.asarray(v) for k, v in pr.items()},
39 turnovers=np.float64(t * R.UTAU), step=np.int64(z["step"]),
40 grid=np.asarray([R.NX, R.NY, R.NZ]), utau=np.float64(R.UTAU))
41print(f"wrote {OUT}: {int(acc['_n'])} samples over t u_tau/h "
42 f"{pr['window_turnovers'][0]:.3f} .. {pr['window_turnovers'][1]:.3f}, "
43 f"run at {t*R.UTAU:.3f} turnovers (step {int(z['step'])})")
44print(f" u_tau: imposed {R.UTAU:.6f}, wall gradient {pr['utau_wall']:.6f} "
45 f"({100*(pr['utau_wall']/R.UTAU-1):+.1f} %; walls {pr['utau_lo']:.6f} / {pr['utau_hi']:.6f})")
46j = R.NY // 2
47print(f" centreline: <alpha> {pr['alpha'][j]:.5f}, <u>_liq/u_tau {pr['u_liq'][j]/R.UTAU:.3f}")
48k = int(np.argmax(pr['u_liq']))
49print(f" peak <u>_liq/u_tau {pr['u_liq'][k]/R.UTAU:.3f} at y/h = {pr['y'][k]:.3f}")