diff --git a/docs/validation/leontini_viv_predeclare.md b/docs/validation/leontini_viv_predeclare.md index 26ec7e3..4cbdfb2 100644 --- a/docs/validation/leontini_viv_predeclare.md +++ b/docs/validation/leontini_viv_predeclare.md @@ -66,31 +66,39 @@ this page is jointly agreed. Clocks: lattice dt = 1; T_n = 1/f_n = 5,000 steps. Response cycles are counted from the measured signal; T_n is used only for the seed check. -- Start (source-faithful): fluid at rest except the uniform inlet, body at - rest at the declared centre, y_0 = v_0 = 0, F_last = 0. +- Start: body at rest at the declared centre (the only initial condition the + source states), y_0 = v_0 = 0, F_last = 0; fluid at rest except the uniform + inlet (our choice; the source gives no fluid initial condition). - Seed (conditional, one time, declared): at step n_seed = 200,000 (t = 40 T_n), if max |y| over steps [175,000, 200,000) is below .01 D, then in that step, after the check and before the candidate update, set v_n += 2 pi f_n (.01 D) (F_last unchanged) and proceed normally; the geometry moves continuously through the update. `seed_applied`, step and size are logged; never repeated or changed. -- Cycle boundary (discrete): step n closes a cycle iff y[n−1] < m and - y[n] ≥ m, where m = time-mean of y over the previous completed cycle - (m = 0 before the first completed cycle); y_0 = 0 is not a crossing, and no - boundary is accepted fewer than 2 samples after the previous one. +- Cycle boundary (discrete, fixed threshold): step n closes a cycle iff + y[n−1] < 0 and y[n] ≥ 0 (upward crossing of the equilibrium y = 0); + y_0 = 0 is not a crossing; no boundary fewer than 2 samples after the + previous one. - Per cycle: positive peak max(y), negative peak min(y), mean offset - (time-mean of y), amplitude a = (max − min)/2. -- Budget counting: a completed cycle counts toward the 150-cycle budget only - if a ≥ .01 D (pre-seed numerical chatter does not consume it). -- Windows: adjacent non-overlapping blocks of 10 counted cycles - (1–10, 11–20, ...); W_k = mean amplitude of block k. -- Settled at the end of block k (k ≥ 2) iff W_{k−1} ≥ 1e-6 D and - |W_k − W_{k−1}| / W_{k−1} ≤ .02, and the last 5 cycle amplitudes lie - within 1 % of their mean. Otherwise not yet settled (no NaN pass). -- Scoring: the 20 counted cycles after settling. They must remain settled: - each 10-cycle block of the 20 satisfies the same 2 % (against the previous - block) and 1 % rules, else FAIL-CLOSED. Success stop: after the 20th - scoring cycle; the run does not continue to 150. + (time-mean of y), amplitude a = (max − min)/2 (the only amplitude used for + settling). +- Eligibility: a completed cycle is counted (toward the settling proof and + the 150 budget) only if a ≥ .01 D; ineligible cycles are logged, never + counted, so near-zero motion cannot settle or pass. +- Seed reset: if the seed is applied, the incomplete cycle at n_seed is + discarded and the settling proof starts empty; the 150 budget and the + native cap keep running from t = 0. +- Windows: adjacent non-overlapping blocks of 10 counted cycles; + W_k = mean amplitude of block k (W_k ≥ .01 D by eligibility, so no zero + denominator). +- Block rule R(k), k ≥ 2: |W_k − W_{k−1}| / W_{k−1} ≤ .02 and, for the last 5 + cycles of block k, max_i |a_i − ā_5| / ā_5 ≤ .01 with ā_5 their mean. +- Settled at the end of block k when R(k) holds. Scoring = the next two + blocks k+1, k+2 (20 counted cycles); both must satisfy R. If one fails, + that block becomes the new reference: the settling proof restarts from it + and continues within the caps (deterministic; no other retry). A pass + requires one complete stable 20-cycle scoring window before a cap; success + stops after its 20th cycle. - Caps (both always armed; the first hit wins and is reported): 150 counted response cycles including the 20 scoring cycles (so settling must complete by counted cycle 130) → `timeout_response_cycles`; 1,000,000 native steps @@ -102,8 +110,12 @@ counted from the measured signal; T_n is used only for the seed check. step (FAIL-CLOSED): non-finite y, v or force; |y| > 1.0 D (the tighter gate; about twice the largest reference peak, .551 D) or the ±1.5 D offset box reached; no_donor > 0; a failed upload/step/sync. -- All failures are reported as they are (no sub-iteration, no RHS or - parameter retune, no automatic second case). +- On any failure the driver stops and reports; it never retries, + sub-iterates, retunes the RHS or parameters, or starts a second case. + Device-side failures (upload/step/sync, no_donor) mark the Simulation + failed through the existing lifecycle; input rejection by `set_body` + (offset box, speed, step bound) and timeouts end the driver run without + that mark. - Target metric over the 20 scoring cycles: A_max/D = max over those cycles of max(|positive peak|, |negative peak|) about y = 0 (Qin reports "maximum amplitude"); also reported: mean amplitude, positive and negative peaks,