// Generate a real .cymsim file with cymsimweb's CPU loop (coarse fixture config, 0.35 s, with // the acceleration record and displacement frames), for trying the viewer without a browser run. // Requires a cymsimweb checkout beside this repository: node tools/make-test-file.ts out.cymsim import fs from "node:fs"; import { buildSetup } from "../../cymsimweb/src/model/setup.ts"; import { CpuSimulator } from "../../cymsimweb/src/cpu/simulator.ts"; import { AccelerationStore, DisplacementStore } from "../../cymsimweb/src/analysis/acceleration.ts"; import { writeCymsim, type CymsimRun, type H5Module } from "../../cymsimweb/src/io/cymsimFile.ts"; import { configToYaml } from "../../cymsimweb/src/config/yaml.ts"; import { dispEveryFor } from "../../cymsimweb/src/model/simulator.ts"; const h5: H5Module = (await import("h5wasm/node")).default as unknown as H5Module; await h5.ready; const fixture = JSON.parse(fs.readFileSync(new URL("../../cymsimweb/tests/fixtures/python_reference.json", import.meta.url), "utf8")); const cfg = structuredClone(fixture.config); cfg.output.record_acceleration = true; cfg.output.displacement_rate = 1000; cfg.numerics.duration = 0.35; const setup = await buildSetup(cfg), N = setup.mesh.n; const nSamples = Math.round(0.35 * setup.fs); const dispEvery = dispEveryFor(setup.fs, cfg.output.displacement_rate); const sim = new CpuSimulator(setup, { recordAcceleration: true, dispEvery }); const acc = new AccelerationStore(N, setup.fs), disp = new DisplacementStore(N, setup.fs / dispEvery); const front: number[] = [], back: number[] = []; const energy: number[][] = []; for (let done = 0; done < nSamples; done += 1000) { const r = await sim.runChunk(Math.min(1000, nSamples - done)); front.push(...r.pressureFront); back.push(...r.pressureBack); acc.push(r.acceleration!, r.pressureFront.length, r.firstSample); r.dispFrames.forEach((w, i) => disp.push(w, r.dispSamples[i] / setup.fs)); const d = await sim.diagnostics(); energy.push([d.time, d.kinetic, d.membrane, d.bending, d.exciters, d.maxWoverH]); } const d = await sim.diagnostics(), state = await sim.exportState(); const { mesh, shell } = setup; const run: CymsimRun = { yaml: configToYaml(cfg), config: cfg, mesh: { xy: mesh.xy, z0: shell.z0Node, thickness: shell.hNode, normal: shell.normalNode, triangles: Int32Array.from(mesh.tri), area: mesh.area, boundary: Int32Array.from(mesh.boundary), nNodes: N, nElements: mesh.e }, listener: { rFront: setup.radiation.rFront, rBack: setup.radiation.rBack }, fs: setup.fs, dt: setup.dt, substeps: setup.substeps, duration: cfg.numerics.duration, nSamples: setup.nSamples, nStepsDone: state.step, complete: true, wallTime: 1.0, decimationSpan: 32, audioBaffled: Float32Array.from(front), audioUnbaffled: Float32Array.from(front.map((f, i) => f - back[i])), acceleration: acc, taps: setup.radiation.taps, displacement: { rate: disp.rate, times: disp.times, frames: disp.frames }, energy, hits: d.hits.map((h, k) => ({ time: setup.patches[k].time, kind: setup.patches[k].hit.exciter.kind, peak_force: h.peakForce, contact_time: h.contactTime, rebound_velocity: h.velocity, energy_in: 9.6, energy_out: 0.5 * setup.patches[k].mass * h.velocity ** 2 })), state, creator: "cymsimweb test", created: "", }; const out = process.argv[2] ?? "test.cymsim"; writeCymsim(h5, out, run, "cymsimweb testgen"); console.log(`${out}: ${(fs.statSync(out).size / 1048576).toFixed(1)} MB, ${N} nodes, ${nSamples} samples, ${disp.frames.length} displacement frames`);