import { describe, expect, it } from "vitest"; import { buildCompareBundle, parseCompareResult } from "../src/index"; import { relL2, runner, solve, testSpec } from "./helpers"; describe("modal versus finite differences on the same problem", () => { it("agree on displacement to about a percent and on stress to a few percent", async () => { const spec = testSpec(); // Match the modal run to the FD window and grid so frames line up spec.output.duration = spec.fd.duration; spec.output.grid = [spec.fd.nx, spec.fd.ny]; const modal = await solve(spec, "modal"); const fd = await solve(spec, "fd"); const cmpRun = await runner.run({ bundle: buildCompareBundle(), inputs: { A: modal.run.ok ? modal.run.value : 0, B: fd.run.ok ? fd.run.value : 0 }, }); expect(cmpRun.ok).toBe(true); if (!cmpRun.ok) return; const cmp = parseCompareResult(cmpRun.value); expect(cmp.w_rel_l2).toBeLessThan(0.03); expect(cmp.vm_rel_l2).toBeLessThan(0.1); // stress error exceeds displacement error, as a second derivative should expect(cmp.vm_rel_l2).toBeGreaterThan(cmp.w_rel_l2); expect(Math.abs(cmp.w_peak_a - cmp.w_peak_b) / cmp.w_peak_a).toBeLessThan(0.03); // frames compared on the shared grid expect(cmp.frames_rel_l2.length).toBe(modal.result.frames.t.length); expect(cmp.frames_diff).not.toBeNull(); // the JS-side norm of the aligned series agrees with the .m norm expect(relL2(cmp.w_a, cmp.w_b)).toBeCloseTo(cmp.w_rel_l2, 6); }); });