research: VIV driver — exact seed window, error status, no overwrite, bounded smoke flag
Seed quiet check reads states y_t, t in [n_seed - 5 T_n, n_seed); an exception sets status 'error: ...' before the report is written; an output directory that already holds report.json or steps.npy is refused; --max-steps gives a plumbing smoke that is never scored. Predeclare states the code's actual uniform-U fluid initial condition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f08b5e671f
commit
bb83b3476d
@@ -40,14 +40,22 @@ def config(D=D, U=U):
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--out", required=True)
|
||||
ap.add_argument("--max-steps", type=int, default=0,
|
||||
help="plumbing smoke only: stop after N steps; never scored")
|
||||
args = ap.parse_args()
|
||||
if os.path.realpath(args.out).startswith(os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))):
|
||||
raise SystemExit("--out must be outside the checkout")
|
||||
os.makedirs(args.out, exist_ok=True)
|
||||
for name in ("report.json", "steps.npy"): # never overwrite earlier evidence
|
||||
if os.path.exists(os.path.join(args.out, name)):
|
||||
raise SystemExit(f"{args.out} already holds {name}; use a fresh output directory")
|
||||
cfg, nx, ny = config()
|
||||
s, cyc = viv.Structure(D, U), viv.Cycles(D)
|
||||
T_n = 1.0 / s.f_n
|
||||
step_cap, n_seed = int(round(viv.STEP_CAP_TN * T_n)), int(round(viv.SEED_TN * T_n))
|
||||
quiet = int(round(5 * T_n))
|
||||
if args.max_steps:
|
||||
step_cap = min(step_cap, args.max_steps)
|
||||
centre = (30.0 * D, 0.5 * (ny - 1))
|
||||
|
||||
from CelerisLab.body.motion import Translation
|
||||
@@ -61,7 +69,8 @@ def main():
|
||||
translation=Translation((0.0, 0.0, -1.5 * D, 1.5 * D), 0.5))
|
||||
sim.initialize()
|
||||
for n in range(step_cap):
|
||||
if n == n_seed and max((abs(r[1]) for r in rows[-int(5 * T_n):]), default=0.0) < viv.ELIGIBLE * D:
|
||||
# rows[k] holds the state y_{k+1}; the declared window is y_t, t in [n_seed - 5 T_n, n_seed)
|
||||
if n == n_seed and max(abs(r[1]) for r in rows[n_seed - quiet - 1:n_seed - 1]) < viv.ELIGIBLE * D:
|
||||
s.v += s.seed_velocity(D) # after the quiet check, before the update
|
||||
seed_step = n
|
||||
cyc.discard_current()
|
||||
@@ -92,14 +101,17 @@ def main():
|
||||
status = "timeout_response_cycles"
|
||||
break
|
||||
else:
|
||||
status = "timeout_native_steps"
|
||||
status = "smoke_stopped" if args.max_steps else "timeout_native_steps"
|
||||
except BaseException as exc:
|
||||
status = f"error: {exc!r}"
|
||||
raise
|
||||
finally:
|
||||
np.save(os.path.join(args.out, "steps.npy"), np.asarray(rows, float))
|
||||
report = dict(status=status, steps=len(rows), t_U_over_D=len(rows) * U / D, T_n=T_n,
|
||||
report = dict(status=status, smoke=bool(args.max_steps), steps=len(rows), t_U_over_D=len(rows) * U / D, T_n=T_n,
|
||||
seed_step=seed_step, counted_cycles=cyc.counted, cycles=cyc.log,
|
||||
columns=["n", "y", "v", "F_rhs_cme_wen", "F_cme", "F_wen", "F_obs",
|
||||
"node_cover_minus_uncover_y", "no_donor"])
|
||||
if status == "scored":
|
||||
if status == "scored" and not args.max_steps:
|
||||
report["score"] = viv.score(cyc.window)
|
||||
with open(os.path.join(args.out, "report.json"), "w") as fh:
|
||||
json.dump(report, fh, indent=1)
|
||||
|
||||
Reference in New Issue
Block a user