diff --git a/PARITY.md b/PARITY.md index a1945daa..9cd4d94f 100644 --- a/PARITY.md +++ b/PARITY.md @@ -463,11 +463,21 @@ stable control here: across seeds 1 and 3, halving its step from `0.01` to The proposed [Applications correction](https://github.com/WEC-Sim/WEC-Sim_Applications/pull/120) sets both yaw thresholds to zero and rebaselines its regression from the -archived continuous-heading source. The new full-duration gate pins that -candidate application commit, checks MATLAB 0.01/0.005 s self-change for -each seed, then independently advances the public physical Python path at -0.005 s against the refined source. Its predeclared yaw, speed, PTO torque, -wave, and work limits remain unpromoted until all three seeds pass in CI. +archived continuous-heading source. The [full-duration CI gate](https://github.com/cmudrc/wec-sim-python/actions/runs/39873398353) +pins that candidate application commit, checks MATLAB 0.01/0.005 s +self-change for each seed, then independently advances the public physical +Python path at 0.005 s against the refined source. All three seeds pass the +predeclared source and physical limits. The largest source self-changes are +`2.07e-5` rad yaw, `4.77e-6` rad/s speed, `0.573` N m PTO torque, and +`0.00654%` PTO work; waves are identical at common samples. The largest +physical Python gaps against the matched 0.005 s source are `8.27e-6` rad +yaw, `1.90e-6` rad/s speed, `0.228` N m torque, less than `1e-13` m wave, +and `0.00303%` work. These 250 s comparisons use generated phases and the +pinned HDF5 without prescribed source states, forces, or heading choices. +With threshold zero, both implementations interpolate heading coefficients +continuously; there are no discrete hold events to match. The corrected +input is under upstream review, while the original published one-degree +hold and its badge remain qualified. The remaining seed-2 source refinement uses the same pinned R2025b model, HDF5, and phase seed with only `simu.dt` changed from `0.01` to `0.005` to @@ -1191,7 +1201,7 @@ establish Python parity. | Published case(s) | Evidence and remaining work | | --- | --- | | RM3 `B2B_Case5` and `B2B_Case6`; state-space setting in `Radiation_Force_Options` | Opt-in Python state-space radiation now has full-duration independent motion gates against the pinned MATLAB fitted trajectories for all three settings. The pinned fit has negative low-frequency damping in the active joint coordinates, so these are numerical source comparisons rather than physical validation. The default Python convolution path remains separate. | -| OSWEC `PassiveYawRegression` | Three phase realizations of the published irregular hold show up to `83.6%` disagreement in 250 s PTO work after event divergence, despite source-force replay matching all six channels. Prescribing only the source heading-update sequence restores tight yaw and PTO-work gates across all three seeds. In a pinned three-step audit, MATLAB PTO work changes by `-47.8%` then `+31.9%` for seed 1 and `-19.2%` then `+102.0%` for seed 3 as `dt` halves from `0.01` to `0.005` to `0.0025` s, with identical incident waves. The opt-in `wecsim_ode4` public path now pairs the published 250 s trajectory for all three seeds with self-selected heading events. The default implicit path still diverges and a converged held-heading reference remains unestablished, so this case stays qualified. | +| OSWEC `PassiveYawRegression` | Three phase realizations of the published irregular hold show up to `83.6%` disagreement in 250 s PTO work after event divergence, despite source-force replay matching all six channels. Prescribing only the source heading-update sequence restores tight yaw and PTO-work gates across all three seeds. In a pinned three-step audit, MATLAB PTO work changes by `-47.8%` then `+31.9%` for seed 1 and `-19.2%` then `+102.0%` for seed 3 as `dt` halves from `0.01` to `0.005` to `0.0025` s, with identical incident waves. The opt-in `wecsim_ode4` public path now pairs the published 250 s trajectory for all three seeds with self-selected heading events. The default implicit path still diverges and a converged held-heading reference remains unestablished. A proposed upstream correction changes the input to continuous heading; its three-seed full-duration source-stability and independent physical Python gates pass in CI, with no discrete hold events under the corrected event rule. The original published case stays qualified until that correction is accepted. | | OSWEC `Variable_Hydro/Passive_Yaw`, published 600 s irregular sea | The [R2025b published run](https://github.com/cmudrc/wec-sim-python/actions/runs/38035515976) and Python agree on the sea, saved-state heading selection, and six excitation components, but native heading events diverge after 54.73 s. The 600 s native Python run differs by up to `0.1103` rad yaw and `9.05%` PTO work. Prescribing MATLAB's saved heading choices reduces those to `0.00868` rad and `0.0081%`; that is a diagnostic. A [matched 250 s step audit](https://github.com/cmudrc/wec-sim-python/actions/runs/38127365821) finds `0.01562` rad yaw and `2.802%` work change between MATLAB's own `0.01` and `0.005` s runs; Python versus MATLAB at `0.005` s differs by `0.01950` rad yaw and `3.590%` work. The 120 s default-solver motion limits fail over 250 s. The [fresh 600 s opt-in source-ode4 public gate](https://github.com/cmudrc/wec-sim-python/actions/runs/38411605074) independently pairs all 624 heading-event samples and passes yaw, speed, torque, and work limits. The default physical solver still differs, and MATLAB self-change makes this a qualified numerical reproduction rather than a badge-counted published physical gate. | | RM3 `Paraview_Visualization/RM3_MoorDyn_Viz` | The pinned 80 s R2025b application now exports its Traditional 1000-bin sea, both bodies, PTO, MoorDyn connection, and three fairlead tensions in a [focused source comparison](https://github.com/cmudrc/wec-sim-python/actions/runs/38084526959). On multiple independent phase realizations, Python wave elevation agrees within `1.8e-14` m and all body excitation components within `3.7e-8` N or N m. A derived 10 s run supplies every source MoorDyn connection pose and speed; replaying those through the same pinned native library reproduces all six source load components within `0.01` N or N m on both Linux and macOS. The same seeded MATLAB source motion and mooring forces are identical at all shared samples with `dtOut=0.01` and the published `0.1` s; the output interval does not explain the gap. Published-step full coupled motion remains unpaired: the original 80 s case has shown up to `234` mm float surge error across repeated random seas, while independent seed-1 and seed-2 derived seas show `191` and `20.1` mm over 10 s despite matching waves and native mooring loads on saved poses. Halving Python's physical time step from `0.01` to `0.005` s changes seed-1 surge by at most `0.35` mm, far below its source gap. A [derived full-duration fine-step gate](https://github.com/cmudrc/wec-sim-python/actions/runs/38108596566) now pairs 80 s active body and MoorDyn motion, connection loads, and PTO force: maximum float-surge and MoorDyn pitch-moment differences are `0.827` mm and `1.636` kN m against `2` mm and `2` kN m gates. The original published-step gate remains red, and the physical Python default is unchanged. A [full 801-frame R2025b VTP gate](https://github.com/cmudrc/wec-sim-python/actions/runs/38114342891) now pairs the published numerical wave, float, spar, and three-line MoorDyn scene. Python regenerates the 1,000-component sea and writes body meshes from the pinned STL files and saved MATLAB poses, while MoorDyn line frames use saved source node and tension histories. All wave point coordinates, quad connectivity, and offsets match exactly at stored VTP precision. Across both body histories, maximum matched-facet center, vertex, and geometric area differences are `1e-5` m, `1.4143e-5` m, and `1.972e-4` m². The only body `CellData` array, `CellArea`, differs by at most `1e-5` m². Across all 2,403 line pieces, connectivity and offsets match exactly; node coordinates differ by at most `1e-5` m and tensions by `0.05` N. `ground.txt` also matches. This is complete numerical VTP output parity **on source body and line histories**; independent coupled motion at the original published step remains unpaired. | | OSWEC `Desalination` | The pinned 300 s Simscape Fluids application runs under R2025b; [expanded source baseline](https://github.com/cmudrc/wec-sim-python/actions/runs/37838787789) records flap, PTO, pressure, flow, and mechanical-power traces. Its 250-bin incident sea, six flap excitation components, and body-local rod motion pair with Python over all 30,001 samples; maximum excitation error is below `1e-6` N or N m. The source Morison drag law matches 605 sampled flap states within `1e-6` N or N m after accounting for the source's logged-force sign. The source PTO actuation force exactly follows the measured cylinder force with a one-step delay over the full trajectory. Given MATLAB's inlet pressure, the Python osmotic valve and resistance reproduce all 30,001 permeate-flow values within `2.1e-12` m³/s. Given the source accumulator flow and startup pressure, the Python gas-volume and hard-stop law reconstructs all 30,001 pressure values within `1e-3` Pa using the source's backward Euler flow step. The initial inferred liquid volume is negative because the source starts its network far below the 3 MPa precharge while allowing finite hard-stop penetration. Given the source chamber pressures and rod speed, the Python ideal cylinder reproduces all 30,001 rod-force samples within `1e-7` N and both port-flow traces within `1e-12` m³/s; the measured source force has the opposite sign. The published hydraulic junction balance closes within `2e-15` m³/s, including the relief branch. The high-pressure network now advances from saved rod speed alone, without measured source pressure or branch flows. Over all 30,001 samples it gates pressure within `500` Pa (source pressure reaches 5.6 MPa), permeate, brine, and recovered flow within `1e-5` m³/s each, and relief/accumulator flow within `3e-3` m³/s each. Using the source feed flow instead, the network reconstructs the first 6001 pressure states within `0.01` Pa. This also provides a stronger prescribed-rod-motion component gate than the coupled check below. A four-valve cylinder model using the published passive-orifice settings predicts chamber pressures and rod force from Python high pressure and the saved rod speed. The pinned legacy solver alternates raw chamber pressure at the 0.01 s sample rate while valve flow remains smooth; over 20% of valve 1 samples log flow against the pressure drop. Pointwise chamber pressure and force are therefore not claimed as paired. After a 0.1 s mean, the independent rod-force error is below 100 kN RMS; net rod work differs by less than 3% over 300 s. Raw rod-force disagreement remains above 1 MN RMS. The independent 300 s Python runner now couples incident sea, flap motion, radiation memory, source-convention Morison drag, four-valve chamber force, and high-pressure dynamics. With the pinned HDF5 and published MATLAB phase seed 1, but no source forces or state trajectories as inputs, its paired gates are maximum flap-pitch error below `0.02` rad, pitch-speed error below `0.01` rad/s, body-center error below `0.1` m, rod-speed error below `0.02` m/s, high-pressure error below `40` kPa, rod-stroke error below `0.05` m, 0.1 s mean rod-force error below `150` kN RMS, and net rod-work error below `2%` over 300 s. The source-specific Morison convention and one-step PTO actuation delay are confined to this case runner. The raw chamber pressure/force artifact remains unpaired. The source also permits chamber gauge pressure below −15 MPa, so this numerical comparison is not evidence of physical cavitation behavior. The two published OSWEC PTO-Sim hydraulic crank applications are covered above. |