* test(physics): add TMS Dynamics golden validation suite Cross-engine validation of Ymir force models against the TMS Dynamics 3.0 golden dataset (vessel1 VLCC). Strategy is state-in -> force-out: the golden motion trajectory is fed row by row into the matching Ymir force model and the result is compared against the golden per-force decomposition. This is integrator-independent, so it validates the force formula, not the time step. - GoldenCsv.h: header-only CSV reader (column access by name) - Vessel1Params.h: force configs mapped from vessel1.json, with the tonne->SI x1000 unit conversion documented (verified empirically to ~3e-5 on Fr_z) - TestGolden08Restoring.cpp: restoring (Fr_z, Mr_y) + heave damping (Fd_z) - Downsampled golden fixtures under tests/fixtures/golden/08_restoring/ - ymir_golden_tests target wired into tests/CMakeLists.txt Tolerances are set empirically and the residual causes are documented: the restoring divergence (up to ~6.5% Fr_z / ~13.5% Mr_y as pitch grows) is the off-diagonal hydrostatic coupling Ymir omits by design. Findings on squat (diverges ~4 orders — model gap) and the body-frame-flow forces (need TMS heading-convention mapping) are captured under docs/specs/features/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * build(tests): run C++ suite through the turbo monorepo Make core/ a pnpm workspace package so `pnpm test` (turbo run test) runs the C++ ctest suite alongside the JS vitest suites — one command for everything. - Add "core" to pnpm-workspace.yaml so turbo discovers @ymir/core - core/package.json: add a `build` script (cmake configure + compile) - core/turbo.json: override `test` to dependsOn ["build"] instead of the root's build:wasm, so native ctest does not require Emscripten; cache off (native) - scripts/run-all-tests.sh: standalone runner (cpp/js/e2e flags) for running the C++ suite without touching the wasm/emcc toolchain @ymir/core#build -> @ymir/core#test: 270/270 tests pass via turbo. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(physics): add wind golden validation + reconstruct flow convention Extends the cross-engine golden suite to wind drag (scenario 02_wind) and adds the earth->body flow conversion needed by flow-dependent forces. - GoldenFrame.h: nautToBodyFrame mirroring NavalDomain — rotates the scenario environment (speed + nautical direction) into the body frame using the golden heading, so wind/current vectors can be reconstructed from controlDict + the golden trajectory - Vessel1Params.h: vessel1Wind() config with the full Cd(angle) table - TestGolden02Wind.cpp: Fwd_x validated to ~4% across the trajectory (residual is the rho_air constant: Ymir 1.225 vs reference ~1.27); Fwd_y/Mwd_z ~0 bow-on - Fixtures for 02_wind Documents the remaining divergences with measured numbers: current OBOKATA disagrees in sign and magnitude (Fc_x -83kN vs golden +172kN — sectional-area approximation + sign convention), squat off by ~4 orders. See docs/specs/features/golden-validation/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(graphify): refresh knowledge graph after golden validation work Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(physics): align rho_air, squat sinkage, and damping norm to reference Cross-engine alignment against the TMS Dynamics 3.0 golden dataset (see docs/planning/force-model-alignment/). Verified against the reference engine sources in dynamics/nashville/src/*Forces/. - rho_air 1.225 -> 1.275 (PhysicalConstants.h): matches PhysicalProps.cpp of the reference and closes the ~4% wind gap. Wind golden test tightened to <3%. - SquatForces: fix double division by (rho*g) — the sinkage numerator is now volumetricWeight/(rho*g*L^2) (single division, matching the reference), not nabla_/(rho*g*L^2). Also use heave relative to equilibrium (z + draft) for the depth/seabed clamp, since the reference q[2] is waterline-referenced. Squat goes from ~4 orders of magnitude off to the correct order (partial: <=5% still blocked by the artificial 07 scenario depth dynamics). - DampingForces: the exponential-decay velocity norm now uses all 6 DOF (matching dampingForces/DampingForces.cpp); the surge/sway sign was already correct given Ymir's speedToWater convention. Restoring needs no change: the reference restoring is also diagonal-only, so the residual is a zero-crossing artifact, not a missing off-diagonal term. Full C++ suite: 271/271 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(physics): add force-model-alignment spec/design/tasks + findings TLC spec-driven planning for aligning all force models to the golden dataset: - spec.md: 11 requirements (FMA-01..11), tolerances, decisions - design.md: reference formula per model cross-checked with Ymir; root causes - tasks.md: atomic tasks + execution status of the first pass Records the key research corrections: restoring reference is diagonal (no off-diagonal), squat is a double-division bug, current alignment conflicts with self-propelled physics (reverted, needs speedToWater-convention resolution). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(graphify): refresh graph after force-model alignment --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 lines
337 B
JSON
12 lines
337 B
JSON
{
|
|
"name": "@ymir/core",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"scripts": {
|
|
"build": "cmake -S . -B build -G Ninja -DYMIR_BUILD_TESTS=ON -DYMIR_BUILD_APPS=OFF && cmake --build build",
|
|
"build:wasm": "bash build-wasm.sh",
|
|
"test": "ctest --test-dir build --output-on-failure",
|
|
"clean": "rm -rf build build-wasm"
|
|
}
|
|
}
|