/ proof-of-concept / cymsimweb
Sign in
proof-of-concept / cymsimweb
export .cymsim file
Jeremy Magland <jmagland@flatironinstitute.org> committed commit 13f4dbdc9e86 parent 6d7f34a Browse files
23 changed files+1121−251
README.mdmodified+6−3View file
@@ -13,12 +13,14 @@ Requires Node 20 or later and, for the GPU time loop, a browser with WebGPU (Chr
1313
1414 ## Using the app
1515
16-The sidebar holds the preset selector, YAML import and download, the run controls, and three tabs: the YAML editor, a form with the same fields, and the set-up summary of the last run. The YAML schema is that of the Python package (the same file runs in both), and the four presets are its example configurations. Edits in the form rewrite the YAML and edits in the YAML rebuild the form; unknown fields, wrong types and out-of-range values are listed under the editor, and a run does not start while issues remain. Omitted fields take the defaults, which describe an 18 inch medium-thin B20 crash.
16+The sidebar holds the preset selector, YAML import and download, the `.cymsim` load and export buttons, the run controls, and three tabs: the YAML editor, a form with the same fields, and the set-up summary of the last run. The YAML schema is that of the Python package (the same file runs in both), and the four presets are its example configurations. Edits in the form rewrite the YAML and edits in the YAML rebuild the form; unknown fields, wrong types and out-of-range values are listed under the editor, and a run does not start while issues remain. Omitted fields take the defaults, which describe an 18 inch medium-thin B20 crash.
1717
1818 Start builds the set-up and begins the run. The main area shows the cymbal as a lit height field (drag to orbit, wheel to zoom, the exaggeration slider scales the displacement), the spectrogram of the listener signal growing as chunks of audio arrive, and a playback bar.
1919
2020 **Displacement movie.** During a run the transverse displacement of every node is captured at the frame rate in the plate toolbar (2000 frames per second of simulated time by default; 0 disables capture). Afterwards Replay plays those frames back in the plate view, slowed down by the factor on the slider (x50 by default, up to x10000), and the position slider scrubs through them. A frame is stored as one 16-bit value per node against that frame's own peak, so a 2 s run of the default 4657-node mesh at 2000 fps is about 19 MB; capture stops at 256 MB and the toolbar says so. The lowest modes of an 18 inch crash are a few hundred hertz, so x200 to x500 is about right for watching individual cycles, and x2000 or more for the contact itself.
2121
22+**Saving and loading runs (.cymsim).** Export writes the run so far as a `.cymsim` file, an HDF5 file specified in cymsim's [docs/format.md](https://vault1.magland.org/proof-of-concept/cymsim): the YAML configuration, the mesh with its nodal normals, the listener geometry, the baffled and unbaffled listener signals, transverse displacement frames at `output.displacement_rate` (default 60 fps of simulated time), the energy log and hit table, and the integrator state. With `output.record_acceleration: true` (off by default) the file also holds the normal acceleration of every node at the audio rate, stored as int16 with a scale per sample, which is what another program needs to compute the sound for other listeners, rooms or radiation models; it costs about 0.4 GB per simulated second at the default mesh, the app states the size before the run starts, warns above 1 GB and refuses above the device's limit. A run that is still going is paused between chunks while the file is built and continues afterwards, so a partial run can be saved at any time. Load reads a `.cymsim` file written by this app or by the Python package: the configuration goes into the editor, the sound into the spectrogram and playback, the displacement frames into the plate view (Replay and the position slider work at the file's frame rate), and the records stay in memory so that the run can be exported again. A partial file written by this app on the same backend can be continued with Resume. See [THEORY.md](THEORY.md), section 8.
23+
2224 **Spectrogram axis.** The frequency axis is linear by default, which shows the upper partials and the noise floor of a crash as they are spaced; the scale selector switches to logarithmic, and the max-f selector zooms the axis to 20, 10, 5 or 2 kHz. Play plays the part of the signal that exists so far from the slider position and stops where the signal ends; press again to hear newer material. The signal selector switches between the unbaffled estimate (front minus diffracted back, the default) and the baffled Rayleigh integral; the WAV download writes the selected one at 16 bits, normalized to 0.9 full scale or at 1 Pa = 0.05 full scale. Under the views, the energy table (kinetic, membrane, bending, exciters, and the nonlinearity meter max|w|/h) and the hit table (peak force, contact time, exciter velocity) update about once a second, and the log reports the set-up and the run.
2325
2426 URL parameters: `?preset=<id>` selects a preset (`crash_mallet`, `crash_stick`, `hit_train`, `quick_cpu`), `backend=cpu` forces the CPU loop, `autostart=1` starts on load, `chat=1` opens the chat panel, `bridge=ws://host:port` points it at a bridge other than `ws://localhost:8765`.
@@ -40,7 +42,7 @@ At the default resolution (6 mm elements, about 4700 nodes, 54 sub-steps per aud
4042
4143 ## Tests
4244
43-`npm run test:cpu` runs the node:test files: the mesher (manifold, quality, and exact agreement with the Python mesher), the DKT element against the Python element, the shell assembly (mass, stability bound, rigid modes and element checks against Python), the CPU time loop against a Python run (dent-free geometry, float64: peak force, contact time, rebound velocity and energies to 1e-4 in the linear case, and the listener pressure to a few percent rms), the YAML layer, and the STFT. `npm run test:gpu` runs the same WGSL kernels under Node with Google Dawn (the `webgpu` package, software backend) and compares them with the CPU loop. It is a plain script rather than a node:test file because Dawn aborts under the test runner. The reference numbers in `tests/fixtures/python_reference.json` were produced by the Python package.
45+`npm run test:cpu` runs the node:test files: the mesher (manifold, quality, and exact agreement with the Python mesher), the DKT element against the Python element, the shell assembly (mass, stability bound, rigid modes and element checks against Python), the CPU time loop against a Python run (dent-free geometry, float64: peak force, contact time, rebound velocity and energies to 1e-4 in the linear case, the listener pressure and the recorded node accelerations to 1e-3 rms), the decimation kernel against Python's, the YAML layer, the STFT, and the .cymsim file (a round trip through h5wasm, and, when `python -c "import cymsim"` works, a file written here loaded by Python and a Python file loaded here). `npm run test:gpu` runs the same WGSL kernels under Node with Google Dawn (the `webgpu` package, software backend) and compares them with the CPU loop, including the acceleration record, the displacement frames and a run continued from an exported state. It is a plain script rather than a node:test file because Dawn aborts under the test runner. The reference numbers in `tests/fixtures/python_reference.json` were produced by the Python package (`python tools/make_web_fixture.py` there refreshes the run-dependent parts).
4446
4547 ## Layout
4648
@@ -50,7 +52,8 @@ At the default resolution (6 mm elements, about 4700 nodes, 54 sub-steps per aud
5052 | `src/model/` | seeded RNG, cymbal geometry, mesher, DKT element, shell assembly, element forces and energies, exciters, radiation, set-up |
5153 | `src/cpu/` | float64 reference time loop, also the fallback without WebGPU |
5254 | `src/gpu/` | WGSL kernels and the WebGPU driver |
53-| `src/analysis/`, `src/audio/` | incremental STFT and band summary, the displacement-movie store and player; Web Audio playback and WAV export |
55+| `src/analysis/`, `src/audio/` | incremental STFT and band summary, the displacement-movie store and player, the acceleration and displacement records; Web Audio playback and WAV export |
56+| `src/io/` | the .cymsim (HDF5) file, written and read with h5wasm |
5457 | `src/ui/`, `src/run.ts`, `src/main.ts` | editor, form, plate and spectrogram views, readouts, chat panel, the run loop, wiring |
5558 | `src/chat/`, `bridge/` | WebSocket client of the bridge and the tool executor; the local Claude Code bridge (Agent SDK) |
5659 | `tests/` | node:test files, the Dawn check, and the Python fixture |
THEORY.mdmodified+17−7View file
@@ -40,17 +40,19 @@ Because the projection is applied one step late, the state carries at any time t
4040
4141 The partial sums of two consecutive steps live in two halves of one buffer selected by the parity of the step, so the node pass reads one half while writing the other. The step counter is kept in two slots: the element pass copies slot A to slot B, the node pass reads slot B and writes A + 1 to slot A. Every kernel thus reads a slot that no thread of the same dispatch writes, and no uniform has to be updated per dispatch; a chunk of thousands of sub-steps is encoded as one compute pass with only pipeline switches and dispatches.
4242
43-## 4. Radiation at the audio rate
43+## 4. Radiation at the audio rate, and the acceleration record
4444
45-The Python package scatters every element's acceleration into retarded-time buffers at sub-step resolution and decimates the result to the audio rate with a polyphase FIR. A scatter with per-element delays needs atomics or a per-element history far too long to keep at sub-step resolution (about 300 MB at the default resolution), so the web application reverses the order: each element's acceleration is first decimated to the audio rate, then delayed and summed.
45+The Python package scatters every element's acceleration into retarded-time buffers at sub-step resolution and decimates the result to the audio rate. A scatter with per-element delays needs atomics or a per-element history far too long to keep at sub-step resolution (about 300 MB at the default resolution), so the web application reverses the order: the acceleration is first decimated to the audio rate, then delayed and summed.
4646
47-The decimation is a Blackman-windowed sinc with cutoff $0.45 f_s$ spanning eight audio samples, applied through eight accumulator slots per element: at sub-step phase $k$ of audio sample $j_0$ the element adds its acceleration times the tap $h_w(k)$ to slot $w$, which belongs to audio sample $j_0 + w - 3$; when a sample is complete its slot is written to a per-element history ring (of length a little more than the longest delay in audio samples) and the slots shift. A triangular window over two samples was tried first and was found insufficient in the linear reference run, whose sharp contact puts energy above the audio band. The gather is one dispatch of a single workgroup per audio sample: every element's history is read at $j - \lfloor d_e \rfloor$ and $j - \lfloor d_e \rfloor - 1$ with the fractional delay applied by linear interpolation, for the front path and for the path over the rim, and the two sums are reduced in shared memory and written to the chunk's output buffer. Linear interpolation of a fractional delay attenuates the top of the band slightly (up to a few dB at 20 kHz for a half-sample fraction, spread over the elements' different fractions), which we accept for an interactive tool.
47+The quantity that is decimated is the same as in Python: the *normal* acceleration of every node, $a_i = n_i \cdot (\ddot u_i, \ddot v_i, \ddot w_i)$ with $n_i$ the unit normal of the rest surface at the node (section 7 of cymsim's model.md), taken as the difference of consecutive *projected* velocities divided by $\Delta t$, which for the leapfrog scheme is the exact central second difference of $q$. The decimation kernel is also the same: a Kaiser-windowed sinc spanning $W = 32$ audio samples ($\beta = 8$, $-6$ dB at $0.46 f_s$, below $-80$ dB from $0.54 f_s$; `decimationKernel` in `src/model/radiation.ts` reproduces `cymsim.decimation.decimation_kernel` to $10^{-16}$). It is applied in the node pass through $W$ accumulator slots per node: at sub-step phase $k$ of audio sample $j_0$ the node adds $a_i$ times the tap $h_w(k)$ to slot $w$, which belongs to audio sample $j_0 + w - W/2 + 1$ and lives at ring position (sample mod $W$). When the sub-step count crosses a sample boundary the oldest slot is complete: its value is written to a per-node history ring (a little longer than the longest delay in audio samples), to the chunk's acceleration output when the record is on, and the slot is cleared for the newest sample. This costs $W$ multiply-adds per node per sub-step and $W N$ floats of state, and it needs no atomics because each node owns its slots. The finished node samples are what the `.cymsim` file stores (section 8).
4848
49-The acceleration that radiates is the difference of consecutive *projected* transverse velocities. With the lagged projection, the difference of raw velocities would contain the full rigid acceleration $f_{rigid}/M$ at every step, since each step adds it and the next removes it; a plate that appears to accelerate as a whole radiates like a monopole, which is exactly the component that the front and back terms of an unbaffled plate are meant to cancel. This error was invisible in the nonlinear run and a factor 4.6 in the rms pressure of the linear reference run, where the cancellation is 25:1. With the projected differences the two implementations agree to 0.1 percent in rms in both runs.
49+The gather is one dispatch of a single workgroup per finished audio sample $j$. Each thread first forms the element means of the node sample from the node history and writes them to a per-element history ring, then reads its elements' histories at the fractional delays of the front path and of the path over the rim with a 16-tap Kaiser-windowed-sinc interpolator (`fractionalDelayTaps`), and the two sums are reduced in shared memory and written to the chunk's output buffer. The interpolator replaces the linear interpolation of the first version, which attenuated the top of the band by a few dB at a half-sample fraction. Against the Python package, whose delays are applied at sub-step resolution before the same decimation, the listener pressure now agrees to $3 \times 10^{-4}$ relative rms on the test configuration (it was a few percent), and the recorded node accelerations to about $10^{-4}$, the int16 quantisation of the record included.
50+
51+The acceleration that radiates is the difference of consecutive *projected* velocities. With the lagged projection, the difference of raw velocities would contain the full rigid acceleration $f_{rigid}/M$ at every step, since each step adds it and the next removes it; a plate that appears to accelerate as a whole radiates like a monopole, which is exactly the component that the front and back terms of an unbaffled plate are meant to cancel. This error was invisible in the nonlinear run and a factor 4.6 in the rms pressure of the linear reference run, where the cancellation is 25:1.
5052
5153 ## 5. Buffers and precision
5254
53-The GPU keeps eleven storage buffers, at most eight in any one pipeline (the default WebGPU limit): per-element data (CST operators, area, slopes, membrane stiffness, damping factor and the 81 entries of $K_e$, 96 floats per element, with the decimation taps at the tail), element node indices, the state (q, v, the radiated nodal acceleration and the previous projected velocity), the element forces, per-node data (inverse mass, mass and the six rigid modes, 40 floats per node), the adjacency in CSR form, the hits (static patch data and the exciter state, one float and one integer buffer), the synchronization buffer (step counters and partial sums), the radiation state (accumulator slots and history) and the radiation coefficients. Everything on the GPU is float32. The set-up is float64 and is packed once. Diagnostics (energies, exciter state) are read back between chunks; the plate view reads $w$ from the state buffer directly in its vertex shader without a readback.
55+The GPU keeps the set-up and the state in storage buffers, at most eight in any one pipeline (the default WebGPU limit): per-element data (CST operators, area, slopes, membrane stiffness, damping factor and the 81 entries of $K_e$, 96 floats per element), element node indices, the state (q, v and the previous projected $(u, v, w)$ velocities, 13 floats per node), the element forces, per-node data (inverse mass, mass, the six rigid modes and the nodal normal, 44 floats per node, with the decimation taps at the tail), the adjacency in CSR form, the hits (static patch data and the exciter state, one float and one integer buffer), the synchronization buffer (step counters and partial sums), the radiation buffer (the $W N$ accumulator slots, the node history, and the chunk's acceleration output rows when recording), the element history, the radiation coefficients (delays and interpolator taps, 36 floats per element) and the chunk's pressure output. A uniform holds the chunk's sample and frame bases. Everything on the GPU is float32. The set-up is float64 and is packed once. Diagnostics (energies, exciter state) are read back between chunks; the plate view reads $w$ from the state buffer directly in its vertex shader without a readback. The whole integrator state (state, sync, hits, radiation and element-history buffers, plus the step count) can be read back and written again, which is how a partial `.cymsim` file is continued.
5456
5557 Float32 is adequate for the leapfrog at these step sizes: the displacement increment per step is about $10^{-3}$ of the displacement, so the update loses a few bits per step in $q$ without a visible effect on the energy balance, and the run is chaotic anyway once max|w|/h exceeds a few units, so no float32 trajectory tracks a float64 one for long. What is checked is the deterministic part (section 6).
5658
@@ -60,7 +62,7 @@ The tests compare three implementations pairwise on a coarse dent-free 18 inch p
6062
6163 TypeScript set-up against Python: the mesh is identical to round-off; the DKT stiffness agrees with the autodiff element to $10^{-9}$; mass, stability bound, limiting element, element stiffnesses, lumped masses and rigid modes agree to $10^{-8}$ or better; the contact patch (nodes, weights, offsets, stiffness, free contact time) agrees to $10^{-6}$.
6264
63-CPU loop against Python (float64 both): in the linear run the peak force and rebound velocity agree to $10^{-5}$, the energies and max|w|/h to $10^{-4}$, the rms of the unbaffled pressure to 0.1 percent; in the nonlinear run, where the trajectory is sensitive, the same quantities agree to $10^{-3}$ and the pressure to 0.2 percent rms with the peaks at the same sample.
65+CPU loop against Python (float64 both): in the linear run the peak force and rebound velocity agree to $10^{-5}$, the energies and max|w|/h to $10^{-4}$; in the nonlinear run, where the trajectory is sensitive, the same quantities agree to $10^{-3}$. The unbaffled and baffled pressures agree to $2$ to $3 \times 10^{-4}$ relative rms in both runs, and the recorded normal accelerations of individual nodes to about $10^{-4}$ (the test requires $10^{-3}$); the only remaining differences are the delay applied at sub-step resolution in Python against the 16-tap interpolator here, and the int16 quantisation of the record. The decimation taps agree to $10^{-16}$.
6466
6567 GPU kernels against the CPU loop (float32 against float64, under Dawn): peak force to $10^{-4}$, contact time to the step, energies to $10^{-3}$ and the pressure to $10^{-3}$ relative rms in the linear run; $10^{-3}$, $10^{-2}$ and $10^{-2}$ in a short nonlinear run.
6668
@@ -70,6 +72,14 @@ The plate view reads `w` straight from the simulation's state buffer while a run
7072
7173 Frames are stored quantized to 16 bits against each frame's own peak, which costs 2 bytes per node per frame and keeps the relative error near 1e-4 of that frame's amplitude, far below what the colour map and the height exaggeration resolve. The default 2000 fps resolves the low modes of a crash (a few hundred hertz) with several samples per cycle; the contact itself, a few milliseconds long, needs 5000 fps or more. Replay is driven by `requestAnimationFrame` against wall time divided by the slowdown factor, so the same frames play correctly on any display: the player advances simulated time by the elapsed wall time over the factor and shows the nearest captured frame, rather than stepping one frame per repaint.
7274
73-## 8. Limitations
75+## 8. The .cymsim file
76+
77+A run can be saved at any time, complete or not, as a `.cymsim` file, an HDF5 file whose layout is specified in cymsim's [docs/format.md](https://vault1.magland.org/proof-of-concept/cymsim). It holds the configuration as YAML, the mesh with its nodal normals, the listener geometry, the two listener signals, the transverse displacement at a low frame rate (`output.displacement_rate`, default 60 Hz; a strobe for display, not a signal), optionally the normal acceleration of every node at the audio rate (`output.record_acceleration`, default off), the energy log, the hit summaries, and this application's integrator state. The file is written with h5wasm (libhdf5 compiled to WebAssembly, loaded on first use) into an in-memory image that is then downloaded, so at export time the memory in use briefly doubles; a running simulation is paused between chunks while the file is built, so that the state and the records are consistent, and continues afterwards.
78+
79+The acceleration record is the reason for the file: it is what another program needs to compute the sound of the simulated cymbal for listeners, rooms or radiation models other than the built-in one, and it must not be derived from stored displacements (a second difference multiplies noise by $\omega^2$ and folds the shell's ultrasonic content into the band). It is the same audio-rate normal acceleration that feeds the listener sum (section 4), quantised to int16 against one float32 scale per sample, so that a stroke's 90 dB of decay keeps its precision; the relative error of a node is at most $1.5 \times 10^{-5}$ of the sample's peak. The cost is $2 N f_s$ bytes per simulated second, about 0.4 GB per second at the default mesh, kept in memory in blocks as the chunks arrive; the app estimates the size before a run starts, warns above 1 GB and refuses above half the device memory (or 2 GB when the browser does not say). The chunk size is reduced so that a chunk's rows stay under 64 MB on the GPU. The Python test suite rebuilds the baffled listener signal from such a record alone, with a band-limited fractional delay, to $1.5 \times 10^{-4}$ relative rms.
80+
81+Loading a file restores the editor, the spectrogram and playback, the displacement frames (which also serve as the replay movie, at the file's frame rate), the energy and hit tables and the acceleration record, so that a loaded run can be exported again. A partial file written by this application on the same backend (GPU or CPU) can be continued with Resume, which rebuilds the set-up from the configuration, writes the saved state back into the buffers and runs on, appending to the signals and records; a float32 state reproduces the uninterrupted run only to float32 precision, which in the chaotic regime means the same statistics rather than the same waveform. Files written by the Python package load in the same way; their state group belongs to the Python integrator and is ignored, and their runs cannot be continued here.
82+
83+## 9. Limitations
7484
7585 The limitations of the model are those listed in the Python documentation. Specific to the web application: the imperfections of a seed differ from Python's; the decimation and the fractional delays are approximations described in section 4; the plate view shows $w$ scaled by a user-chosen factor and is not a measurement; the movie is capped at 256 MB, after which capture stops silently apart from a note in the toolbar, and its frames are quantized as described in section 7; and the CPU fallback is a hundred times slower than a discrete GPU. The set-up runs on the main thread and freezes the page for a second or two at full resolution.
index.htmlmodified+6−0View file
@@ -23,10 +23,16 @@
2323 <input id="file" type="file" accept=".yaml,.yml,text/yaml" hidden />
2424 <button id="download-yaml">Download YAML</button>
2525 </div>
26+ <div class="row buttons">
27+ <button id="load-cymsim" title="load a saved run (.cymsim, HDF5): configuration, sound, displacement frames, and the acceleration record if it has one">Load .cymsim</button>
28+ <input id="file-cymsim" type="file" accept=".cymsim" hidden />
29+ <button id="export-cymsim" disabled title="save the run so far as a .cymsim file (a running simulation pauses while the file is built)">Export .cymsim</button>
30+ </div>
2631 <div class="row buttons">
2732 <button id="start" class="primary">Start</button>
2833 <button id="pause" disabled>Pause</button>
2934 <button id="stop" disabled>Stop</button>
35+ <button id="resume" disabled title="continue the run of a loaded partial .cymsim file written by this app">Resume</button>
3036 </div>
3137 <div class="row"><progress id="progress" value="0" max="1"></progress><span id="progress-text"></span></div>
3238 <div id="backend" class="muted"></div>
package-lock.jsonmodified+7−0View file
@@ -15,6 +15,7 @@
1515 "@codemirror/state": "^6.7.4",
1616 "@codemirror/view": "^6.43.11",
1717 "@lezer/highlight": "^1.2.3",
18+ "h5wasm": "^0.10.3",
1819 "js-yaml": "^4.1.0",
1920 "ws": "^8.21.3",
2021 "zod": "^4.6.5"
@@ -1853,6 +1854,12 @@
18531854 "url": "https://github.com/sponsors/ljharb"
18541855 }
18551856 },
1857+ "node_modules/h5wasm": {
1858+ "version": "0.10.3",
1859+ "resolved": "https://registry.npmjs.org/h5wasm/-/h5wasm-0.10.3.tgz",
1860+ "integrity": "sha512-W4Jy5ExtX/VNbyD8GdOBckDuj6AL16TemppVNxZsV3rJZEWCv2sxlCzOttZLer3zkMttbDYsWHl0qt1z3Bln+Q==",
1861+ "license": "SEE LICENSE IN LICENSE.txt"
1862+ },
18561863 "node_modules/has-symbols": {
18571864 "version": "1.1.0",
18581865 "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
package.jsonmodified+1−0View file
@@ -29,6 +29,7 @@
2929 "@codemirror/state": "^6.7.4",
3030 "@codemirror/view": "^6.43.11",
3131 "@lezer/highlight": "^1.2.3",
32+ "h5wasm": "^0.10.3",
3233 "js-yaml": "^4.1.0",
3334 "ws": "^8.21.3",
3435 "zod": "^4.6.5"
src/analysis/acceleration.tsadded+67−0View file
@@ -0,0 +1,67 @@
1+// In-memory record of the audio-rate normal acceleration of every node, quantized to int16
2+// against one float32 scale per sample, exactly the encoding of the .cymsim file (see
3+// cymsim/docs/format.md, section 6), so that exporting copies blocks without re-encoding and
4+// loading keeps the file's blocks as they are. Recording is opt-in (output.record_acceleration):
5+// at the default mesh it costs about 0.4 GB per simulated second.
6+
7+export interface AccelerationBlock { first: number; count: number; data: Int16Array; scale: Float32Array }
8+
9+export class AccelerationStore {
10+ readonly nodes: number; readonly fs: number;
11+ readonly blocks: AccelerationBlock[] = [];
12+ nSamples = 0;
13+
14+ constructor(nodes: number, fs: number) { this.nodes = nodes; this.fs = fs; }
15+
16+ get bytes() { return this.nSamples * (2 * this.nodes + 4); }
17+
18+ /** Bytes a full record of ``nSamples`` samples takes in memory and in the file. */
19+ static estimateBytes(nSamples: number, nodes: number): number { return nSamples * (2 * nodes + 4); }
20+
21+ /** Encode ``count`` rows of float accelerations (row-major, N per row) that continue the record at ``first``. */
22+ push(rows: Float32Array, count: number, first: number) {
23+ if (count <= 0) return;
24+ if (first !== this.nSamples) throw new Error(`acceleration record is not contiguous: got sample ${first}, expected ${this.nSamples}`);
25+ const N = this.nodes, data = new Int16Array(count * N), scale = new Float32Array(count);
26+ for (let r = 0; r < count; r++) {
27+ let peak = 0;
28+ const b = r * N;
29+ for (let i = 0; i < N; i++) { const a = Math.abs(rows[b + i]); if (a > peak) peak = a; }
30+ const s = peak > 0 ? peak / 32767 : 0;
31+ scale[r] = s;
32+ if (s > 0) for (let i = 0; i < N; i++) data[b + i] = Math.round(rows[b + i] / s);
33+ }
34+ this.blocks.push({ first, count, data, scale }); this.nSamples += count;
35+ }
36+
37+ /** Append an already encoded block (from a file). */
38+ pushEncoded(data: Int16Array, scale: Float32Array) {
39+ const count = scale.length;
40+ if (count === 0) return;
41+ if (data.length !== count * this.nodes) throw new Error("encoded acceleration block has the wrong size");
42+ this.blocks.push({ first: this.nSamples, count, data, scale }); this.nSamples += count;
43+ }
44+
45+ /** Decoded accelerations [m/s^2] of samples [j0, j1), row-major. */
46+ read(j0: number, j1: number): Float32Array {
47+ j0 = Math.max(0, j0); j1 = Math.min(this.nSamples, j1);
48+ const N = this.nodes, out = new Float32Array(Math.max(0, j1 - j0) * N);
49+ for (const b of this.blocks) {
50+ const lo = Math.max(j0, b.first), hi = Math.min(j1, b.first + b.count);
51+ for (let j = lo; j < hi; j++) {
52+ const s = b.scale[j - b.first], src = (j - b.first) * N, dst = (j - j0) * N;
53+ for (let i = 0; i < N; i++) out[dst + i] = b.data[src + i] * s;
54+ }
55+ }
56+ return out;
57+ }
58+}
59+
60+/** The transverse displacement frames kept for the .cymsim file (a strobe for display, not a signal). */
61+export class DisplacementStore {
62+ readonly nodes: number; readonly rate: number;
63+ readonly times: number[] = []; readonly frames: Float32Array[] = [];
64+ constructor(nodes: number, rate: number) { this.nodes = nodes; this.rate = rate; }
65+ push(w: Float32Array, time: number) { if (w.length === this.nodes) { this.frames.push(w); this.times.push(time); } }
66+ get bytes() { return this.frames.length * this.nodes * 4; }
67+}
src/config/schema.tsmodified+6−2View file
@@ -23,7 +23,11 @@ export interface Numerics {
2323 fs: number; duration: number; cfl_safety: number; rot_inertia_factor: number; inplane_mass_scale: number;
2424 steps_per_block: number; dtype: string; nonlinear: boolean; n_progress: number;
2525 }
26-export interface Output { prefix: string; wav: boolean; npz: boolean; cascade_plot: boolean }
26+export interface Output {
27+ prefix: string; wav: boolean; npz: boolean; cascade_plot: boolean;
28+ record_acceleration: boolean; // keep the normal acceleration of every node at the audio rate (large; off by default)
29+ displacement_rate: number; // frames per second of transverse displacement kept in the .cymsim file; 0 = none
30+}
2731 export interface SimulationConfig {
2832 material: Material; profile: Profile; imperfections: Imperfections; mesh: MeshConfig; hits: Hit[];
2933 listener: Listener; numerics: Numerics; output: Output;
@@ -49,7 +53,7 @@ export const defaultNumerics = (): Numerics => ({
4953 fs: 44100, duration: 2, cfl_safety: 0.6, rot_inertia_factor: 1 / 64, inplane_mass_scale: 1, steps_per_block: 20000,
5054 dtype: "float32", nonlinear: true, n_progress: 20,
5155 });
52-export const defaultOutput = (): Output => ({ prefix: "crash", wav: true, npz: true, cascade_plot: true });
56+export const defaultOutput = (): Output => ({ prefix: "crash", wav: true, npz: true, cascade_plot: true, record_acceleration: false, displacement_rate: 60 });
5357 export const defaultConfig = (): SimulationConfig => ({
5458 material: defaultMaterial(), profile: defaultProfile(), imperfections: defaultImperfections(), mesh: defaultMesh(),
5559 hits: [defaultHit()], listener: defaultListener(), numerics: defaultNumerics(), output: defaultOutput(),
src/config/yaml.tsmodified+1−0View file
@@ -87,6 +87,7 @@ export function validateConfig(cfg: SimulationConfig): Issue[] {
8787 if (!(cfg.mesh.element_size > 0 && cfg.mesh.element_size <= p.radius / 2)) issues.push({ path: "mesh.element_size", message: "must be positive and well below the radius" });
8888 if (!(n.duration > 0)) issues.push({ path: "numerics.duration", message: "must be positive" });
8989 if (!(n.fs >= 8000 && n.fs <= 192000)) issues.push({ path: "numerics.fs", message: "must lie between 8000 and 192000 Hz" });
90+ if (!(cfg.output.displacement_rate >= 0)) issues.push({ path: "output.displacement_rate", message: "must be non-negative" });
9091 if (!(p.radius > 0 && p.h_rim > 0 && p.h_shoulder > 0 && p.h_bell > 0)) issues.push({ path: "profile", message: "radius and thicknesses must be positive" });
9192 if (!(p.bell_top_radius < p.bell_shoulder_radius && p.bell_shoulder_radius < p.radius)) issues.push({ path: "profile", message: "need bell_top_radius < bell_shoulder_radius < radius" });
9293 if (!(cfg.material.E > 0 && cfg.material.rho > 0 && cfg.material.nu > -1 && cfg.material.nu < 0.5)) issues.push({ path: "material", message: "E and rho must be positive and nu in (-1, 0.5)" });
src/cpu/simulator.tsmodified+69−46View file
@@ -1,54 +1,49 @@
11 // Float64 reference time loop with exactly the structure of the GPU kernels: an element pass
2-// (forces, sigma1 term, radiation accumulation), a hit pass (contact forces, release), a node
3-// pass (gather, contact, lagged rigid-mode projection, leapfrog update, partial sums for the
4-// next projection), and the exciter update. See THEORY.md.
2+// (forces, sigma1 term), a hit pass (contact forces, release), a node pass (gather, contact,
3+// lagged rigid-mode projection, leapfrog update, partial sums for the next projection, normal
4+// acceleration and its decimation accumulators), the exciter update, and once per audio sample
5+// the gather of the listener pressure from the element history. See THEORY.md.
56 import { elementForces, strainEnergies } from "../model/forces.ts";
67 import { HOLD_HEIGHT } from "../model/exciter.ts";
7-import { DECIMATION_SPAN } from "../model/radiation.ts";
8+import { DECIMATION_SPAN, DELAY_TAPS, delayedValue } from "../model/radiation.ts";
89 import type { Setup } from "../model/setup.ts";
9-import type { ChunkResult, Diagnostics, SimulatorBackend } from "../model/simulator.ts";
10+import type { BackendOptions, BackendState, ChunkResult, Diagnostics, SimulatorBackend } from "../model/simulator.ts";
1011
1112 export class CpuSimulator implements SimulatorBackend {
1213 readonly kind = "cpu" as const;
1314 private n = 0; // sub-step counter
14- private readonly q: Float64Array; private readonly v: Float64Array; private readonly nodeAcc: Float64Array;
15- private readonly vwPrev: Float64Array; // projected transverse velocity of the previous step (for the radiated acceleration)
15+ private readonly q: Float64Array; private readonly v: Float64Array;
16+ private readonly vPrev: Float64Array; // projected (u, v, w) velocities of the previous step (for the radiated acceleration)
1617 private readonly ef: Float64Array; private readonly fc: Float64Array;
1718 private readonly zs: Float64Array; private readonly vs: Float64Array; private readonly Fk: Float64Array; private readonly F: Float64Array;
1819 private readonly Fmax: Float64Array; private readonly ncont: Uint32Array;
1920 private partialsPrev = new Float64Array(12); private partialsNew = new Float64Array(12); // [0,6): Rm.(M v), [6,12): Rm.(M q)
20- private readonly acc: Float64Array; // (E, DECIMATION_SPAN) decimation accumulators
21- private readonly history: Float64Array;
22- private pending: { j: number; front: number; back: number }[] = [];
21+ private readonly accRing: Float64Array; // (DECIMATION_SPAN, N) partial audio samples of the normal acceleration
22+ private readonly elemHist: Float64Array; // (ringLength, E) finished element-mean samples
23+ private readonly emitted: Float64Array; // (N,) the node sample finished at the current step
24+ private pending: { j: number; front: number; back: number; acc: Float32Array | null }[] = [];
2325 samplesDone = 0;
2426 readonly maxChunk = 8192;
25- readonly setup: Setup; readonly movieEvery: number;
27+ readonly setup: Setup; readonly movieEvery: number; readonly dispEvery: number; readonly recordAcceleration: boolean;
2628
27- /** ``movieEvery`` > 0 captures w every that many audio samples. */
28- constructor(setup: Setup, movieEvery = 0) {
29- this.setup = setup; this.movieEvery = movieEvery;
29+ constructor(setup: Setup, opts: BackendOptions | number = {}) {
30+ if (typeof opts === "number") opts = { movieEvery: opts };
31+ this.setup = setup; this.movieEvery = opts.movieEvery ?? 0; this.dispEvery = opts.dispEvery ?? 0; this.recordAcceleration = opts.recordAcceleration ?? false;
3032 const N = setup.mesh.n, E = setup.mesh.e, K = setup.schedule.K, P = setup.schedule.P;
31- this.q = new Float64Array(5 * N); this.v = new Float64Array(5 * N); this.nodeAcc = new Float64Array(N); this.vwPrev = new Float64Array(N);
33+ this.q = new Float64Array(5 * N); this.v = new Float64Array(5 * N); this.vPrev = new Float64Array(3 * N);
3234 this.ef = new Float64Array(15 * E); this.fc = new Float64Array(N);
3335 this.zs = new Float64Array(K).fill(HOLD_HEIGHT); this.vs = new Float64Array(K);
3436 this.Fk = new Float64Array(K * P); this.F = new Float64Array(K); this.Fmax = new Float64Array(K); this.ncont = new Uint32Array(K);
35- this.acc = new Float64Array(E * DECIMATION_SPAN); this.history = new Float64Array(E * setup.radiation.ringLength);
37+ this.accRing = new Float64Array(DECIMATION_SPAN * N); this.elemHist = new Float64Array(E * setup.radiation.ringLength);
38+ this.emitted = new Float64Array(N);
3639 }
3740
3841 private step() {
3942 const { shell: sh, mesh, schedule: sc, radiation: rad, dt, substeps: m } = this.setup;
40- const { tri } = mesh, N = mesh.n, E = mesh.e, n = this.n;
43+ const N = mesh.n, n = this.n;
4144 const sigma0 = this.setup.config.material.sigma0;
4245 // ---- element pass
4346 elementForces(sh, this.q, this.v, this.ef);
44- if (n >= 1) {
45- const s = n - 1, j0 = Math.floor(s / m), kk = s - j0 * m, W = DECIMATION_SPAN, taps = rad.taps;
46- if (kk === 0 && j0 > 0) this.finalizeSample(j0 - W / 2); // slot 0 = sample j0 - (W/2 - 1) of the previous j0
47- for (let e = 0; e < E; e++) {
48- const a = (this.nodeAcc[tri[3 * e]] + this.nodeAcc[tri[3 * e + 1]] + this.nodeAcc[tri[3 * e + 2]]) / 3;
49- for (let w = 0; w < W; w++) this.acc[e * W + w] += a * taps[w * m + kk];
50- }
51- }
5247 // ---- hit pass
5348 this.fc.fill(0);
5449 for (let k = 0; k < sc.K; k++) {
@@ -72,9 +67,13 @@ export class CpuSimulator implements SimulatorBackend {
7267 this.F[k] = Ftot;
7368 }
7469 // ---- node pass
75- const { M, Minv, Rm, adjOffsets, adjEntries } = sh, L = 5 * N, c = this.partialsPrev;
70+ const { M, Minv, Rm, adjOffsets, adjEntries, normalNode } = sh, L = 5 * N, c = this.partialsPrev;
7671 this.partialsNew.fill(0);
7772 const f = new Float64Array(5);
73+ // decimation bookkeeping for the acceleration of the previous step, s = n - 1
74+ const s = n - 1, W = DECIMATION_SPAN, taps = rad.taps;
75+ const j0 = s >= 0 ? Math.floor(s / m) : 0, kk = s >= 0 ? s - j0 * m : -1;
76+ const emit = s >= 0 && kk === 0, jE = j0 - W / 2, slotE = ((jE % W) + W) % W, r = (((j0 + 1 - W / 2) % W) + W) % W;
7877 for (let nd = 0; nd < N; nd++) {
7978 f.fill(0);
8079 for (let a = adjOffsets[nd]; a < adjOffsets[nd + 1]; a++) {
@@ -82,6 +81,7 @@ export class CpuSimulator implements SimulatorBackend {
8281 for (let d = 0; d < 5; d++) f[d] += this.ef[15 * e + 5 * i + d];
8382 }
8483 f[2] += this.fc[nd];
84+ let acc = 0;
8585 for (let d = 0; d < 5; d++) {
8686 const idx = 5 * nd + d;
8787 // lagged projection: remove the rigid content that the previous step's update introduced
@@ -89,12 +89,16 @@ export class CpuSimulator implements SimulatorBackend {
8989 for (let k = 0; k < 6; k++) { const r = Rm[k * L + idx]; vd -= c[k] * r; qd -= c[6 + k] * r; }
9090 const v1 = (vd + dt * f[d] * Minv[idx]) / (1 + 2 * sigma0 * dt);
9191 // radiated acceleration from consecutive projected velocities, so that the rigid increment
92- // that the lagged projection removes one step later never radiates
93- if (d === 2) { this.nodeAcc[nd] = (vd - this.vwPrev[nd]) / dt; this.vwPrev[nd] = vd; }
92+ // that the lagged projection removes one step later never radiates; normal component
93+ if (d < 3) { acc += normalNode[3 * nd + d] * (vd - this.vPrev[3 * nd + d]) / dt; this.vPrev[3 * nd + d] = vd; }
9494 const q1 = qd + dt * v1;
9595 this.q[idx] = q1; this.v[idx] = v1;
9696 for (let k = 0; k < 6; k++) { const r = Rm[k * L + idx] * M[idx]; this.partialsNew[k] += r * v1; this.partialsNew[6 + k] += r * q1; }
9797 }
98+ if (s >= 0) {
99+ if (emit) { this.emitted[nd] = this.accRing[slotE * N + nd]; this.accRing[slotE * N + nd] = 0; }
100+ for (let w = 0; w < W; w++) this.accRing[((r + w) % W) * N + nd] += acc * taps[w * m + kk];
101+ }
98102 }
99103 [this.partialsPrev, this.partialsNew] = [this.partialsNew, this.partialsPrev];
100104 // ---- exciters
@@ -103,40 +107,41 @@ export class CpuSimulator implements SimulatorBackend {
103107 this.Fmax[k] = Math.max(this.Fmax[k], this.F[k]); if (this.F[k] > 0) this.ncont[k]++;
104108 }
105109 this.n++;
110+ if (emit && jE >= 0) this.finalizeSample(jE);
106111 }
107112
108- /** Slot 0 (audio sample j) of the accumulators is complete: store it, shift the slots, evaluate the listener pressure. */
113+ /** Audio sample j of the node accelerations is complete: element means into the history, then the listener pressure. */
109114 private finalizeSample(j: number) {
110- const { radiation: rad, mesh } = this.setup, E = mesh.e, D = rad.ringLength, W = DECIMATION_SPAN;
111- for (let e = 0; e < E; e++) {
112- if (j >= 0) this.history[e * D + (j % D)] = this.acc[e * W];
113- for (let w = 0; w < W - 1; w++) this.acc[e * W + w] = this.acc[e * W + w + 1];
114- this.acc[e * W + W - 1] = 0;
115- }
116- if (j < 0) return;
115+ const { radiation: rad, mesh } = this.setup, E = mesh.e, D = rad.ringLength, { tri } = mesh;
116+ const row = (j % D) * E;
117+ for (let e = 0; e < E; e++) this.elemHist[row + e] = (this.emitted[tri[3 * e]] + this.emitted[tri[3 * e + 1]] + this.emitted[tri[3 * e + 2]]) / 3;
117118 let front = 0, back = 0;
118119 for (let e = 0; e < E; e++) {
119- const jf = j - rad.i0F[e], jb = j - rad.i0B[e];
120- if (jf >= 1) front += rad.coefF[e] * (this.history[e * D + (jf % D)] * (1 - rad.frF[e]) + this.history[e * D + ((jf - 1) % D)] * rad.frF[e]);
121- if (jb >= 1) back += rad.coefB[e] * (this.history[e * D + (jb % D)] * (1 - rad.frB[e]) + this.history[e * D + ((jb - 1) % D)] * rad.frB[e]);
120+ front += rad.coefF[e] * delayedValue(this.elemHist, E, e, D, j, rad.i0F[e], rad.tapsF, e * DELAY_TAPS);
121+ back += rad.coefB[e] * delayedValue(this.elemHist, E, e, D, j, rad.i0B[e], rad.tapsB, e * DELAY_TAPS);
122122 }
123- this.pending.push({ j, front, back });
123+ this.pending.push({ j, front, back, acc: this.recordAcceleration ? Float32Array.from(this.emitted) : null });
124124 }
125125
126126 async runChunk(nSamples: number): Promise<ChunkResult> {
127127 const m = this.setup.substeps, N = this.setup.mesh.n, frames: Float32Array[] = [], frameSamples: number[] = [];
128+ const dispFrames: Float32Array[] = [], dispSamples: number[] = [];
129+ const capture = () => { const w = new Float32Array(N); for (let nd = 0; nd < N; nd++) w[nd] = this.q[5 * nd + 2]; return w; };
128130 for (let s = 0; s < nSamples * m; s++) {
129- if (this.movieEvery > 0 && this.n % (m * this.movieEvery) === 0) {
130- const w = new Float32Array(N);
131- for (let nd = 0; nd < N; nd++) w[nd] = this.q[5 * nd + 2];
132- frames.push(w); frameSamples.push(this.n / m);
133- }
131+ if (this.movieEvery > 0 && this.n % (m * this.movieEvery) === 0) { frames.push(capture()); frameSamples.push(this.n / m); }
132+ if (this.dispEvery > 0 && this.n % (m * this.dispEvery) === 0) { dispFrames.push(capture()); dispSamples.push(this.n / m); }
134133 this.step();
135134 }
136135 this.samplesDone += nSamples;
137136 const out = this.pending; this.pending = [];
138137 const firstSample = out.length ? out[0].j : this.samplesDone;
139- return { firstSample, pressureFront: Float32Array.from(out, (o) => o.front), pressureBack: Float32Array.from(out, (o) => o.back), frames, frameSamples };
138+ let acceleration: Float32Array | null = null;
139+ if (this.recordAcceleration) {
140+ acceleration = new Float32Array(out.length * N);
141+ out.forEach((o, i) => acceleration!.set(o.acc!, i * N));
142+ }
143+ return { firstSample, pressureFront: Float32Array.from(out, (o) => o.front), pressureBack: Float32Array.from(out, (o) => o.back),
144+ frames, frameSamples, acceleration, dispFrames, dispSamples };
140145 }
141146
142147 async diagnostics(): Promise<Diagnostics> {
@@ -165,5 +170,23 @@ export class CpuSimulator implements SimulatorBackend {
165170 return w;
166171 }
167172
173+ async exportState(): Promise<BackendState> {
174+ return { kind: "cpu", step: this.n, samplesDone: this.samplesDone, arrays: {
175+ q: this.q.slice(), v: this.v.slice(), vPrev: this.vPrev.slice(), partials: this.partialsPrev.slice(),
176+ zs: this.zs.slice(), vs: this.vs.slice(), Fmax: this.Fmax.slice(), ncont: this.ncont.slice(),
177+ accRing: this.accRing.slice(), elemHist: this.elemHist.slice() } };
178+ }
179+
180+ async importState(st: BackendState): Promise<void> {
181+ if (st.kind !== "cpu") throw new Error("state was written by another backend");
182+ const a = st.arrays;
183+ for (const [name, dst] of [["q", this.q], ["v", this.v], ["vPrev", this.vPrev], ["partials", this.partialsPrev], ["zs", this.zs], ["vs", this.vs],
184+ ["Fmax", this.Fmax], ["ncont", this.ncont], ["accRing", this.accRing], ["elemHist", this.elemHist]] as const) {
185+ if (!a[name] || a[name].length !== dst.length) throw new Error(`state array ${name} is missing or has the wrong size`);
186+ (dst as Float64Array).set(a[name] as any);
187+ }
188+ this.n = st.step; this.samplesDone = st.samplesDone; this.pending = [];
189+ }
190+
168191 dispose() {}
169192 }
src/gpu/shaders.tsmodified+64−40View file
@@ -1,21 +1,26 @@
1-// WGSL kernels of the time loop. Three entry points: the element pass (forces, sigma1 term,
2-// contact forces of the hits, decimation accumulators of the radiated acceleration), the node
3-// pass (gather, contact, lagged rigid-mode projection, leapfrog update, partial sums, exciter
4-// update) and the gather pass (retarded-time sum at the listener once per audio sample). Sizes
1+// WGSL kernels of the time loop. Four entry points: the element pass (forces, sigma1 term,
2+// contact forces of the hits), the node pass (gather, contact, lagged rigid-mode projection,
3+// leapfrog update, partial sums, exciter update, and the normal acceleration with its decimation
4+// accumulators), the gather pass (element means of a finished audio sample into the history,
5+// then the retarded-time sum at the listener) and the capture pass (displacement frames). Sizes
56 // and constants are baked into the source. See THEORY.md for the buffer layouts and the ordering
67 // argument behind the two step counters.
78
89 export interface ShaderConstants {
9- N: number; E: number; K: number; P: number; M: number; W: number; D: number; G: number;
10- dt: number; sigma0: number; nl: number;
10+ N: number; E: number; K: number; P: number; M: number; W: number; D: number; G: number; T: number;
11+ accRows: number; dt: number; sigma0: number; nl: number;
1112 }
1213
1314 export const ELEM_STRIDE = 96; // Gx[3] Gy[3] A z0x z0y C11 C12 C33 cd Ke[81] pad[2]
14-export const NODE_STRIDE = 40; // Minv[5] M[5] Rm[6][5]
15+export const NODE_STRIDE = 44; // Minv[5] M[5] Rm[6][5] normal[3] pad[1]; the decimation taps follow the nodes
1516 export const HIT_HEADER = 12; // kPoint alpha mass gap velocity zs vs F Fmax pad[3]
1617 export const HITU_HEADER = 4; // releaseStep ncont pad[2]
1718 export const SYNC_HEADER = 4; // stepA stepB pad[2], then partials[2][G][12]
19+export const RADCOEF_STRIDE = 36; // coefF coefB i0F i0B tapsF[16] tapsB[16]
1820 export const WORKGROUP_NODES = 256;
21+export const STATE_FLOATS = 13; // per node: q[5] v[5] vPrev[3]
22+/** Chunk uniform: base size frameBase every accBase accRows pad pad (eight 32-bit words). */
23+export const CHUNK_WORDS = 8;
1924
2025 function f(x: number): string {
2126 const s = x.toPrecision(9);
@@ -26,13 +31,14 @@ export function shaderSource(c: ShaderConstants): string {
2631 const HF = HIT_HEADER + 5 * c.P, HU = HITU_HEADER + 3 * c.P;
2732 return /* wgsl */ `
2833 const N: u32 = ${c.N}u; const E: u32 = ${c.E}u; const K: u32 = ${c.K}u; const P: u32 = ${c.P}u;
29-const M: u32 = ${c.M}u; const W: u32 = ${c.W}u; const D: u32 = ${c.D}u; const G: u32 = ${c.G}u;
34+const M: u32 = ${c.M}u; const W: u32 = ${c.W}u; const D: u32 = ${c.D}u; const G: u32 = ${c.G}u; const T: u32 = ${c.T}u;
3035 const DT: f32 = ${f(c.dt)}; const DAMP0: f32 = ${f(1 / (1 + 2 * c.sigma0 * c.dt))}; const NL: f32 = ${f(c.nl)};
31-const EF: u32 = ${ELEM_STRIDE}u; const NF: u32 = ${NODE_STRIDE}u; const HF: u32 = ${HF}u; const HU: u32 = ${HU}u;
32-const OFF_V: u32 = 5u * N; const OFF_ACC: u32 = 10u * N; const OFF_VWP: u32 = 11u * N;
33-const OFF_HIST: u32 = E * W; const OFF_TAPS: u32 = EF * E; const OFF_PART: u32 = ${SYNC_HEADER}u;
36+const EF: u32 = ${ELEM_STRIDE}u; const NF: u32 = ${NODE_STRIDE}u; const HF: u32 = ${HF}u; const HU: u32 = ${HU}u; const RC: u32 = ${RADCOEF_STRIDE}u;
37+const OFF_V: u32 = 5u * N; const OFF_VWP: u32 = 10u * N;
38+const OFF_NHIST: u32 = W * N; const OFF_ACCOUT: u32 = (W + D) * N;
39+const OFF_TAPS: u32 = NF * N; const OFF_PART: u32 = ${SYNC_HEADER}u;
3440
35-struct Chunk { base: i32, size: u32, frameBase: u32, every: u32 }
41+struct Chunk { base: i32, size: u32, frameBase: u32, every: u32, accBase: i32, accRows: u32, pad0: u32, pad1: u32 }
3642
3743 // ------------------------------------------------------------------ element pass
3844 @group(0) @binding(0) var<storage, read> elemF: array<f32>;
@@ -42,7 +48,6 @@ struct Chunk { base: i32, size: u32, frameBase: u32, every: u32 }
4248 @group(0) @binding(4) var<storage, read_write> hitsF: array<f32>;
4349 @group(0) @binding(5) var<storage, read> hitsUR: array<u32>;
4450 @group(0) @binding(6) var<storage, read_write> syncE: array<f32>;
45-@group(0) @binding(7) var<storage, read_write> rad: array<f32>;
4651
4752 @compute @workgroup_size(64)
4853 fn elementPass(@builtin(global_invocation_id) gid: vec3<u32>) {
@@ -85,18 +90,6 @@ fn elementPass(@builtin(global_invocation_id) gid: vec3<u32>) {
8590 out[slot] -= s;
8691 }
8792 for (var i = 0u; i < 15u; i++) { elemForce[15u * e + i] = out[i]; }
88- // decimation accumulators of the radiated acceleration (of the previous step)
89- if (step >= 1u) {
90- let s = step - 1u; let j0 = s / M; let kk = s - j0 * M;
91- if (kk == 0u && j0 > 0u) {
92- let j = i32(j0) - i32(W / 2u);
93- if (j >= 0) { rad[OFF_HIST + e * D + (u32(j) % D)] = rad[e * W]; }
94- for (var w = 0u; w < W - 1u; w++) { rad[e * W + w] = rad[e * W + w + 1u]; }
95- rad[e * W + W - 1u] = 0.0;
96- }
97- let a = (stateR[OFF_ACC + n0] + stateR[OFF_ACC + n1] + stateR[OFF_ACC + n2]) / 3.0;
98- for (var w = 0u; w < W; w++) { rad[e * W + w] += a * elemF[OFF_TAPS + w * M + kk]; }
99- }
10093 } else if (id < E + K) {
10194 // contact forces of hit k at this step
10295 let k = id - E; let hf = k * HF; let hu = k * HU;
@@ -130,9 +123,13 @@ fn elementPass(@builtin(global_invocation_id) gid: vec3<u32>) {
130123 @group(1) @binding(4) var<storage, read_write> hitsFN: array<f32>;
131124 @group(1) @binding(5) var<storage, read_write> hitsU: array<u32>;
132125 @group(1) @binding(6) var<storage, read_write> sync: array<f32>;
126+@group(1) @binding(7) var<storage, read_write> rad: array<f32>;
127+@group(1) @binding(8) var<uniform> chunkN: Chunk;
133128
134129 var<workgroup> red: array<f32, ${12 * WORKGROUP_NODES}>;
135130
131+fn modW(x: i32) -> u32 { return u32(((x % i32(W)) + i32(W)) % i32(W)); }
132+
136133 @compute @workgroup_size(${WORKGROUP_NODES})
137134 fn nodePass(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>, @builtin(workgroup_id) wid: vec3<u32>) {
138135 let nd = gid.x; let t = lid.x;
@@ -164,17 +161,37 @@ fn nodePass(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(local_invoca
164161 }
165162 }
166163 let nb = nd * NF;
164+ var acc = 0.0;
167165 for (var d = 0u; d < 5u; d++) {
168166 let idx = 5u * nd + d;
169167 var vd = state[OFF_V + idx]; var qd = state[idx];
170168 for (var k = 0u; k < 6u; k++) { let r = nodeF[nb + 10u + 5u * k + d]; vd -= c[k] * r; qd -= c[6u + k] * r; }
171169 let v1 = (vd + DT * fo[d] * nodeF[nb + d]) * DAMP0;
172- if (d == 2u) { state[OFF_ACC + nd] = (vd - state[OFF_VWP + nd]) / DT; state[OFF_VWP + nd] = vd; }
170+ // normal acceleration of the previous step from consecutive projected velocities
171+ if (d < 3u) { acc += nodeF[nb + 40u + d] * (vd - state[OFF_VWP + 3u * nd + d]) / DT; state[OFF_VWP + 3u * nd + d] = vd; }
173172 let q1 = qd + DT * v1;
174173 state[idx] = q1; state[OFF_V + idx] = v1;
175174 let mm = nodeF[nb + 5u + d];
176175 for (var k = 0u; k < 6u; k++) { let r = nodeF[nb + 10u + 5u * k + d] * mm; part[k] += r * v1; part[6u + k] += r * q1; }
177176 }
177+ // decimation of the acceleration of sub-step s = step - 1 into the W accumulator slots of this node;
178+ // slot w belongs to audio sample j0 + w - W/2 + 1, kept at ring position (sample mod W)
179+ if (step >= 1u) {
180+ let s = step - 1u; let j0 = s / M; let kk = s - j0 * M;
181+ if (kk == 0u) {
182+ let jE = i32(j0) - i32(W / 2u);
183+ let slotE = modW(jE);
184+ let val = rad[slotE * N + nd];
185+ if (jE >= 0) {
186+ rad[OFF_NHIST + (u32(jE) % D) * N + nd] = val;
187+ let row = jE - chunkN.accBase;
188+ if (chunkN.accRows > 0u && row >= 0 && u32(row) < chunkN.accRows) { rad[OFF_ACCOUT + u32(row) * N + nd] = val; }
189+ }
190+ rad[slotE * N + nd] = 0.0;
191+ }
192+ let r = modW(i32(j0) + 1 - i32(W / 2u));
193+ for (var w = 0u; w < W; w++) { rad[((r + w) % W) * N + nd] += acc * nodeF[OFF_TAPS + w * M + kk]; }
194+ }
178195 }
179196 for (var k = 0u; k < 12u; k++) { red[t * 12u + k] = part[k]; }
180197 workgroupBarrier();
@@ -196,34 +213,41 @@ fn nodePass(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(local_invoca
196213 }
197214 }
198215
199-// ------------------------------------------------------------------ gather pass (listener)
216+// ------------------------------------------------------------------ gather pass (listener), once per finished audio sample
200217 @group(2) @binding(0) var<storage, read> syncG: array<f32>;
201218 @group(2) @binding(1) var<storage, read> radR: array<f32>;
202219 @group(2) @binding(2) var<storage, read> radCoef: array<f32>;
203220 @group(2) @binding(3) var<storage, read_write> pressure: array<f32>;
204221 @group(2) @binding(4) var<uniform> chunk: Chunk;
222+@group(2) @binding(5) var<storage, read_write> elemHist: array<f32>;
223+@group(2) @binding(6) var<storage, read> elemUG: array<u32>;
205224
206225 var<workgroup> redF: array<f32, 256>;
207226 var<workgroup> redB: array<f32, 256>;
208227
228+fn delayed(e: u32, j: i32, i0: i32, tapBase: u32) -> f32 {
229+ var s = 0.0;
230+ for (var t = 0u; t < T; t++) {
231+ let lag = i0 + i32(t) - i32(T / 2u) + 1; let jj = j - lag;
232+ if (jj >= 0 && lag >= 0) { s += radCoef[tapBase + t] * elemHist[(u32(jj) % D) * E + e]; }
233+ }
234+ return s;
235+}
236+
209237 @compute @workgroup_size(256)
210238 fn gatherPass(@builtin(local_invocation_id) lid: vec3<u32>) {
211239 let t = lid.x;
212- let step = bitcast<u32>(syncG[0]);
213- let j = i32((step - 1u) / M) - i32(W / 2u);
240+ let step = bitcast<u32>(syncG[0]); // the node pass of step n has run: the finished sample belongs to s = n - 1
241+ let j = i32((step - 2u) / M) - i32(W / 2u);
214242 var fs = 0.0; var bs = 0.0;
215243 if (j >= 0) {
244+ let hrow = OFF_NHIST + (u32(j) % D) * N;
216245 for (var e = t; e < E; e += 256u) {
217- let rc = 6u * e;
218- let jf = j - i32(radCoef[rc + 2u]); let jb = j - i32(radCoef[rc + 4u]);
219- if (jf >= 1) {
220- let fr = radCoef[rc + 3u];
221- fs += radCoef[rc] * (radR[OFF_HIST + e * D + (u32(jf) % D)] * (1.0 - fr) + radR[OFF_HIST + e * D + (u32(jf - 1) % D)] * fr);
222- }
223- if (jb >= 1) {
224- let fr = radCoef[rc + 5u];
225- bs += radCoef[rc + 1u] * (radR[OFF_HIST + e * D + (u32(jb) % D)] * (1.0 - fr) + radR[OFF_HIST + e * D + (u32(jb - 1) % D)] * fr);
226- }
246+ let mean = (radR[hrow + elemUG[3u * e]] + radR[hrow + elemUG[3u * e + 1u]] + radR[hrow + elemUG[3u * e + 2u]]) / 3.0;
247+ elemHist[(u32(j) % D) * E + e] = mean;
248+ let rc = RC * e;
249+ fs += radCoef[rc] * delayed(e, j, i32(radCoef[rc + 2u]), rc + 4u);
250+ bs += radCoef[rc + 1u] * delayed(e, j, i32(radCoef[rc + 3u]), rc + 4u + T);
227251 }
228252 }
229253 redF[t] = fs; redB[t] = bs;
@@ -238,7 +262,7 @@ fn gatherPass(@builtin(local_invocation_id) lid: vec3<u32>) {
238262 }
239263 }
240264
241-// ------------------------------------------------------------------ capture pass (displacement movie)
265+// ------------------------------------------------------------------ capture pass (displacement frames)
242266 @group(3) @binding(0) var<storage, read> stateC: array<f32>;
243267 @group(3) @binding(1) var<storage, read_write> movie: array<f32>;
244268 @group(3) @binding(2) var<uniform> chunkC: Chunk;
src/gpu/simulator.tsmodified+130−72View file
@@ -1,16 +1,19 @@
1-// WebGPU time loop: packs the set-up into storage buffers, compiles the three kernels and runs
1+// WebGPU time loop: packs the set-up into storage buffers, compiles the four kernels and runs
22 // the sub-steps of a chunk of audio samples as one command buffer. Works in a browser and under
33 // Node with the `webgpu` (Dawn) package, which the tests use.
44 import { HOLD_HEIGHT } from "../model/exciter.ts";
55 import { strainEnergies } from "../model/forces.ts";
6-import { DECIMATION_SPAN } from "../model/radiation.ts";
6+import { DECIMATION_SPAN, DELAY_TAPS } from "../model/radiation.ts";
77 import type { Setup } from "../model/setup.ts";
8-import type { ChunkResult, Diagnostics, SimulatorBackend } from "../model/simulator.ts";
9-import { ELEM_STRIDE, HIT_HEADER, HITU_HEADER, NODE_STRIDE, SYNC_HEADER, WORKGROUP_NODES, shaderSource } from "./shaders.ts";
8+import type { BackendOptions, BackendState, ChunkResult, Diagnostics, SimulatorBackend } from "../model/simulator.ts";
9+import { CHUNK_WORDS, ELEM_STRIDE, HIT_HEADER, HITU_HEADER, NODE_STRIDE, RADCOEF_STRIDE, STATE_FLOATS, SYNC_HEADER, WORKGROUP_NODES, shaderSource } from "./shaders.ts";
1010
1111 // evaluated lazily: under Node the WebGPU globals are installed after this module is imported
1212 const storageUsage = () => GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC;
1313
14+/** Largest per-chunk output buffer (acceleration rows or movie frames) we allocate on the GPU. */
15+const OUTPUT_BUDGET = 64e6;
16+
1417 export class GpuSimulator implements SimulatorBackend {
1518 readonly kind = "gpu" as const;
1619 readonly setup: Setup; readonly device: GPUDevice;
@@ -20,25 +23,33 @@ export class GpuSimulator implements SimulatorBackend {
2023 private readonly buffers: Record<string, GPUBuffer> = {};
2124 private readonly pipelines: Record<string, GPUComputePipeline> = {};
2225 private readonly bindGroups: Record<string, GPUBindGroup> = {};
23- private readonly chunkCapacity: number; readonly movieEvery: number; private readonly framesCapacity: number;
26+ private readonly chunkCapacity: number; readonly movieEvery: number; readonly dispEvery: number; readonly recordAcceleration: boolean;
27+ private readonly framesCapacity: number; private readonly dispCapacity: number; private readonly accRows: number;
2428 private readonly stagingPressure: GPUBuffer; private readonly stagingState: GPUBuffer; private readonly stagingHits: GPUBuffer; private readonly stagingHitsU: GPUBuffer;
25- private readonly stagingMovie: GPUBuffer | null;
29+ private readonly stagingMovie: GPUBuffer | null; private readonly stagingDisp: GPUBuffer | null; private readonly stagingAcc: GPUBuffer | null;
30+ private readonly radStateFloats: number; // accumulator slots plus node history, the part of `rad` that is state
2631
27- /** ``movieEvery`` > 0 captures w every that many audio samples; the chunk size is reduced so a chunk's frames stay under 64 MB. */
28- constructor(device: GPUDevice, setup: Setup, chunkCapacity = 8192, movieEvery = 0) {
29- this.device = device; this.setup = setup; this.movieEvery = movieEvery;
32+ constructor(device: GPUDevice, setup: Setup, chunkCapacity = 8192, opts: BackendOptions | number = {}) {
33+ if (typeof opts === "number") opts = { movieEvery: opts };
34+ this.device = device; this.setup = setup;
35+ this.movieEvery = opts.movieEvery ?? 0; this.dispEvery = opts.dispEvery ?? 0; this.recordAcceleration = opts.recordAcceleration ?? false;
3036 const Nn = setup.mesh.n;
31- if (movieEvery > 0) chunkCapacity = Math.max(128, Math.min(chunkCapacity, Math.floor((64e6 / (4 * Nn)) * movieEvery)));
37+ // a chunk's outputs (movie frames, acceleration rows) stay under the budget
38+ if (this.movieEvery > 0) chunkCapacity = Math.max(128, Math.min(chunkCapacity, Math.floor((OUTPUT_BUDGET / (4 * Nn)) * this.movieEvery)));
39+ if (this.recordAcceleration) chunkCapacity = Math.max(128, Math.min(chunkCapacity, Math.floor(OUTPUT_BUDGET / (4 * Nn)) - 2));
3240 this.chunkCapacity = chunkCapacity;
33- this.framesCapacity = movieEvery > 0 ? Math.ceil(chunkCapacity / movieEvery) + 2 : 0;
34- const { mesh, shell: sh, schedule: sc, radiation: rad, substeps: M, dt } = setup;
35- const N = mesh.n, E = mesh.e, K = sc.K, P = sc.P, W = DECIMATION_SPAN, D = rad.ringLength;
41+ this.framesCapacity = this.movieEvery > 0 ? Math.ceil(chunkCapacity / this.movieEvery) + 2 : 0;
42+ this.dispCapacity = this.dispEvery > 0 ? Math.ceil(chunkCapacity / this.dispEvery) + 2 : 0;
43+ this.accRows = this.recordAcceleration ? chunkCapacity + 2 : 0;
44+ const { mesh, shell: sh, schedule: sc, radiation: rad, substeps: M } = setup;
45+ const N = mesh.n, E = mesh.e, K = sc.K, P = sc.P, W = DECIMATION_SPAN, D = rad.ringLength, T = DELAY_TAPS;
3646 this.G = Math.ceil(N / WORKGROUP_NODES);
3747 this.HF = HIT_HEADER + 5 * P; this.HU = HITU_HEADER + 3 * P;
3848 const G = this.G, HF = this.HF, HU = this.HU;
49+ this.radStateFloats = (W + D) * N;
3950
4051 // ---- pack the set-up
41- const elemF = new Float32Array(ELEM_STRIDE * E + W * M);
52+ const elemF = new Float32Array(ELEM_STRIDE * E);
4253 for (let e = 0; e < E; e++) {
4354 const b = ELEM_STRIDE * e;
4455 for (let i = 0; i < 3; i++) { elemF[b + i] = mesh.Gx[3 * e + i]; elemF[b + 3 + i] = mesh.Gy[3 * e + i]; }
@@ -47,14 +58,15 @@ export class GpuSimulator implements SimulatorBackend {
4758 elemF[b + 12] = 2 * setup.config.material.sigma1 * sh.rhoHA[e];
4859 for (let i = 0; i < 81; i++) elemF[b + 13 + i] = sh.Ke[81 * e + i];
4960 }
50- elemF.set(rad.taps, ELEM_STRIDE * E);
5161 const elemU = new Uint32Array(3 * E); elemU.set(mesh.tri);
52- const nodeF = new Float32Array(NODE_STRIDE * N);
62+ const nodeF = new Float32Array(NODE_STRIDE * N + W * M);
5363 for (let n = 0; n < N; n++) {
5464 const b = NODE_STRIDE * n;
5565 for (let d = 0; d < 5; d++) { nodeF[b + d] = sh.Minv[5 * n + d]; nodeF[b + 5 + d] = sh.M[5 * n + d]; }
5666 for (let k = 0; k < 6; k++) for (let d = 0; d < 5; d++) nodeF[b + 10 + 5 * k + d] = sh.Rm[(k * N + n) * 5 + d];
67+ for (let d = 0; d < 3; d++) nodeF[b + 40 + d] = sh.normalNode[3 * n + d];
5768 }
69+ nodeF.set(rad.taps, NODE_STRIDE * N);
5870 const adj = new Uint32Array(N + 1 + sh.adjEntries.length); adj.set(sh.adjOffsets); adj.set(sh.adjEntries, N + 1);
5971 const hitsF = new Float32Array(HF * K), hitsU = new Uint32Array(HU * K);
6072 for (let k = 0; k < K; k++) {
@@ -67,10 +79,11 @@ export class GpuSimulator implements SimulatorBackend {
6779 }
6880 hitsU[hu] = sc.releaseStep[k]; hitsU[hu + 1] = 0;
6981 }
70- const radCoef = new Float32Array(6 * E);
82+ const radCoef = new Float32Array(RADCOEF_STRIDE * E);
7183 for (let e = 0; e < E; e++) {
72- radCoef[6 * e] = rad.coefF[e]; radCoef[6 * e + 1] = rad.coefB[e]; radCoef[6 * e + 2] = rad.i0F[e];
73- radCoef[6 * e + 3] = rad.frF[e]; radCoef[6 * e + 4] = rad.i0B[e]; radCoef[6 * e + 5] = rad.frB[e];
84+ const b = RADCOEF_STRIDE * e;
85+ radCoef[b] = rad.coefF[e]; radCoef[b + 1] = rad.coefB[e]; radCoef[b + 2] = rad.i0F[e]; radCoef[b + 3] = rad.i0B[e];
86+ for (let t = 0; t < T; t++) { radCoef[b + 4 + t] = rad.tapsF[e * T + t]; radCoef[b + 4 + T + t] = rad.tapsB[e * T + t]; }
7487 }
7588 const mk = (name: string, data: Float32Array | Uint32Array, usage = storageUsage()) => {
7689 const buf = device.createBuffer({ label: name, size: Math.max(16, data.byteLength), usage });
@@ -78,29 +91,34 @@ export class GpuSimulator implements SimulatorBackend {
7891 this.buffers[name] = buf;
7992 return buf;
8093 };
94+ const mkEmpty = (name: string, floats: number) => {
95+ const buf = device.createBuffer({ label: name, size: Math.max(16, 4 * floats), usage: storageUsage() });
96+ this.buffers[name] = buf;
97+ return buf;
98+ };
8199 mk("elemF", elemF); mk("elemU", elemU); mk("nodeF", nodeF); mk("adj", adj); mk("radCoef", radCoef);
82100 mk("hitsF", hitsF); mk("hitsU", hitsU);
83- mk("state", new Float32Array(12 * N)); mk("elemForce", new Float32Array(15 * E));
84- mk("sync", new Float32Array(SYNC_HEADER + 2 * G * 12)); mk("rad", new Float32Array(E * W + E * D));
85- mk("pressure", new Float32Array(2 * chunkCapacity));
86- const chunkBuf = device.createBuffer({ label: "chunk", size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
87- this.buffers.chunk = chunkBuf;
88- const staging = (size: number) => device.createBuffer({ size, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST });
89- this.stagingPressure = staging(8 * chunkCapacity); this.stagingState = staging(12 * N * 4);
90- this.stagingHits = staging(Math.max(16, HF * K * 4)); this.stagingHitsU = staging(Math.max(16, HU * K * 4));
91- if (this.framesCapacity > 0) {
92- mk("movie", new Float32Array(this.framesCapacity * N));
93- this.stagingMovie = staging(this.framesCapacity * N * 4);
94- } else this.stagingMovie = null;
101+ mkEmpty("state", STATE_FLOATS * N); mkEmpty("elemForce", 15 * E);
102+ mkEmpty("sync", SYNC_HEADER + 2 * G * 12); mkEmpty("rad", this.radStateFloats + this.accRows * N); mkEmpty("elemHist", D * E);
103+ mkEmpty("pressure", 2 * chunkCapacity);
104+ const uniform = (name: string) => { const b = device.createBuffer({ label: name, size: 4 * CHUNK_WORDS, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }); this.buffers[name] = b; return b; };
105+ uniform("chunk"); uniform("chunkD");
106+ const staging = (size: number) => device.createBuffer({ size: Math.max(16, size), usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST });
107+ this.stagingPressure = staging(8 * chunkCapacity); this.stagingState = staging(STATE_FLOATS * N * 4);
108+ this.stagingHits = staging(HF * K * 4); this.stagingHitsU = staging(HU * K * 4);
109+ this.stagingMovie = this.framesCapacity > 0 ? (mkEmpty("movie", this.framesCapacity * N), staging(this.framesCapacity * N * 4)) : null;
110+ this.stagingDisp = this.dispCapacity > 0 ? (mkEmpty("disp", this.dispCapacity * N), staging(this.dispCapacity * N * 4)) : null;
111+ this.stagingAcc = this.accRows > 0 ? staging(this.accRows * N * 4) : null;
95112
96113 // ---- pipelines
97- const module = device.createShaderModule({ code: shaderSource({ N, E, K, P, M, W, D, G, dt, sigma0: setup.config.material.sigma0, nl: sh.nl }) });
98- const bgl = (entries: [number, "read-only-storage" | "storage" | "uniform"][]) => device.createBindGroupLayout({
114+ const module = device.createShaderModule({ code: shaderSource({ N, E, K, P, M, W, D, G, T, accRows: this.accRows, dt: setup.dt, sigma0: setup.config.material.sigma0, nl: sh.nl }) });
115+ type Kind = "read-only-storage" | "storage" | "uniform";
116+ const bgl = (entries: [number, Kind][]) => device.createBindGroupLayout({
99117 entries: entries.map(([binding, type]) => ({ binding, visibility: GPUShaderStage.COMPUTE, buffer: { type } })),
100118 });
101- const L0 = bgl([[0, "read-only-storage"], [1, "read-only-storage"], [2, "read-only-storage"], [3, "storage"], [4, "storage"], [5, "read-only-storage"], [6, "storage"], [7, "storage"]]);
102- const L1 = bgl([[0, "storage"], [1, "read-only-storage"], [2, "read-only-storage"], [3, "read-only-storage"], [4, "storage"], [5, "storage"], [6, "storage"]]);
103- const L2 = bgl([[0, "read-only-storage"], [1, "read-only-storage"], [2, "read-only-storage"], [3, "storage"], [4, "uniform"]]);
119+ const L0 = bgl([[0, "read-only-storage"], [1, "read-only-storage"], [2, "read-only-storage"], [3, "storage"], [4, "storage"], [5, "read-only-storage"], [6, "storage"]]);
120+ const L1 = bgl([[0, "storage"], [1, "read-only-storage"], [2, "read-only-storage"], [3, "read-only-storage"], [4, "storage"], [5, "storage"], [6, "storage"], [7, "storage"], [8, "uniform"]]);
121+ const L2 = bgl([[0, "read-only-storage"], [1, "read-only-storage"], [2, "read-only-storage"], [3, "storage"], [4, "uniform"], [5, "storage"], [6, "read-only-storage"]]);
104122 const L3 = bgl([[0, "read-only-storage"], [1, "storage"], [2, "uniform"], [3, "read-only-storage"]]);
105123 const empty = device.createBindGroupLayout({ entries: [] });
106124 const mkPipe = (entryPoint: string, layouts: GPUBindGroupLayout[]) => device.createComputePipeline({
@@ -109,89 +127,103 @@ export class GpuSimulator implements SimulatorBackend {
109127 this.pipelines.element = mkPipe("elementPass", [L0]);
110128 this.pipelines.node = mkPipe("nodePass", [empty, L1]);
111129 this.pipelines.gather = mkPipe("gatherPass", [empty, empty, L2]);
112- if (this.framesCapacity > 0) this.pipelines.capture = mkPipe("capturePass", [empty, empty, empty, L3]);
130+ if (this.framesCapacity > 0 || this.dispCapacity > 0) this.pipelines.capture = mkPipe("capturePass", [empty, empty, empty, L3]);
113131 const B = this.buffers;
114132 const bg = (layout: GPUBindGroupLayout, bufs: GPUBuffer[]) => device.createBindGroup({ layout, entries: bufs.map((buffer, binding) => ({ binding, resource: { buffer } })) });
115- this.bindGroups.element = bg(L0, [B.elemF, B.elemU, B.state, B.elemForce, B.hitsF, B.hitsU, B.sync, B.rad]);
116- this.bindGroups.node = bg(L1, [B.state, B.elemForce, B.nodeF, B.adj, B.hitsF, B.hitsU, B.sync]);
117- this.bindGroups.gather = bg(L2, [B.sync, B.rad, B.radCoef, B.pressure, B.chunk]);
133+ this.bindGroups.element = bg(L0, [B.elemF, B.elemU, B.state, B.elemForce, B.hitsF, B.hitsU, B.sync]);
134+ this.bindGroups.node = bg(L1, [B.state, B.elemForce, B.nodeF, B.adj, B.hitsF, B.hitsU, B.sync, B.rad, B.chunk]);
135+ this.bindGroups.gather = bg(L2, [B.sync, B.rad, B.radCoef, B.pressure, B.chunk, B.elemHist, B.elemU]);
118136 if (this.framesCapacity > 0) this.bindGroups.capture = bg(L3, [B.state, B.movie, B.chunk, B.sync]);
137+ if (this.dispCapacity > 0) this.bindGroups.captureDisp = bg(L3, [B.state, B.disp, B.chunkD, B.sync]);
119138 this.bindGroups.empty = device.createBindGroup({ layout: empty, entries: [] });
120139 }
121140
122- /** Audio sample completed by the gather pass at sub-step n, or -1 when none is due. */
141+ /** Audio sample finished by the node pass of sub-step n (the acceleration of s = n - 1), or -1 when none. */
123142 private sampleDueAt(n: number): number {
124143 const M = this.setup.substeps, W = DECIMATION_SPAN;
125144 if (n < 1 || (n - 1) % M !== 0) return -1;
126- const j0 = (n - 1) / M;
127- if (j0 === 0) return -1;
128- const j = j0 - W / 2;
145+ const j = (n - 1) / M - W / 2;
129146 return j >= 0 ? j : -1;
130147 }
131148
132149 get maxChunk() { return this.chunkCapacity; }
133150
151+ private capture(pass: GPUComputePassEncoder, group: GPUBindGroup) {
152+ pass.setPipeline(this.pipelines.capture); pass.setBindGroup(0, this.bindGroups.empty); pass.setBindGroup(1, this.bindGroups.empty);
153+ pass.setBindGroup(2, this.bindGroups.empty); pass.setBindGroup(3, group); pass.dispatchWorkgroups(this.G);
154+ }
155+
156+ private async readStaging(staging: GPUBuffer, bytes: number): Promise<Float32Array> {
157+ await staging.mapAsync(GPUMapMode.READ, 0, bytes);
158+ const data = new Float32Array(staging.getMappedRange(0, bytes).slice(0));
159+ staging.unmap();
160+ return data;
161+ }
162+
134163 async runChunk(nSamples: number): Promise<ChunkResult> {
135164 if (nSamples > this.chunkCapacity) throw new Error("chunk larger than the pressure buffer");
136165 const { device, setup } = this, M = setup.substeps, E = setup.mesh.e, K = setup.schedule.K, N = setup.mesh.n;
137166 const n0 = this.step, n1 = n0 + nSamples * M;
138167 let base = -1, count = 0;
139168 for (let n = n0; n < n1; n++) { const j = this.sampleDueAt(n); if (j >= 0) { if (base < 0) base = j; count++; } }
140- // frames captured in this chunk: the state at the start of sub-step n where n / M is a multiple of movieEvery
141- const frameSamples: number[] = [];
142- const every = this.movieEvery;
143- if (every > 0) for (let n = n0; n < n1; n++) if (n % (M * every) === 0) frameSamples.push(n / M);
144- const frameBase = frameSamples.length ? frameSamples[0] / every : 0;
145- device.queue.writeBuffer(this.buffers.chunk, 0, new Int32Array([base < 0 ? 0 : base, Math.max(count, 1), frameBase, Math.max(every, 1)]));
169+ // frames captured in this chunk: the state at the start of sub-step n where n / M is a multiple of `every`
170+ const framesAt = (every: number) => { const out: number[] = []; if (every > 0) for (let n = n0; n < n1; n++) if (n % (M * every) === 0) out.push(n / M); return out; };
171+ const frameSamples = framesAt(this.movieEvery), dispSamples = framesAt(this.dispEvery);
172+ const frameBase = frameSamples.length ? frameSamples[0] / this.movieEvery : 0, dispBase = dispSamples.length ? dispSamples[0] / this.dispEvery : 0;
173+ const accBase = base < 0 ? 0 : base, accRows = this.recordAcceleration ? Math.max(count, 0) : 0;
174+ device.queue.writeBuffer(this.buffers.chunk, 0, new Int32Array([accBase, Math.max(count, 1), frameBase, Math.max(this.movieEvery, 1), accBase, accRows, 0, 0]));
175+ device.queue.writeBuffer(this.buffers.chunkD, 0, new Int32Array([accBase, Math.max(count, 1), dispBase, Math.max(this.dispEvery, 1), accBase, accRows, 0, 0]));
146176 const enc = device.createCommandEncoder();
147177 enc.clearBuffer(this.buffers.pressure);
148178 const pass = enc.beginComputePass();
149179 const wgE = Math.ceil((E + K) / 64), wgN = this.G;
150180 for (let n = n0; n < n1; n++) {
151- if (every > 0 && n % (M * every) === 0) {
152- pass.setPipeline(this.pipelines.capture); pass.setBindGroup(0, this.bindGroups.empty); pass.setBindGroup(1, this.bindGroups.empty);
153- pass.setBindGroup(2, this.bindGroups.empty); pass.setBindGroup(3, this.bindGroups.capture); pass.dispatchWorkgroups(wgN);
154- }
181+ if (this.movieEvery > 0 && n % (M * this.movieEvery) === 0) this.capture(pass, this.bindGroups.capture);
182+ if (this.dispEvery > 0 && n % (M * this.dispEvery) === 0) this.capture(pass, this.bindGroups.captureDisp);
155183 pass.setPipeline(this.pipelines.element); pass.setBindGroup(0, this.bindGroups.element); pass.dispatchWorkgroups(wgE);
184+ pass.setPipeline(this.pipelines.node); pass.setBindGroup(0, this.bindGroups.empty); pass.setBindGroup(1, this.bindGroups.node); pass.dispatchWorkgroups(wgN);
156185 if (this.sampleDueAt(n) >= 0) {
157186 pass.setPipeline(this.pipelines.gather); pass.setBindGroup(0, this.bindGroups.empty); pass.setBindGroup(1, this.bindGroups.empty);
158187 pass.setBindGroup(2, this.bindGroups.gather); pass.dispatchWorkgroups(1);
159188 }
160- pass.setPipeline(this.pipelines.node); pass.setBindGroup(0, this.bindGroups.empty); pass.setBindGroup(1, this.bindGroups.node); pass.dispatchWorkgroups(wgN);
161189 }
162190 pass.end();
163191 enc.copyBufferToBuffer(this.buffers.pressure, 0, this.stagingPressure, 0, 8 * this.chunkCapacity);
164- const nFrames = frameSamples.length;
192+ const nFrames = frameSamples.length, nDisp = dispSamples.length;
165193 if (nFrames > 0) enc.copyBufferToBuffer(this.buffers.movie, 0, this.stagingMovie!, 0, nFrames * N * 4);
194+ if (nDisp > 0) enc.copyBufferToBuffer(this.buffers.disp, 0, this.stagingDisp!, 0, nDisp * N * 4);
195+ if (accRows > 0) enc.copyBufferToBuffer(this.buffers.rad, this.radStateFloats * 4, this.stagingAcc!, 0, accRows * N * 4);
166196 device.queue.submit([enc.finish()]);
167197 this.step = n1; this.samplesDone += nSamples;
168- await this.stagingPressure.mapAsync(GPUMapMode.READ);
169- const all = new Float32Array(this.stagingPressure.getMappedRange().slice(0));
170- this.stagingPressure.unmap();
171- const frames: Float32Array[] = [];
172- if (nFrames > 0) {
173- await this.stagingMovie!.mapAsync(GPUMapMode.READ, 0, nFrames * N * 4);
174- const data = new Float32Array(this.stagingMovie!.getMappedRange(0, nFrames * N * 4).slice(0));
175- this.stagingMovie!.unmap();
176- for (let f = 0; f < nFrames; f++) frames.push(data.slice(f * N, (f + 1) * N));
177- }
198+ const all = await this.readStaging(this.stagingPressure, 8 * this.chunkCapacity);
199+ const split = (data: Float32Array, k: number) => Array.from({ length: k }, (_, f) => data.slice(f * N, (f + 1) * N));
200+ const frames = nFrames > 0 ? split(await this.readStaging(this.stagingMovie!, nFrames * N * 4), nFrames) : [];
201+ const dispFrames = nDisp > 0 ? split(await this.readStaging(this.stagingDisp!, nDisp * N * 4), nDisp) : [];
202+ const acceleration = this.recordAcceleration ? (accRows > 0 ? await this.readStaging(this.stagingAcc!, accRows * N * 4) : new Float32Array(0)) : null;
178203 const size = Math.max(count, 1);
179- return { firstSample: base < 0 ? this.samplesDone : base, pressureFront: all.slice(0, count), pressureBack: all.slice(size, size + count), frames, frameSamples };
204+ return { firstSample: base < 0 ? this.samplesDone : base, pressureFront: all.slice(0, count), pressureBack: all.slice(size, size + count),
205+ frames, frameSamples, acceleration, dispFrames, dispSamples };
180206 }
181207
182208 private async read(buffer: GPUBuffer, staging: GPUBuffer, bytes: number): Promise<ArrayBuffer> {
183209 const enc = this.device.createCommandEncoder();
184210 enc.copyBufferToBuffer(buffer, 0, staging, 0, bytes);
185211 this.device.queue.submit([enc.finish()]);
186- await staging.mapAsync(GPUMapMode.READ);
187- const out = staging.getMappedRange().slice(0);
212+ await staging.mapAsync(GPUMapMode.READ, 0, bytes);
213+ const out = staging.getMappedRange(0, bytes).slice(0);
188214 staging.unmap();
189215 return out;
190216 }
191217
218+ /** Read a whole buffer through a temporary staging buffer. */
219+ private async readWhole(buffer: GPUBuffer, bytes: number): Promise<ArrayBuffer> {
220+ const staging = this.device.createBuffer({ size: Math.max(16, bytes), usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST });
221+ try { return await this.read(buffer, staging, bytes); } finally { staging.destroy(); }
222+ }
223+
192224 async diagnostics(): Promise<Diagnostics> {
193225 const { setup } = this, sh = setup.shell, N = setup.mesh.n, sc = setup.schedule, HF = this.HF, HU = this.HU;
194- const st = new Float32Array(await this.read(this.buffers.state, this.stagingState, 12 * N * 4));
226+ const st = new Float32Array(await this.read(this.buffers.state, this.stagingState, STATE_FLOATS * N * 4));
195227 const hf = new Float32Array(await this.read(this.buffers.hitsF, this.stagingHits, Math.max(16, HF * sc.K * 4)));
196228 const hu = new Uint32Array(await this.read(this.buffers.hitsU, this.stagingHitsU, Math.max(16, HU * sc.K * 4)));
197229 let ke = 0, woh = 0;
@@ -209,17 +241,43 @@ export class GpuSimulator implements SimulatorBackend {
209241
210242 async displacement(): Promise<Float32Array> {
211243 const N = this.setup.mesh.n;
212- const st = new Float32Array(await this.read(this.buffers.state, this.stagingState, 12 * N * 4));
244+ const st = new Float32Array(await this.read(this.buffers.state, this.stagingState, STATE_FLOATS * N * 4));
213245 const w = new Float32Array(N);
214246 for (let n = 0; n < N; n++) w[n] = st[5 * n + 2];
215247 return w;
216248 }
217249
250+ async exportState(): Promise<BackendState> {
251+ const { setup } = this, N = setup.mesh.n, E = setup.mesh.e, K = setup.schedule.K, D = setup.radiation.ringLength;
252+ const B = this.buffers;
253+ return { kind: "gpu", step: this.step, samplesDone: this.samplesDone, arrays: {
254+ state: new Float32Array(await this.readWhole(B.state, STATE_FLOATS * N * 4)),
255+ sync: new Float32Array(await this.readWhole(B.sync, (SYNC_HEADER + 2 * this.G * 12) * 4)),
256+ hitsF: new Float32Array(await this.readWhole(B.hitsF, Math.max(16, this.HF * K * 4))).subarray(0, this.HF * K),
257+ hitsU: new Uint32Array(await this.readWhole(B.hitsU, Math.max(16, this.HU * K * 4))).subarray(0, this.HU * K),
258+ rad: new Float32Array(await this.readWhole(B.rad, this.radStateFloats * 4)),
259+ elemHist: new Float32Array(await this.readWhole(B.elemHist, D * E * 4)),
260+ } };
261+ }
262+
263+ async importState(st: BackendState): Promise<void> {
264+ if (st.kind !== "gpu") throw new Error("state was written by another backend");
265+ const { setup } = this, N = setup.mesh.n, E = setup.mesh.e, K = setup.schedule.K, D = setup.radiation.ringLength;
266+ const expect: Record<string, number> = { state: STATE_FLOATS * N, sync: SYNC_HEADER + 2 * this.G * 12, hitsF: this.HF * K, hitsU: this.HU * K, rad: this.radStateFloats, elemHist: D * E };
267+ for (const [name, len] of Object.entries(expect)) {
268+ const a = st.arrays[name];
269+ if (!a || a.length !== len) throw new Error(`state array ${name} is missing or has the wrong size`);
270+ this.device.queue.writeBuffer(this.buffers[name], 0, a.buffer, a.byteOffset, a.byteLength);
271+ }
272+ this.step = st.step; this.samplesDone = st.samplesDone;
273+ }
274+
218275 /** The state buffer (q at offset 0, 5 floats per node), for a renderer that reads w directly. */
219276 get stateBuffer(): GPUBuffer { return this.buffers.state; }
220277
221278 dispose() {
222279 for (const b of Object.values(this.buffers)) b.destroy();
223- this.stagingPressure.destroy(); this.stagingState.destroy(); this.stagingHits.destroy(); this.stagingHitsU.destroy(); this.stagingMovie?.destroy();
280+ this.stagingPressure.destroy(); this.stagingState.destroy(); this.stagingHits.destroy(); this.stagingHitsU.destroy();
281+ this.stagingMovie?.destroy(); this.stagingDisp?.destroy(); this.stagingAcc?.destroy();
224282 }
225283 }
src/io/cymsimFile.tsadded+199−0View file
@@ -0,0 +1,199 @@
1+// Reading and writing .cymsim files (HDF5) with h5wasm. The layout is specified in
2+// cymsim/docs/format.md; this module writes exactly what the Python package writes, apart from
3+// the `state` group, which holds this application's own integrator state (writer "cymsimweb").
4+// The h5wasm module is passed in by the caller: the browser uses the in-memory build ("h5wasm")
5+// and writes the file image to a Blob, the tests use "h5wasm/node" on the real file system.
6+import type { SimulationConfig } from "../config/schema.ts";
7+import type { BackendState } from "../model/simulator.ts";
8+import { AccelerationStore } from "../analysis/acceleration.ts";
9+
10+export const FORMAT_VERSION = 1;
11+export const STATE_WRITER = "cymsimweb";
12+const ENERGY_COLUMNS = "time kinetic membrane bending exciters max_w_over_h";
13+const HIT_FIELDS = ["time", "peak_force", "contact_time", "rebound_velocity", "energy_in", "energy_out"] as const;
14+
15+// h5wasm's types are loose; we use the few calls we need through this minimal shape
16+export interface H5Module { File: new (path: string, mode: string) => any; ready: Promise<{ FS: any }> }
17+
18+export interface HitRecord { time: number; kind: string; peak_force: number; contact_time: number; rebound_velocity: number; energy_in: number; energy_out: number }
19+
20+/** Everything a .cymsim file holds, in memory. */
21+export interface CymsimRun {
22+ yaml: string; config: SimulationConfig;
23+ mesh: { xy: Float64Array; z0: Float64Array; thickness: Float64Array; normal: Float64Array; triangles: Int32Array | Uint32Array; area: Float64Array; boundary: Int32Array | Uint32Array; nNodes: number; nElements: number };
24+ listener: { rFront: Float64Array; rBack: Float64Array };
25+ fs: number; dt: number; substeps: number; duration: number; nSamples: number; nStepsDone: number; complete: boolean; wallTime: number; decimationSpan: number;
26+ audioBaffled: Float32Array; audioUnbaffled: Float32Array; // the two listener signals, final samples so far
27+ acceleration: AccelerationStore | null; taps: Float64Array | null; // taps: (W, m)
28+ displacement: { rate: number; times: number[]; frames: Float32Array[] } | null;
29+ energy: number[][]; // rows of six
30+ hits: HitRecord[];
31+ state: BackendState | null; // this application's state, when written by it
32+ creator: string; created: string;
33+}
34+
35+export const dtypeOf = (a: ArrayLike<number>) => a instanceof Float64Array ? "<d" : a instanceof Float32Array ? "<f" : a instanceof Int16Array ? "<h" : a instanceof Uint32Array ? "<I" : "<i";
36+
37+function attr(g: any, name: string, value: number | string | Float64Array, dtype?: string) {
38+ if (typeof value === "string") g.create_attribute(name, value);
39+ else if (typeof value === "number") g.create_attribute(name, value, null, dtype ?? (Number.isInteger(value) ? "<i" : "<d"));
40+ else g.create_attribute(name, value, [value.length], "<d");
41+}
42+
43+/** Create a resizable time-major dataset (rows, cols) and fill it from blocks without holding a copy of everything. */
44+function writeSeries(g: any, name: string, dtype: string, cols: number, rows: number, chunkRows: number, fill: (write: (r0: number, block: ArrayLike<number>) => void) => void) {
45+ const shape = cols > 0 ? [rows, cols] : [rows], chunks = cols > 0 ? [Math.max(1, Math.min(chunkRows, rows || chunkRows)), cols] : [Math.max(1, Math.min(chunkRows, rows || chunkRows))];
46+ const empty = dtype === "<h" ? new Int16Array(0) : dtype === "<d" ? new Float64Array(0) : new Float32Array(0);
47+ const ds = g.create_dataset({ name, data: empty, shape: cols > 0 ? [0, cols] : [0], dtype, maxshape: cols > 0 ? [null, cols] : [null], chunks });
48+ if (rows > 0) {
49+ ds.resize(shape);
50+ fill((r0, block) => {
51+ const n = cols > 0 ? block.length / cols : block.length;
52+ ds.write_slice(cols > 0 ? [[r0, r0 + n], [0, cols]] : [[r0, r0 + n]], block);
53+ });
54+ }
55+ return ds;
56+}
57+
58+/** Write ``run`` to ``path`` in h5wasm's file system (in memory in the browser, the real disk under Node). */
59+export function writeCymsim(h5: H5Module, path: string, run: CymsimRun, creator: string): void {
60+ const f = new h5.File(path, "w");
61+ try {
62+ const N = run.mesh.nNodes, E = run.mesh.nElements;
63+ attr(f, "format", "cymsim"); attr(f, "format_version", FORMAT_VERSION); attr(f, "creator", creator);
64+ attr(f, "created", new Date().toISOString().replace(/\.\d{3}Z$/, "+00:00"));
65+ f.create_group("config").create_dataset({ name: "yaml", data: run.yaml });
66+
67+ const mesh = f.create_group("mesh");
68+ attr(mesh, "n_nodes", N); attr(mesh, "n_elements", E);
69+ mesh.create_dataset({ name: "xy", data: run.mesh.xy, shape: [N, 2], dtype: "<d" });
70+ mesh.create_dataset({ name: "z0", data: run.mesh.z0, shape: [N], dtype: "<d" });
71+ mesh.create_dataset({ name: "thickness", data: run.mesh.thickness, shape: [N], dtype: "<d" });
72+ mesh.create_dataset({ name: "normal", data: run.mesh.normal, shape: [N, 3], dtype: "<d" });
73+ mesh.create_dataset({ name: "triangles", data: Int32Array.from(run.mesh.triangles), shape: [E, 3], dtype: "<i" });
74+ mesh.create_dataset({ name: "area", data: run.mesh.area, shape: [E], dtype: "<d" });
75+ mesh.create_dataset({ name: "boundary", data: Int32Array.from(run.mesh.boundary), shape: [run.mesh.boundary.length], dtype: "<i" });
76+
77+ const lis = f.create_group("listener"), L = run.config.listener;
78+ attr(lis, "position", Float64Array.from(L.position)); attr(lis, "c_air", L.c_air, "<d"); attr(lis, "rho_air", L.rho_air, "<d");
79+ attr(lis, "back_diffraction_gain", L.back_diffraction_gain, "<d");
80+ lis.create_dataset({ name: "r_front", data: run.listener.rFront, shape: [E], dtype: "<d" });
81+ lis.create_dataset({ name: "r_back", data: run.listener.rBack, shape: [E], dtype: "<d" });
82+
83+ const rg = f.create_group("run");
84+ attr(rg, "fs", run.fs); attr(rg, "dt", run.dt, "<d"); attr(rg, "substeps", run.substeps); attr(rg, "duration", run.duration, "<d");
85+ attr(rg, "n_samples", run.nSamples); attr(rg, "decimation_span", run.decimationSpan); attr(rg, "n_steps_done", run.nStepsDone);
86+ attr(rg, "complete", run.complete ? 1 : 0); attr(rg, "wall_time", run.wallTime, "<d");
87+
88+ const audio = f.create_group("audio");
89+ attr(audio, "fs", run.fs); attr(audio, "units", "Pa");
90+ for (const [name, data] of [["baffled", run.audioBaffled], ["unbaffled", run.audioUnbaffled]] as const) {
91+ writeSeries(audio, name, "<f", 0, data.length, 65536, (write) => write(0, data));
92+ }
93+
94+ if (run.acceleration && run.taps) {
95+ const a = run.acceleration, g = f.create_group("acceleration");
96+ attr(g, "fs", run.fs); attr(g, "component", "normal"); attr(g, "units", "m/s^2"); attr(g, "encoding", "int16 * scale[t]");
97+ attr(g, "description", "acceleration of every node along the rest-surface normal (front, +z side, positive), low-pass filtered by the kernel in 'taps' and sampled at fs; sample j is centred on t = j / fs");
98+ const rows = Math.max(1, Math.min(1024, Math.floor(16e6 / (2 * N))));
99+ writeSeries(g, "normal", "<h", N, a.nSamples, rows, (write) => { for (const b of a.blocks) write(b.first, b.data); });
100+ writeSeries(g, "scale", "<f", 0, a.nSamples, 65536, (write) => { for (const b of a.blocks) write(b.first, b.scale); });
101+ const W = run.decimationSpan, m = run.substeps;
102+ const taps = g.create_dataset({ name: "taps", data: run.taps, shape: [W, m], dtype: "<d" });
103+ attr(taps, "layout", "taps[w, kk]: weight of sub-step j0 m + kk in audio sample j0 + w - W/2 + 1");
104+ attr(taps, "kaiser_beta", 8.0, "<d"); attr(taps, "cutoff", 0.46, "<d");
105+ }
106+
107+ if (run.displacement) {
108+ const d = run.displacement, g = f.create_group("displacement");
109+ attr(g, "rate", d.rate, "<d"); attr(g, "units", "m"); attr(g, "description", "transverse displacement w of every node at the frame times");
110+ writeSeries(g, "w", "<f", N, d.frames.length, 64, (write) => d.frames.forEach((fr, i) => write(i, fr)));
111+ writeSeries(g, "time", "<d", 0, d.times.length, 4096, (write) => write(0, Float64Array.from(d.times)));
112+ }
113+
114+ const eg = f.create_group("energy");
115+ const table = writeSeries(eg, "table", "<d", 6, run.energy.length, 1024, (write) => write(0, Float64Array.from(run.energy.flat())));
116+ attr(table, "columns", ENERGY_COLUMNS);
117+
118+ const hg = f.create_group("hits"), K = run.hits.length;
119+ for (const name of HIT_FIELDS) hg.create_dataset({ name, data: Float64Array.from(run.hits, (h) => h[name]), shape: [K], dtype: "<d" });
120+ hg.create_dataset({ name: "kind", data: run.hits.map((h) => h.kind), shape: [K], dtype: "S16" });
121+
122+ if (run.state) {
123+ const s = run.state, g = f.create_group("state");
124+ attr(g, "writer", STATE_WRITER); attr(g, "n_steps_done", s.step); attr(g, "samples_done", s.samplesDone); attr(g, "backend", s.kind);
125+ for (const [name, a] of Object.entries(s.arrays)) g.create_dataset({ name, data: a, shape: [a.length], dtype: dtypeOf(a) });
126+ }
127+ } finally { f.close(); }
128+}
129+
130+const str = (v: unknown) => (typeof v === "string" ? v : Array.isArray(v) ? String(v[0]) : String(v));
131+const num = (v: unknown) => Number(Array.isArray(v) ? v[0] : v);
132+
133+/** Read a .cymsim file from h5wasm's file system. ``parse`` turns the YAML text into a configuration. */
134+export function readCymsim(h5: H5Module, path: string, parse: (yaml: string) => SimulationConfig): CymsimRun {
135+ const f = new h5.File(path, "r");
136+ try {
137+ if (str(f.get_attribute("format", true)) !== "cymsim") throw new Error("not a .cymsim file");
138+ const get = (p: string) => { const d = f.get(p); if (!d) throw new Error(`missing ${p}`); return d; };
139+ const has = (p: string) => f.get(p) !== null && f.get(p) !== undefined;
140+ const value = <T,>(p: string) => get(p).value as T;
141+ const a = (p: string, name: string) => get(p).get_attribute(name, true);
142+ const yamlText = str(value("config/yaml"));
143+ const config = parse(yamlText);
144+ const nNodes = num(a("mesh", "n_nodes")), nElements = num(a("mesh", "n_elements"));
145+ const f64 = (p: string) => Float64Array.from(value<ArrayLike<number>>(p));
146+ const f32 = (p: string) => Float32Array.from(value<ArrayLike<number>>(p));
147+ const fs = num(a("run", "fs")), substeps = num(a("run", "substeps"));
148+ let acceleration: AccelerationStore | null = null, taps: Float64Array | null = null;
149+ if (has("acceleration")) {
150+ acceleration = new AccelerationStore(nNodes, fs);
151+ const ds = get("acceleration/normal"), scale = f32("acceleration/scale"), T = ds.shape[0] as number;
152+ // read in slabs of about 64 MB so that no second copy of the whole record is needed
153+ const slab = Math.max(1, Math.floor(32e6 / nNodes));
154+ for (let r0 = 0; r0 < T; r0 += slab) {
155+ const r1 = Math.min(T, r0 + slab);
156+ const data = ds.slice([[r0, r1], [0, nNodes]]) as Int16Array;
157+ acceleration.pushEncoded(Int16Array.from(data), scale.slice(r0, r1));
158+ }
159+ taps = f64("acceleration/taps");
160+ }
161+ let displacement: CymsimRun["displacement"] = null;
162+ if (has("displacement")) {
163+ const w = get("displacement/w"), Td = w.shape[0] as number, all = w.value as Float32Array, times = Array.from(f64("displacement/time"));
164+ const frames: Float32Array[] = [];
165+ for (let i = 0; i < Td; i++) frames.push(Float32Array.from(all.subarray(i * nNodes, (i + 1) * nNodes)));
166+ displacement = { rate: num(a("displacement", "rate")), times, frames };
167+ }
168+ const et = get("energy/table"), erows = et.shape[0] as number, eflat = Array.from(et.value as ArrayLike<number>);
169+ const energy: number[][] = [];
170+ for (let i = 0; i < erows; i++) energy.push(eflat.slice(6 * i, 6 * i + 6));
171+ const K = get("hits/time").shape[0] as number, kinds = get("hits/kind").value as unknown as string[];
172+ const hits: HitRecord[] = [];
173+ for (let k = 0; k < K; k++) {
174+ const h: any = { kind: str(Array.isArray(kinds) ? kinds[k] : kinds) };
175+ for (const name of HIT_FIELDS) h[name] = Number((get(`hits/${name}`).value as ArrayLike<number>)[k]);
176+ hits.push(h);
177+ }
178+ let state: BackendState | null = null;
179+ if (has("state") && str(a("state", "writer")) === STATE_WRITER) {
180+ const g = get("state"), arrays: BackendState["arrays"] = {};
181+ for (const name of g.keys() as string[]) {
182+ const v = g.get(name).value;
183+ arrays[name] = v instanceof Float64Array || v instanceof Float32Array || v instanceof Uint32Array ? v : Float32Array.from(v as ArrayLike<number>);
184+ }
185+ state = { kind: str(a("state", "backend")) as "cpu" | "gpu", step: num(a("state", "n_steps_done")), samplesDone: num(a("state", "samples_done")), arrays };
186+ }
187+ const optional = (name: string, dflt: number) => { try { return num(a("run", name)); } catch { return dflt; } };
188+ return {
189+ yaml: yamlText, config,
190+ mesh: { xy: f64("mesh/xy"), z0: f64("mesh/z0"), thickness: f64("mesh/thickness"), normal: f64("mesh/normal"), triangles: Int32Array.from(value<ArrayLike<number>>("mesh/triangles")),
191+ area: f64("mesh/area"), boundary: Int32Array.from(value<ArrayLike<number>>("mesh/boundary")), nNodes, nElements },
192+ listener: { rFront: f64("listener/r_front"), rBack: f64("listener/r_back") },
193+ fs, dt: num(a("run", "dt")), substeps, duration: num(a("run", "duration")), nSamples: num(a("run", "n_samples")),
194+ nStepsDone: optional("n_steps_done", 0), complete: optional("complete", 0) !== 0, wallTime: optional("wall_time", 0), decimationSpan: optional("decimation_span", 32),
195+ audioBaffled: f32("audio/baffled"), audioUnbaffled: f32("audio/unbaffled"), acceleration, taps, displacement, energy, hits, state,
196+ creator: str(f.get_attribute("creator", true)), created: str(f.get_attribute("created", true)),
197+ };
198+ } finally { f.close(); }
199+}
src/main.tsmodified+232−35View file
@@ -1,3 +1,4 @@
1+import { AccelerationStore, DisplacementStore } from "./analysis/acceleration.ts";
12 import { Movie, MoviePlayer, DEFAULT_MOVIE_BUDGET, movieEvery } from "./analysis/movie.ts";
23 import { Stft, bandSummary } from "./analysis/spectrogram.ts";
34 import { ChatClient, type AppApi } from "./chat/client.ts";
@@ -8,9 +9,11 @@ import type { SimulationConfig } from "./config/schema.ts";
89 import { configToYaml, parseConfigYaml, type Issue } from "./config/yaml.ts";
910 import { CpuSimulator } from "./cpu/simulator.ts";
1011 import { GpuSimulator } from "./gpu/simulator.ts";
12+import { readCymsim, writeCymsim, type CymsimRun, type H5Module } from "./io/cymsimFile.ts";
13+import { patchEnergy } from "./model/exciter.ts";
1114 import { DECIMATION_SPAN } from "./model/radiation.ts";
1215 import { buildSetup, type Setup } from "./model/setup.ts";
13-import type { ChunkResult, Diagnostics, SimulatorBackend } from "./model/simulator.ts";
16+import { dispEveryFor, type BackendOptions, type ChunkResult, type Diagnostics, type SimulatorBackend } from "./model/simulator.ts";
1417 import type { FrequencyScale } from "./ui/spectrogramView.ts";
1518 import { Runner } from "./run.ts";
1619 import { YamlEditor } from "./ui/editor.ts";
@@ -19,6 +22,7 @@ import { PlateView } from "./ui/plateView.ts";
1922 import { Readouts, formatSummary } from "./ui/readouts.ts";
2023 import { SpectrogramView } from "./ui/spectrogramView.ts";
2124
25+const APP_VERSION = "0.1.0";
2226 const $ = <T extends HTMLElement>(id: string) => document.getElementById(id) as T;
2327 const params = new URLSearchParams(location.search);
2428
@@ -118,8 +122,15 @@ let runState: "idle" | "setup" | "running" | "paused" | "done" | "stopped" = "id
118122 let lastDiagnostics: Diagnostics | null = null;
119123 let lastProgress = { done: 0, wall: 0 };
120124 let backend: SimulatorBackend | null = null;
125+let backendOpts: BackendOptions = {};
121126 let front = new Float32Array(0), back = new Float32Array(0), frontier = 0, pushed = 0;
122127 let stft: Stft | null = null;
128+// the records that go into a .cymsim file
129+let accStore: AccelerationStore | null = null;
130+let dispStore: DisplacementStore | null = null;
131+let energyRows: number[][] = [];
132+let wallBefore = 0; // wall time of earlier sessions of a resumed run
133+let loaded: CymsimRun | null = null; // a loaded file whose run has not been continued
123134 const signalSel = $<HTMLSelectElement>("signal");
124135 const signal = () => {
125136 const out = new Float32Array(frontier);
@@ -174,50 +185,100 @@ movieStop.onclick = () => { moviePlayer?.stop(); updateMovieUi(); };
174185 moviePos.oninput = () => { if (!movie || !moviePlayer) return; moviePlayer.stop(); moviePlayer.seek(Number(moviePos.value) * movie.duration); updateMovieUi(); };
175186 updateMovieUi();
176187
177-const startBtn = $<HTMLButtonElement>("start"), pauseBtn = $<HTMLButtonElement>("pause"), stopBtn = $<HTMLButtonElement>("stop");
188+const startBtn = $<HTMLButtonElement>("start"), pauseBtn = $<HTMLButtonElement>("pause"), stopBtn = $<HTMLButtonElement>("stop"), resumeBtn = $<HTMLButtonElement>("resume");
178189 const playBtn = $<HTMLButtonElement>("play"), stopAudioBtn = $<HTMLButtonElement>("stop-audio"), wavBtn = $<HTMLButtonElement>("download-wav");
190+const exportBtn = $<HTMLButtonElement>("export-cymsim"), loadBtn = $<HTMLButtonElement>("load-cymsim");
179191 const progress = $<HTMLProgressElement>("progress");
180192
181-async function start() {
182- if (!config || issues.length) { readouts.log("fix the configuration issues first"); return; }
183- startBtn.disabled = true; presetSel.disabled = true; runState = "setup";
184- readouts.clearLog();
185- const cfg = structuredClone(config);
186- try {
187- readouts.log("building the set-up ...");
188- setup = await buildSetup(cfg, async (phase) => { readouts.log(` ${phase}`); await new Promise((r) => setTimeout(r, 0)); });
189- } catch (err) {
190- readouts.log(`set-up failed: ${(err as Error).message}`); startBtn.disabled = false; presetSel.disabled = false; runState = "idle"; return;
193+/** Memory the acceleration record of a run would take, against what this device can be expected to hold. */
194+function recordBudget(nSamples: number, nodes: number): { bytes: number; limit: number } {
195+ const bytes = AccelerationStore.estimateBytes(nSamples, nodes);
196+ const deviceGb = (navigator as unknown as { deviceMemory?: number }).deviceMemory;
197+ const limit = deviceGb ? Math.max(1e9, 0.5 * deviceGb * 1e9) : 2e9;
198+ return { bytes, limit };
199+}
200+
201+const fmtBytes = (b: number) => (b >= 1e9 ? `${(b / 1e9).toFixed(2)} GB` : `${(b / 1e6).toFixed(0)} MB`);
202+
203+function setRunButtons(running: boolean) {
204+ startBtn.disabled = running; presetSel.disabled = running; loadBtn.disabled = running;
205+ pauseBtn.disabled = !running; stopBtn.disabled = !running;
206+ resumeBtn.disabled = running || !(loaded?.state && !loaded.complete && loaded.state.kind === (device ? "gpu" : "cpu"));
207+}
208+
209+/** Start a run of the current configuration, or continue the loaded file's run when ``resumeFrom`` is given. */
210+async function start(resumeFrom: CymsimRun | null = null) {
211+ if (!resumeFrom && (!config || issues.length)) { readouts.log("fix the configuration issues first"); return; }
212+ setRunButtons(true); runState = "setup";
213+ if (!resumeFrom) readouts.clearLog();
214+ const cfg = resumeFrom ? structuredClone(resumeFrom.config) : structuredClone(config!);
215+ const fail = (msg: string) => { readouts.log(msg); runState = resumeFrom ? "stopped" : "idle"; setRunButtons(false); };
216+ if (!resumeFrom || !setup) {
217+ try {
218+ readouts.log("building the set-up ...");
219+ setup = await buildSetup(cfg, async (phase) => { readouts.log(` ${phase}`); await new Promise((r) => setTimeout(r, 0)); });
220+ } catch (err) { fail(`set-up failed: ${(err as Error).message}`); return; }
221+ $("summary").textContent = formatSummary(setup.summary);
222+ readouts.log(`set-up done in ${setup.summary.setupSeconds.toFixed(1)} s: ${setup.summary.nodes} nodes, ${setup.summary.substeps} sub-steps per sample, ${setup.summary.nSteps} steps`);
223+ if (setup.summary.slopeWarning) readouts.log(`warning: max slope ${setup.summary.maxSlope.toFixed(2)} exceeds the shallow-shell bound ${cfg.profile.max_slope}`);
224+ }
225+ const N = setup.mesh.n;
226+ // ---- records: the acceleration record is opt-in and must fit in memory
227+ const recording = resumeFrom ? resumeFrom.acceleration !== null : cfg.output.record_acceleration;
228+ if (recording) {
229+ const { bytes, limit } = recordBudget(setup.nSamples, N);
230+ if (bytes > limit) { fail(`refusing to start: the acceleration record of this run needs ${fmtBytes(bytes)} in memory, above this device's limit of ${fmtBytes(limit)}; shorten the duration, coarsen the mesh, or turn output.record_acceleration off`); return; }
231+ readouts.log(`acceleration record: ${setup.nSamples} samples x ${N} nodes, int16, ${fmtBytes(bytes)} in memory${bytes > 1e9 ? " (warning: above 1 GB)" : ""}`);
191232 }
192- $("summary").textContent = formatSummary(setup.summary);
193- readouts.log(`set-up done in ${setup.summary.setupSeconds.toFixed(1)} s: ${setup.summary.nodes} nodes, ${setup.summary.substeps} sub-steps per sample, ${setup.summary.nSteps} steps`);
194- if (setup.summary.slopeWarning) readouts.log(`warning: max slope ${setup.summary.maxSlope.toFixed(2)} exceeds the shallow-shell bound ${cfg.profile.max_slope}`);
233+ const dispEvery = dispEveryFor(setup.fs, cfg.output.displacement_rate);
195234 backend?.dispose();
196235 const fps = Math.max(0, Number(movieFps.value) || 0);
197236 const every = fps > 0 ? movieEvery(setup.fs, fps) : 0;
198- backend = device ? new GpuSimulator(device, setup, 8192, every) : new CpuSimulator(setup, every);
237+ backendOpts = { movieEvery: every, dispEvery, recordAcceleration: recording };
238+ try {
239+ backend = device ? new GpuSimulator(device, setup, 8192, backendOpts) : new CpuSimulator(setup, backendOpts);
240+ if (resumeFrom) await backend.importState(resumeFrom.state!);
241+ } catch (err) { fail(`could not create the simulator: ${(err as Error).message}`); backend = null; return; }
199242 moviePlayer?.stop();
200- movie = every > 0 ? new Movie(setup.mesh.n, setup.fs, { fps, budgetBytes: DEFAULT_MOVIE_BUDGET }) : null;
201- moviePlayer = movie ? new MoviePlayer(movie, showFrame) : null;
202- if (movie) readouts.log(`movie: capturing every ${every} samples (${(setup.fs / every).toFixed(0)} fps of simulated time, ${((setup.nSamples / every) * setup.mesh.n * 2 / 1e6).toFixed(0)} MB at full duration)`);
243+ if (!resumeFrom) {
244+ movie = every > 0 ? new Movie(N, setup.fs, { fps, budgetBytes: DEFAULT_MOVIE_BUDGET }) : null;
245+ moviePlayer = movie ? new MoviePlayer(movie, showFrame) : null;
246+ if (movie) readouts.log(`movie: capturing every ${every} samples (${(setup.fs / every).toFixed(0)} fps of simulated time, ${((setup.nSamples / every) * N * 2 / 1e6).toFixed(0)} MB at full duration)`);
247+ front = new Float32Array(setup.nSamples); back = new Float32Array(setup.nSamples); frontier = 0;
248+ accStore = recording ? new AccelerationStore(N, setup.fs) : null;
249+ dispStore = dispEvery > 0 ? new DisplacementStore(N, setup.fs / dispEvery) : null;
250+ energyRows = []; wallBefore = 0;
251+ rebuildSpectrogram();
252+ player.stop(); playBtn.disabled = true; wavBtn.disabled = true;
253+ } else {
254+ // keep the loaded signals and records; the movie is rebuilt from the file's displacement frames on load
255+ if (every > 0 && (!movie || movie.length === 0)) { movie = new Movie(N, setup.fs, { fps, budgetBytes: DEFAULT_MOVIE_BUDGET }); moviePlayer = new MoviePlayer(movie, showFrame); }
256+ wallBefore = resumeFrom.wallTime;
257+ readouts.log(`continuing from ${(resumeFrom.nStepsDone * resumeFrom.dt).toFixed(3)} s`);
258+ }
259+ loaded = null;
203260 updateMovieUi();
204261 plate.setMesh(setup.mesh, setup.shell.z0Node, setup.shell.hE.reduce((a, b) => Math.min(a, b), Infinity), backend instanceof GpuSimulator ? backend.stateBuffer : null);
205- $("plate-info").textContent = `${setup.mesh.n} nodes, ${plate.usesWebGPU ? "WebGPU" : "2D"} view`;
206- front = new Float32Array(setup.nSamples); back = new Float32Array(setup.nSamples); frontier = 0;
207- rebuildSpectrogram();
208- player.stop(); playBtn.disabled = true; wavBtn.disabled = true;
209- pauseBtn.disabled = false; stopBtn.disabled = false; pauseBtn.textContent = "Pause";
262+ $("plate-info").textContent = `${N} nodes, ${plate.usesWebGPU ? "WebGPU" : "2D"} view`;
263+ exportBtn.disabled = false;
264+ pauseBtn.textContent = "Pause";
210265 const kinds = setup.patches.map((p) => p.hit.exciter.kind);
211266 let lastPlate = 0;
212- runState = "running"; lastDiagnostics = null; lastProgress = { done: 0, wall: 0 };
267+ runState = "running"; lastDiagnostics = null; lastProgress = { done: backend.samplesDone, wall: 0 };
268+ const thisSetup = setup;
213269 runner = new Runner(backend, setup, {
214270 onChunk(res: ChunkResult) {
215271 const n = res.pressureFront.length;
216- if (n && setup) {
217- front.set(res.pressureFront.subarray(0, Math.min(n, setup.nSamples - res.firstSample)), res.firstSample);
218- back.set(res.pressureBack.subarray(0, Math.min(n, setup.nSamples - res.firstSample)), res.firstSample);
219- frontier = Math.min(setup.nSamples, res.firstSample + n);
272+ if (n) {
273+ front.set(res.pressureFront.subarray(0, Math.min(n, thisSetup.nSamples - res.firstSample)), res.firstSample);
274+ back.set(res.pressureBack.subarray(0, Math.min(n, thisSetup.nSamples - res.firstSample)), res.firstSample);
275+ frontier = Math.min(thisSetup.nSamples, res.firstSample + n);
220276 }
277+ if (accStore && res.acceleration) {
278+ try { accStore.push(res.acceleration, Math.min(n, thisSetup.nSamples - res.firstSample), res.firstSample); }
279+ catch (err) { readouts.log(`acceleration record stopped: ${(err as Error).message}`); accStore = null; }
280+ }
281+ if (dispStore) res.dispFrames.forEach((w, i) => { const t = res.dispSamples[i] / thisSetup.fs; if (t <= thisSetup.config.numerics.duration) dispStore!.push(w, t); });
221282 if (movie) {
222283 for (let f = 0; f < res.frames.length; f++) movie.push(res.frames[f], res.frameSamples[f]);
223284 if (!moviePlayer?.playing) updateMovieUi();
@@ -231,27 +292,28 @@ async function start() {
231292 },
232293 onDiagnostics(d: Diagnostics) {
233294 lastDiagnostics = d; readouts.setDiagnostics(d, kinds);
295+ energyRows.push([d.time, d.kinetic, d.membrane, d.bending, d.exciters, d.maxWoverH]);
234296 if (!Number.isFinite(d.kinetic + d.membrane + d.bending)) { readouts.log("energy is not finite: the run has blown up (lower numerics.cfl_safety)"); runner?.stop(); }
235297 },
236298 onProgress(done, wall) {
237299 lastProgress = { done, wall };
238- if (!setup) return;
239- progress.value = done / setup.nSamples;
240- const audio = done / setup.fs;
241- $("progress-text").textContent = `${audio.toFixed(2)} / ${setup.config.numerics.duration.toFixed(2)} s (${wall.toFixed(0)} s wall, ${(audio / Math.max(wall, 1e-3)).toFixed(3)}x real time)`;
300+ progress.value = done / thisSetup.nSamples;
301+ const audio = done / thisSetup.fs;
302+ $("progress-text").textContent = `${audio.toFixed(2)} / ${thisSetup.config.numerics.duration.toFixed(2)} s (${wall.toFixed(0)} s wall, ${(audio / Math.max(wall, 1e-3)).toFixed(3)}x real time)`;
242303 },
243304 onDone(stopped) {
244305 runState = stopped ? "stopped" : "done";
245306 if (movie && movie.length) { plate.useOwnState(); moviePlayer!.seek(0); }
246307 updateMovieUi();
247- readouts.log(stopped ? "stopped" : `done: ${frontier} samples of pressure (the last ${DECIMATION_SPAN / 2} samples of the decimation window are not produced)`);
248- startBtn.disabled = false; presetSel.disabled = false; pauseBtn.disabled = true; stopBtn.disabled = true;
308+ readouts.log(stopped ? "stopped" : `done: ${frontier} samples of pressure (the last ${DECIMATION_SPAN / 2} samples of the decimation window are not produced)${accStore ? `; acceleration record ${fmtBytes(accStore.bytes)}` : ""}`);
309+ setRunButtons(false);
249310 void backend?.diagnostics().then((d) => { lastDiagnostics = d; readouts.setDiagnostics(d, kinds); });
250311 },
251312 });
252313 void runner.run();
253314 }
254315 startBtn.onclick = () => void start();
316+resumeBtn.onclick = () => { if (loaded) void start(loaded); };
255317 function togglePause(): string {
256318 if (!runner || runState !== "running" && runState !== "paused") return "no run in progress";
257319 if (runner.isPaused) { runner.unpause(); pauseBtn.textContent = "Pause"; runState = "running"; return "continued"; }
@@ -260,6 +322,139 @@ function togglePause(): string {
260322 pauseBtn.onclick = () => { togglePause(); };
261323 stopBtn.onclick = () => runner?.stop();
262324
325+// ---------------------------------------------------------------- .cymsim files
326+// h5wasm (libhdf5 in WebAssembly, about 1 MB compressed) is loaded on first use; its in-memory file system holds the file image
327+let h5Promise: Promise<{ h5: H5Module; FS: any }> | null = null;
328+function loadH5(): Promise<{ h5: H5Module; FS: any }> {
329+ h5Promise ??= import("h5wasm").then(async (m) => { const h5 = m.default as unknown as H5Module; const { FS } = await h5.ready; return { h5, FS }; });
330+ return h5Promise;
331+}
332+
333+/** The run so far as the content of a .cymsim file. */
334+async function currentRun(): Promise<CymsimRun> {
335+ if (!setup || !backend) throw new Error("no run");
336+ const s = setup, { mesh, shell } = s, cfg = s.config;
337+ const state = await backend.exportState();
338+ const d = lastDiagnostics ?? (await backend.diagnostics());
339+ const unbaffled = new Float32Array(frontier);
340+ for (let i = 0; i < frontier; i++) unbaffled[i] = front[i] - back[i];
341+ return {
342+ yaml: configToYaml(cfg), config: cfg,
343+ 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: mesh.n, nElements: mesh.e },
344+ listener: { rFront: s.radiation.rFront, rBack: s.radiation.rBack },
345+ fs: s.fs, dt: s.dt, substeps: s.substeps, duration: cfg.numerics.duration, nSamples: s.nSamples, nStepsDone: state.step,
346+ complete: runState === "done", wallTime: wallBefore + lastProgress.wall, decimationSpan: DECIMATION_SPAN,
347+ audioBaffled: front.slice(0, frontier), audioUnbaffled: unbaffled,
348+ acceleration: accStore, taps: accStore ? s.radiation.taps : null,
349+ displacement: dispStore ? { rate: dispStore.rate, times: dispStore.times, frames: dispStore.frames } : null,
350+ energy: energyRows,
351+ hits: d.hits.map((h, k) => { const p = s.patches[k]; return { time: p.time, kind: p.hit.exciter.kind, peak_force: h.peakForce, contact_time: h.contactTime, rebound_velocity: h.velocity, energy_in: patchEnergy(p), energy_out: 0.5 * p.mass * h.velocity ** 2 }; }),
352+ state: runState === "done" ? null : state, creator: `cymsimweb ${APP_VERSION}`, created: "",
353+ };
354+}
355+
356+async function exportCymsim(): Promise<string> {
357+ if (!setup || !backend) return "no run to export";
358+ const wasRunning = runState === "running";
359+ if (wasRunning && runner) { runner.pause(); await runner.waitPaused(); }
360+ exportBtn.disabled = true;
361+ try {
362+ readouts.log("building the .cymsim file ...");
363+ const [{ h5, FS }, run] = [await loadH5(), await currentRun()];
364+ const path = "/export.cymsim";
365+ writeCymsim(h5, path, run, `cymsimweb ${APP_VERSION}`);
366+ const bytes: Uint8Array = FS.readFile(path);
367+ FS.unlink(path);
368+ const name = `${setup.config.output.prefix}.cymsim`;
369+ download(new Blob([bytes as BlobPart], { type: "application/x-hdf5" }), name);
370+ const what = `${run.audioBaffled.length} audio samples${run.acceleration ? `, ${run.acceleration.nSamples} acceleration samples` : ""}${run.displacement ? `, ${run.displacement.frames.length} displacement frames` : ""}${run.state ? ", integrator state" : ""}`;
371+ readouts.log(`exported ${name} (${fmtBytes(bytes.byteLength)}: ${what}${run.complete ? "" : "; partial run"})`);
372+ return `exported ${name} (${fmtBytes(bytes.byteLength)})`;
373+ } catch (err) {
374+ readouts.log(`export failed: ${(err as Error).message}`); return `export failed: ${(err as Error).message}`;
375+ } finally {
376+ exportBtn.disabled = false;
377+ if (wasRunning && runner) runner.unpause();
378+ }
379+}
380+exportBtn.onclick = () => void exportCymsim();
381+
382+async function loadCymsim(file: File): Promise<string> {
383+ const { h5, FS } = await loadH5();
384+ const path = "/load.cymsim";
385+ let run: CymsimRun;
386+ try {
387+ FS.writeFile(path, new Uint8Array(await file.arrayBuffer()));
388+ run = readCymsim(h5, path, (y) => { const r = parseConfigYaml(y); if (!r.config) throw new Error(r.issues[0]?.message ?? "bad YAML"); return r.config; });
389+ } catch (err) { readouts.log(`could not load ${file.name}: ${(err as Error).message}`); return `could not load: ${(err as Error).message}`; }
390+ finally { try { FS.unlink(path); } catch { /* not written */ } }
391+ runner?.stop(); backend?.dispose(); backend = null; runner = null;
392+ readouts.clearLog();
393+ readouts.log(`loaded ${file.name}: written by ${run.creator} on ${run.created}, ${run.complete ? "complete" : "partial"} run of ${(run.nStepsDone * run.dt).toFixed(3)} of ${run.duration.toFixed(3)} s`);
394+ editor.setText(run.yaml); fromYaml(run.yaml);
395+ runState = "setup"; setRunButtons(true);
396+ try {
397+ setup = await buildSetup(run.config, async (phase) => { readouts.log(` ${phase}`); await new Promise((r) => setTimeout(r, 0)); });
398+ } catch (err) { readouts.log(`set-up of the loaded configuration failed: ${(err as Error).message}`); runState = "idle"; setRunButtons(false); return "set-up failed"; }
399+ const s = setup, N = s.mesh.n;
400+ $("summary").textContent = formatSummary(s.summary);
401+ if (N !== run.mesh.nNodes || s.substeps !== run.substeps) readouts.log(`warning: the file's mesh (${run.mesh.nNodes} nodes, ${run.substeps} sub-steps) differs from this app's set-up (${N} nodes, ${s.substeps} sub-steps); the file was probably written by another version`);
402+ // signals
403+ front = new Float32Array(s.nSamples); back = new Float32Array(s.nSamples);
404+ frontier = Math.min(s.nSamples, run.audioBaffled.length, run.audioUnbaffled.length);
405+ front.set(run.audioBaffled.subarray(0, frontier));
406+ for (let i = 0; i < frontier; i++) back[i] = run.audioBaffled[i] - run.audioUnbaffled[i];
407+ rebuildSpectrogram();
408+ player.stop(); playBtn.disabled = frontier === 0; wavBtn.disabled = frontier === 0;
409+ // records
410+ accStore = run.acceleration && run.acceleration.nodes === N ? run.acceleration : null;
411+ dispStore = null;
412+ if (run.displacement) { dispStore = new DisplacementStore(N, run.displacement.rate); run.displacement.frames.forEach((w, i) => dispStore!.push(w, run.displacement!.times[i])); }
413+ energyRows = run.energy.map((r) => r.slice()); wallBefore = run.wallTime;
414+ // the displacement frames double as the replay movie
415+ moviePlayer?.stop();
416+ if (dispStore && dispStore.frames.length) {
417+ movie = new Movie(N, s.fs, { fps: dispStore.rate, budgetBytes: DEFAULT_MOVIE_BUDGET });
418+ dispStore.frames.forEach((w, i) => movie!.push(w, Math.round(dispStore!.times[i] * s.fs)));
419+ moviePlayer = new MoviePlayer(movie, showFrame);
420+ } else { movie = null; moviePlayer = null; }
421+ plate.setMesh(s.mesh, s.shell.z0Node, s.shell.hE.reduce((a, b) => Math.min(a, b), Infinity), null);
422+ $("plate-info").textContent = `${N} nodes, ${plate.usesWebGPU ? "WebGPU" : "2D"} view`;
423+ if (movie && movie.length) { moviePlayer!.seek(movie.duration); }
424+ updateMovieUi();
425+ // diagnostics
426+ const kinds = s.patches.map((p) => p.hit.exciter.kind), last = run.energy[run.energy.length - 1];
427+ if (last) {
428+ lastDiagnostics = { time: last[0], kinetic: last[1], membrane: last[2], bending: last[3], exciters: last[4], maxWoverH: last[5],
429+ hits: run.hits.map((h) => ({ peakForce: h.peak_force, contactTime: h.contact_time, velocity: h.rebound_velocity, height: 0 })) };
430+ readouts.setDiagnostics(lastDiagnostics, kinds);
431+ }
432+ lastProgress = { done: Math.round(run.nStepsDone / run.substeps), wall: 0 };
433+ progress.value = lastProgress.done / s.nSamples;
434+ $("progress-text").textContent = `${(lastProgress.done / s.fs).toFixed(2)} / ${run.duration.toFixed(2)} s (loaded)`;
435+ const parts = [`${frontier} audio samples`];
436+ if (accStore) parts.push(`acceleration record ${accStore.nSamples} samples (${fmtBytes(accStore.bytes)})`);
437+ else if (run.acceleration) parts.push("acceleration record ignored (node count differs)");
438+ if (dispStore) parts.push(`${dispStore.frames.length} displacement frames at ${dispStore.rate.toFixed(0)} fps`);
439+ if (run.state) parts.push(`integrator state (${run.state.kind})`);
440+ readouts.log(`file holds: ${parts.join(", ")}`);
441+ loaded = run;
442+ runState = run.complete ? "done" : "stopped";
443+ setRunButtons(false);
444+ exportBtn.disabled = true; // export needs a backend; Resume or Start provides one
445+ if (!run.complete && run.state) {
446+ if (run.state.kind !== (device ? "gpu" : "cpu")) readouts.log(`the file's state was written by the ${run.state.kind} backend and cannot be continued on the ${device ? "gpu" : "cpu"} backend`);
447+ else readouts.log("this partial run can be continued with Resume");
448+ }
449+ return `loaded ${file.name}: ${parts.join(", ")}`;
450+}
451+loadBtn.onclick = () => $<HTMLInputElement>("file-cymsim").click();
452+$<HTMLInputElement>("file-cymsim").onchange = async (ev) => {
453+ const file = (ev.target as HTMLInputElement).files?.[0];
454+ (ev.target as HTMLInputElement).value = "";
455+ if (file) await loadCymsim(file);
456+};
457+
263458 // ---------------------------------------------------------------- playback of the completed portion
264459 const position = $<HTMLInputElement>("position"), timeEl = $("time"), gain = $<HTMLInputElement>("gain"), normalize = $<HTMLInputElement>("normalize");
265460 gain.oninput = () => { player.setGainDb(Number(gain.value)); $("gain-text").textContent = `${gain.value} dB`; };
@@ -306,6 +501,8 @@ const appApi: AppApi = {
306501 },
307502 setup: setup ? formatSummary(setup.summary) : null,
308503 movie: movie ? { frames: movie.length, fps: movie.fps, simulatedSeconds: movie.duration, megabytes: movie.bytes / 1e6, budgetReached: movie.full, slowdown: slowdownFactor(), playing: moviePlayer?.playing ?? false } : null,
504+ records: { acceleration: accStore ? { samples: accStore.nSamples, megabytes: accStore.bytes / 1e6 } : null,
505+ displacementFrames: dispStore?.frames.length ?? 0, loadedFile: loaded ? { creator: loaded.creator, complete: loaded.complete, resumable: !resumeBtn.disabled } : null },
309506 spectrogramAxis: { scale: specScale.value, maxFrequencyHz: Number(specFmax.value) || (setup ? setup.fs / 2 : 0) },
310507 diagnostics: lastDiagnostics ? { time: lastDiagnostics.time, kinetic: lastDiagnostics.kinetic, membrane: lastDiagnostics.membrane, bending: lastDiagnostics.bending,
311508 exciters: lastDiagnostics.exciters, maxWoverH: lastDiagnostics.maxWoverH,
src/model/radiation.tsmodified+67−23View file
@@ -1,40 +1,73 @@
11 // Rayleigh-integral listener with the rim-diffraction back term, as in cymsim/radiation.py, but
2-// with the retarded-time sum evaluated at the audio rate: the per-element acceleration is
3-// decimated to the audio rate by a windowed-sinc low-pass spanning DECIMATION_SPAN audio samples
4-// (applied in the time loop through per-element accumulator slots) and delayed by an integer
5-// plus a fractional number of audio samples with linear interpolation. The per-element
6-// coefficients, the delays and the decimation taps are computed here.
2+// with the retarded-time sum evaluated at the audio rate: the normal acceleration of every node
3+// is decimated to the audio rate inside the time loop (the same Kaiser-windowed sinc kernel as
4+// the Python package, applied through DECIMATION_SPAN accumulator slots per node), the element
5+// means of the finished samples are kept in a short history, and each element's history is read
6+// at its fractional delay with a windowed-sinc interpolator of DELAY_TAPS taps. The per-element
7+// coefficients, the delay taps and the decimation taps are computed here. See THEORY.md.
78 import type { Listener } from "../config/schema.ts";
89 import type { CymbalProfile } from "./geometry.ts";
910 import type { Mesh } from "./mesh.ts";
1011
11-/** Audio samples spanned by the decimation kernel (accumulator slots per element). */
12-export const DECIMATION_SPAN = 8;
12+/** Audio samples spanned by the decimation kernel (accumulator slots per node); as in cymsim/decimation.py. */
13+export const DECIMATION_SPAN = 32;
14+export const KAISER_BETA = 8.0;
15+export const CUTOFF = 0.46;
16+/** Taps of the fractional-delay interpolator, centred: lags i0 - DELAY_TAPS/2 + 1 ... i0 + DELAY_TAPS/2. */
17+export const DELAY_TAPS = 16;
18+
19+/** Modified Bessel function I0 by its power series (converges quickly for x < 30). */
20+export function besselI0(x: number): number {
21+ let sum = 1, term = 1;
22+ const y = (x * x) / 4;
23+ for (let k = 1; k < 60; k++) { term *= y / (k * k); sum += term; if (term < 1e-17 * sum) break; }
24+ return sum;
25+}
26+
27+/** h(d) for d = -W m / 2 ... W m / 2 - 1, unit DC gain; identical to cymsim.decimation.decimation_kernel. */
28+export function decimationKernel(m: number, W = DECIMATION_SPAN, beta = KAISER_BETA, cutoff = CUTOFF): Float64Array {
29+ const L = W * m, half = L / 2, fc = cutoff / m, h = new Float64Array(L), i0 = besselI0(beta);
30+ let sum = 0;
31+ for (let i = 0; i < L; i++) {
32+ const d = i - half, x = 2 * Math.PI * fc * d, sinc = d === 0 ? 1 : Math.sin(x) / x;
33+ const u = d / half, win = besselI0(beta * Math.sqrt(Math.max(1 - u * u, 0))) / i0;
34+ h[i] = sinc * win; sum += h[i];
35+ }
36+ for (let i = 0; i < L; i++) h[i] /= sum;
37+ return h;
38+}
1339
1440 /**
15- * Decimation taps: taps[w * m + kk] is the weight with which the sub-step of phase kk (0..m-1)
16- * within audio sample j0 contributes to audio sample j0 + w - (W/2 - 1), for slot w = 0..W-1.
17- * The kernel is a Blackman-windowed sinc with cutoff 0.45 fs, normalised to unit DC gain.
41+ * Decimation taps in polyphase layout: taps[w * m + kk] is the weight with which the sub-step of
42+ * phase kk (0..m-1) within audio sample j0 contributes to audio sample j0 + w - W/2 + 1, for slot
43+ * w = 0..W-1. This is the (W, m) layout stored in a .cymsim file.
1844 */
1945 export function decimationTaps(m: number, W = DECIMATION_SPAN): Float64Array {
20- const taps = new Float64Array(W * m), half = (W * m) / 2, fc = 0.45 / m;
46+ const h = decimationKernel(m, W), taps = new Float64Array(W * m);
47+ for (let w = 0; w < W; w++) for (let kk = 0; kk < m; kk++) taps[w * m + kk] = h[kk + (W / 2 - 1 - w) * m + (W * m) / 2];
48+ return taps;
49+}
50+
51+/** Windowed-sinc taps that read x(j - i0 - fr) from x(j - i0 - t + T/2 - 1), t = 0..T-1 (Kaiser, beta 6, unit sum). */
52+export function fractionalDelayTaps(fr: number, T = DELAY_TAPS): Float64Array {
53+ const taps = new Float64Array(T), half = T / 2, i0 = besselI0(6);
2154 let sum = 0;
22- for (let w = 0; w < W; w++) for (let kk = 0; kk < m; kk++) {
23- const d = kk + (W / 2 - 1 - w) * m; // sub-step offset from the sample centre
24- const x = Math.PI * fc * d, sinc = d === 0 ? 1 : Math.sin(2 * x) / (2 * x);
25- const u = (d + half) / (2 * half), win = 0.42 - 0.5 * Math.cos(2 * Math.PI * u) + 0.08 * Math.cos(4 * Math.PI * u);
26- taps[w * m + kk] = sinc * Math.max(win, 0);
27- sum += taps[w * m + kk];
55+ for (let t = 0; t < T; t++) {
56+ const k = t - half + 1, x = k - fr; // lag offset relative to i0 (k = -T/2 + 1 ... T/2)
57+ const sinc = x === 0 ? 1 : Math.sin(Math.PI * x) / (Math.PI * x);
58+ const u = x / half, win = besselI0(6 * Math.sqrt(Math.max(1 - u * u, 0))) / i0;
59+ taps[t] = sinc * win; sum += taps[t];
2860 }
29- for (let i = 0; i < taps.length; i++) taps[i] /= sum;
61+ for (let t = 0; t < T; t++) taps[t] /= sum;
3062 return taps;
3163 }
3264
3365 export interface Radiation {
3466 coefF: Float64Array; coefB: Float64Array; // rho A / (2 pi r), front and back
35- i0F: Uint32Array; frF: Float64Array; // delay in audio samples: integer and fraction
36- i0B: Uint32Array; frB: Float64Array;
37- ringLength: number; // history ring length in audio samples
67+ i0F: Uint32Array; i0B: Uint32Array; // integer part of the delay in audio samples
68+ frF: Float64Array; frB: Float64Array; // fractional part
69+ tapsF: Float64Array; tapsB: Float64Array; // (E, DELAY_TAPS) interpolator weights
70+ ringLength: number; // element history ring length in audio samples
3871 taps: Float64Array; // (DECIMATION_SPAN, substeps) decimation weights
3972 rFront: Float64Array; rBack: Float64Array;
4073 }
@@ -56,7 +89,7 @@ export function buildRadiation(mesh: Mesh, profile: CymbalProfile, z0Node: Float
5689 }
5790 const rFront = new Float64Array(E), rBack = new Float64Array(E);
5891 const coefF = new Float64Array(E), coefB = new Float64Array(E), i0F = new Uint32Array(E), frF = new Float64Array(E);
59- const i0B = new Uint32Array(E), frB = new Float64Array(E);
92+ const i0B = new Uint32Array(E), frB = new Float64Array(E), tapsF = new Float64Array(E * DELAY_TAPS), tapsB = new Float64Array(E * DELAY_TAPS);
6093 const { c_air: c, rho_air: rho, back_diffraction_gain: g } = listener;
6194 let maxI0 = 0;
6295 for (let e = 0; e < E; e++) {
@@ -68,7 +101,18 @@ export function buildRadiation(mesh: Mesh, profile: CymbalProfile, z0Node: Float
68101 coefB[e] = (g * rho * mesh.area[e]) / (2 * Math.PI * rBack[e]);
69102 const dF = (rFront[e] / c) * fs, dB = (rBack[e] / c) * fs;
70103 i0F[e] = Math.floor(dF); frF[e] = dF - i0F[e]; i0B[e] = Math.floor(dB); frB[e] = dB - i0B[e];
104+ tapsF.set(fractionalDelayTaps(frF[e]), e * DELAY_TAPS); tapsB.set(fractionalDelayTaps(frB[e]), e * DELAY_TAPS);
71105 maxI0 = Math.max(maxI0, i0F[e], i0B[e]);
72106 }
73- return { coefF, coefB, i0F, frF, i0B, frB, ringLength: maxI0 + 4, taps: decimationTaps(substeps), rFront, rBack };
107+ return { coefF, coefB, i0F, i0B, frF, frB, tapsF, tapsB, ringLength: maxI0 + DELAY_TAPS + 4, taps: decimationTaps(substeps), rFront, rBack };
108+}
109+
110+/** The delayed, interpolated value of an element history ring at sample j: sum_t taps[t] x(j - i0 - t + T/2 - 1). */
111+export function delayedValue(hist: ArrayLike<number>, stride: number, e: number, D: number, j: number, i0: number, taps: ArrayLike<number>, tapBase: number): number {
112+ let s = 0;
113+ for (let t = 0; t < DELAY_TAPS; t++) {
114+ const lag = i0 + t - DELAY_TAPS / 2 + 1, jj = j - lag;
115+ if (jj >= 0 && lag >= 0) s += taps[tapBase + t] * hist[(jj % D) * stride + e];
116+ }
117+ return s;
74118 }
src/model/shell.tsmodified+9−1View file
@@ -14,6 +14,7 @@ export const N_DOF = 5; // (u, v, w, theta_x, theta_y) per node
1414 export interface Shell {
1515 mesh: Mesh; material: Material; numerics: Numerics; nl: number;
1616 hE: Float64Array; hNode: Float64Array; z0Node: Float64Array; z0x: Float64Array; z0y: Float64Array;
17+ normalNode: Float64Array; // (N, 3) unit normal of the rest surface at the nodes, +z side (front)
1718 De: Float64Array; Cm: Float64Array; // (E,) and (E, 3) = (C11, C12, C33)
1819 Ke: Float64Array; // (E, 81)
1920 rhoHA: Float64Array; // (E,) rho h A
@@ -37,6 +38,13 @@ export function buildShell(mesh: Mesh, profile: CymbalProfile, material: Materia
3738 for (let i = 0; i < 3; i++) { const z = z0Node[tri[3 * e + i]]; sx += Gx[3 * e + i] * z; sy += Gy[3 * e + i] * z; }
3839 z0x[e] = sx; z0y[e] = sy; maxSlope = Math.max(maxSlope, Math.hypot(sx, sy));
3940 }
41+ // nodal normal from the area-weighted mean of the adjacent elements' slopes, as in cymsim/shell.py
42+ const normalNode = new Float64Array(3 * N), gxN = new Float64Array(N), gyN = new Float64Array(N), aN = new Float64Array(N);
43+ for (let e = 0; e < E; e++) for (let i = 0; i < 3; i++) { const n = tri[3 * e + i]; gxN[n] += area[e] * z0x[e]; gyN[n] += area[e] * z0y[e]; aN[n] += area[e]; }
44+ for (let n = 0; n < N; n++) {
45+ const gx = gxN[n] / aN[n], gy = gyN[n] / aN[n], nrm = Math.sqrt(1 + gx * gx + gy * gy);
46+ normalNode[3 * n] = -gx / nrm; normalNode[3 * n + 1] = -gy / nrm; normalNode[3 * n + 2] = 1 / nrm;
47+ }
4048 const { E: Ey, nu, rho } = material;
4149 const De = new Float64Array(E), Cm = new Float64Array(3 * E), Ke = new Float64Array(81 * E), rhoHA = new Float64Array(E);
4250 for (let e = 0; e < E; e++) {
@@ -108,7 +116,7 @@ export function buildShell(mesh: Mesh, profile: CymbalProfile, material: Materia
108116 if (top > lamMax) { lamMax = top; limitingElement = e; }
109117 }
110118 const omegaMax = Math.sqrt(lamMax);
111- return { mesh, material, numerics, nl, hE, hNode, z0Node, z0x, z0y, De, Cm, Ke, rhoHA, M, Minv, Rm, adjOffsets, adjEntries,
119+ return { mesh, material, numerics, nl, hE, hNode, z0Node, z0x, z0y, normalNode, De, Cm, Ke, rhoHA, M, Minv, Rm, adjOffsets, adjEntries,
112120 mass, maxSlope, omegaMax, dtStable: 2 / omegaMax, limitingElement, zeroModes: [zmin, zmax] };
113121 }
114122
src/model/simulator.tsmodified+29−0View file
@@ -5,6 +5,10 @@ export interface ChunkResult {
55 pressureBack: Float32Array; // diffracted back term [Pa]; unbaffled = front - back
66 frames: Float32Array[]; // displacement w at every node, captured every `movieEvery` audio samples
77 frameSamples: number[]; // audio sample index of each frame
8+ /** Normal acceleration of every node [m/s^2] for the samples [firstSample, firstSample + count), row-major (count, N); present when recording. */
9+ acceleration: Float32Array | null;
10+ dispFrames: Float32Array[]; // displacement w for the .cymsim record, every `dispEvery` audio samples
11+ dispSamples: number[];
812 }
913
1014 export interface HitState { peakForce: number; contactTime: number; velocity: number; height: number }
@@ -13,6 +17,23 @@ export interface Diagnostics {
1317 time: number; kinetic: number; membrane: number; bending: number; exciters: number; maxWoverH: number; hits: HitState[];
1418 }
1519
20+/** What a backend needs to continue a run: its own arrays, opaque to everything but the same backend kind. */
21+export interface BackendState {
22+ kind: "cpu" | "gpu";
23+ step: number; // sub-steps done
24+ samplesDone: number;
25+ arrays: Record<string, Float32Array | Float64Array | Uint32Array>;
26+}
27+
28+export interface BackendOptions {
29+ /** > 0 captures w for the replay movie every that many audio samples. */
30+ movieEvery?: number;
31+ /** > 0 captures w for the .cymsim displacement record every that many audio samples. */
32+ dispEvery?: number;
33+ /** Keep the audio-rate normal acceleration of every node (returned per chunk). */
34+ recordAcceleration?: boolean;
35+}
36+
1637 export interface SimulatorBackend {
1738 readonly kind: "cpu" | "gpu";
1839 readonly samplesDone: number;
@@ -23,5 +44,13 @@ export interface SimulatorBackend {
2344 diagnostics(): Promise<Diagnostics>;
2445 /** Transverse displacement w at every node, for the plate view. */
2546 displacement(): Promise<Float32Array>;
47+ /** The integrator state, for a .cymsim file; ``importState`` continues from one (same backend kind and set-up). */
48+ exportState(): Promise<BackendState>;
49+ importState(state: BackendState): Promise<void>;
2650 dispose(): void;
2751 }
52+
53+/** Sub-steps per audio sample times audio samples between file displacement frames, for a frame rate [fps]. */
54+export function dispEveryFor(fs: number, rate: number): number {
55+ return rate > 0 ? Math.max(1, Math.round(fs / rate)) : 0;
56+}
src/run.tsmodified+12−1View file
@@ -12,6 +12,7 @@ export interface RunCallbacks {
1212
1313 export class Runner {
1414 private paused = false; private stopped = false; private resume: (() => void) | null = null;
15+ private waiting = false; private finished = false; private onPaused: (() => void)[] = [];
1516 private chunk = 512;
1617 readonly backend: SimulatorBackend; readonly setup: Setup; private readonly cb: RunCallbacks;
1718
@@ -21,7 +22,11 @@ export class Runner {
2122 const { setup, backend } = this, t0 = performance.now();
2223 let lastDiag = t0;
2324 while (!this.stopped && backend.samplesDone < setup.nSamples) {
24- if (this.paused) await new Promise<void>((r) => { this.resume = r; });
25+ if (this.paused) {
26+ this.waiting = true; for (const r of this.onPaused) r(); this.onPaused = [];
27+ await new Promise<void>((r) => { this.resume = r; });
28+ this.waiting = false;
29+ }
2530 if (this.stopped) break;
2631 const n = Math.min(this.chunk, backend.maxChunk, setup.nSamples - backend.samplesDone);
2732 const tc = performance.now();
@@ -37,6 +42,7 @@ export class Runner {
3742 }
3843 await new Promise((r) => setTimeout(r, 0));
3944 }
45+ this.finished = true; for (const r of this.onPaused) r(); this.onPaused = [];
4046 this.cb.onDone(this.stopped);
4147 }
4248
@@ -44,4 +50,9 @@ export class Runner {
4450 unpause() { this.paused = false; this.resume?.(); this.resume = null; }
4551 stop() { this.stopped = true; this.unpause(); }
4652 get isPaused() { return this.paused; }
53+ /** Resolves once the loop is idle between chunks (paused) or has finished, so that the backend's state is consistent. */
54+ waitPaused(): Promise<void> {
55+ if (this.finished || this.waiting) return Promise.resolve();
56+ return new Promise((r) => this.onPaused.push(r));
57+ }
4758 }
src/ui/form.tsmodified+3−0View file
@@ -25,6 +25,9 @@ const GROUPS: Group[] = [
2525 { key: "fs", label: "sample rate", unit: "Hz", step: 1 }, { key: "duration", label: "duration", unit: "s" }, { key: "cfl_safety", label: "CFL safety" },
2626 { key: "rot_inertia_factor", label: "rotational inertia factor" }, { key: "inplane_mass_scale", label: "in-plane mass scale" }, { key: "nonlinear", label: "nonlinear" },
2727 { key: "n_progress", label: "progress reports", step: 1 } ] },
28+ { section: "output", title: "Output (.cymsim file)", fields: [
29+ { key: "record_acceleration", label: "record normal acceleration (audio rate, about 0.4 GB/s at 4700 nodes)" },
30+ { key: "displacement_rate", label: "displacement frames", unit: "fps" } ] },
2831 ];
2932
3033 const HIT_FIELDS: Field[] = [ { key: "time", label: "time", unit: "s" }, { key: "r", label: "radius r", unit: "m" }, { key: "phi", label: "azimuth φ", unit: "rad" }, { key: "velocity", label: "velocity", unit: "m/s" } ];
tests/cpu.test.tsmodified+20−17View file
@@ -4,18 +4,26 @@ import { buildSetup } from "../src/model/setup.ts";
44 import { CpuSimulator } from "../src/cpu/simulator.ts";
55 import { fixture } from "./helpers.ts";
66
7+/** Relative rms difference over the common length. */
8+function relRms(a: ArrayLike<number>, b: ArrayLike<number>): number {
9+ let num = 0, den = 0;
10+ for (let i = 0; i < Math.min(a.length, b.length); i++) { num += (a[i] - b[i]) ** 2; den += b[i] ** 2; }
11+ return Math.sqrt(num / den);
12+}
13+
714 test("CPU time loop reproduces the Python run (dent-free, float64)", async () => {
815 const setup = await buildSetup(fixture.config);
916 assert.equal(setup.substeps, fixture.timestep.substeps);
1017 assert.ok(Math.abs(setup.dt / fixture.timestep.dt - 1) < 1e-12);
11- const sim = new CpuSimulator(setup);
12- const front: number[] = [], back: number[] = [];
18+ const sim = new CpuSimulator(setup, { recordAcceleration: true });
19+ const front: number[] = [], back: number[] = [], acc: Float32Array[] = [], N = setup.mesh.n;
1320 const py = fixture.run, hit = py.hits[0], last = py.energy_log[py.energy_log.length - 1];
1421 const nSamples = Math.round(last[0] * setup.fs); // Python ran whole blocks, slightly past the duration
1522 const chunk = 147;
1623 for (let done = 0; done < nSamples; done += chunk) {
1724 const r = await sim.runChunk(Math.min(chunk, nSamples - done));
1825 front.push(...r.pressureFront); back.push(...r.pressureBack);
26+ for (let i = 0; i < r.pressureFront.length; i++) acc.push(r.acceleration!.slice(i * N, (i + 1) * N));
1927 }
2028 const d = await sim.diagnostics();
2129 assert.ok(Math.abs(d.time - last[0]) < 1e-9);
@@ -29,18 +37,15 @@ test("CPU time loop reproduces the Python run (dent-free, float64)", async () =>
2937 assert.ok(rel(d.exciters, last[4]) < 1e-2 && rel(d.maxWoverH, last[5]) < 1e-2);
3038 // the lagged projection leaves a rigid velocity of one step's increment: tiny against the vibration
3139 assert.ok(sim.rigidContent() < 1e-3 * Math.sqrt(2 * d.kinetic), `rigid content ${sim.rigidContent()}`);
32- // radiation: a different decimation and delay scheme, so compare loosely (rms and correlation)
40+ // radiation and the acceleration record: the same decimation kernel and normal component as Python;
41+ // the delay is applied at sub-step resolution there and by a 16-tap interpolator here
3342 const pu = front.map((f, i) => f - back[i]), ref: number[] = py.pressure_unbaffled;
34- const n = Math.min(pu.length, ref.length) - 4;
35- const rms = (a: number[]) => Math.sqrt(a.slice(0, n).reduce((s, x) => s + x * x, 0) / n);
36- let best = 0;
37- for (let lag = -3; lag <= 3; lag++) {
38- let dot = 0;
39- for (let i = 4; i < n; i++) dot += pu[i] * ref[i + lag];
40- best = Math.max(best, dot / (rms(pu) * rms(ref) * (n - 4)));
41- }
42- assert.ok(Math.abs(rms(pu) / rms(ref) - 1) < 0.1, `rms ${rms(pu)} vs ${rms(ref)}`);
43- assert.ok(best > 0.95, `correlation ${best}`);
43+ assert.ok(relRms(pu, ref) < 1e-3, `unbaffled rel rms error ${relRms(pu, ref)}`);
44+ assert.ok(relRms(front, py.pressure_rayleigh) < 1e-3, `baffled rel rms error ${relRms(front, py.pressure_rayleigh)}`);
45+ py.acceleration_nodes.forEach((nd: number, k: number) => {
46+ const mine = acc.map((row) => row[nd]);
47+ assert.ok(relRms(mine, py.acceleration[k]) < 1e-3, `acceleration of node ${nd}: rel rms error ${relRms(mine, py.acceleration[k])}`);
48+ });
4449 });
4550
4651 test("linear run matches Python tightly (no chaotic amplification)", async () => {
@@ -62,8 +67,6 @@ test("linear run matches Python tightly (no chaotic amplification)", async () =>
6267 assert.ok(rel(d.kinetic, last[1]) < 1e-4 && rel(d.membrane, last[2]) < 1e-4 && rel(d.bending, last[3]) < 1e-4,
6368 `energies ${[d.kinetic, d.membrane, d.bending]} vs ${last.slice(1, 4)}`);
6469 assert.ok(rel(d.maxWoverH, last[5]) < 1e-4);
65- const pu = front.map((f, i) => f - back[i]), ref: number[] = py.pressure_unbaffled;
66- const n = Math.min(pu.length, ref.length) - 4;
67- const rms = (a: number[]) => Math.sqrt(a.slice(0, n).reduce((s, x) => s + x * x, 0) / n);
68- assert.ok(Math.abs(rms(pu) / rms(ref) - 1) < 0.1, `rms ${rms(pu)} vs ${rms(ref)}`);
70+ const pu = front.map((f, i) => f - back[i]);
71+ assert.ok(relRms(pu, py.pressure_unbaffled) < 1e-3, `unbaffled rel rms error ${relRms(pu, py.pressure_unbaffled)}`);
6972 });
tests/cymsimfile.test.tsadded+123−0View file
@@ -0,0 +1,123 @@
1+// The .cymsim file: write a short CPU run with h5wasm, read it back, and cross-check with the
2+// Python package when it is installed (python -c "import cymsim" succeeds): Python loads the
3+// file written here, and a file written by Python loads here.
4+import test from "node:test";
5+import assert from "node:assert/strict";
6+import fs from "node:fs";
7+import os from "node:os";
8+import path from "node:path";
9+import { spawnSync } from "node:child_process";
10+import { buildSetup } from "../src/model/setup.ts";
11+import { CpuSimulator } from "../src/cpu/simulator.ts";
12+import { AccelerationStore, DisplacementStore } from "../src/analysis/acceleration.ts";
13+import { readCymsim, writeCymsim, type CymsimRun, type H5Module } from "../src/io/cymsimFile.ts";
14+import { configToYaml, parseConfigYaml } from "../src/config/yaml.ts";
15+import { dispEveryFor } from "../src/model/simulator.ts";
16+import { fixture } from "./helpers.ts";
17+
18+const h5: H5Module = (await import("h5wasm/node")).default as unknown as H5Module;
19+await h5.ready;
20+const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "cymsimweb-"));
21+const python = (() => { const r = spawnSync("python", ["-c", "import cymsim, h5py"], { encoding: "utf8" }); return r.status === 0; })();
22+
23+async function shortRun(nSamples = 300): Promise<CymsimRun> {
24+ const cfg = structuredClone(fixture.config);
25+ cfg.output.record_acceleration = true; cfg.output.displacement_rate = 1000;
26+ const setup = await buildSetup(cfg), N = setup.mesh.n;
27+ const dispEvery = dispEveryFor(setup.fs, cfg.output.displacement_rate);
28+ const sim = new CpuSimulator(setup, { recordAcceleration: true, dispEvery });
29+ const acc = new AccelerationStore(N, setup.fs), disp = new DisplacementStore(N, setup.fs / dispEvery);
30+ const front: number[] = [], back: number[] = [];
31+ for (let done = 0; done < nSamples; done += 100) {
32+ const r = await sim.runChunk(Math.min(100, nSamples - done));
33+ front.push(...r.pressureFront); back.push(...r.pressureBack);
34+ acc.push(r.acceleration!, r.pressureFront.length, r.firstSample);
35+ r.dispFrames.forEach((w, i) => disp.push(w, r.dispSamples[i] / setup.fs));
36+ }
37+ const d = await sim.diagnostics(), state = await sim.exportState();
38+ const { mesh, shell } = setup;
39+ return {
40+ yaml: configToYaml(cfg), config: cfg,
41+ 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 },
42+ listener: { rFront: setup.radiation.rFront, rBack: setup.radiation.rBack },
43+ fs: setup.fs, dt: setup.dt, substeps: setup.substeps, duration: cfg.numerics.duration, nSamples: setup.nSamples, nStepsDone: state.step, complete: false, wallTime: 1.5, decimationSpan: 32,
44+ audioBaffled: Float32Array.from(front), audioUnbaffled: Float32Array.from(front.map((f, i) => f - back[i])),
45+ acceleration: acc, taps: setup.radiation.taps, displacement: { rate: disp.rate, times: disp.times, frames: disp.frames },
46+ energy: [[d.time, d.kinetic, d.membrane, d.bending, d.exciters, d.maxWoverH]],
47+ 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 })),
48+ state, creator: "cymsimweb test", created: "",
49+ };
50+}
51+
52+test("a run written with h5wasm reads back unchanged", async () => {
53+ const run = await shortRun();
54+ const file = path.join(tmp, "web.cymsim");
55+ writeCymsim(h5, file, run, "cymsimweb 0.1.0");
56+ const back = readCymsim(h5, file, (y) => parseConfigYaml(y).config!);
57+ assert.deepEqual(back.config, run.config);
58+ assert.equal(back.fs, run.fs); assert.equal(back.substeps, run.substeps); assert.ok(Math.abs(back.dt - run.dt) < 1e-18);
59+ assert.equal(back.mesh.nNodes, run.mesh.nNodes); assert.deepEqual(Array.from(back.mesh.triangles), Array.from(run.mesh.triangles));
60+ assert.deepEqual(Array.from(back.mesh.normal), Array.from(run.mesh.normal));
61+ assert.deepEqual(Array.from(back.audioBaffled), Array.from(run.audioBaffled));
62+ assert.deepEqual(Array.from(back.audioUnbaffled), Array.from(run.audioUnbaffled));
63+ assert.equal(back.acceleration!.nSamples, run.acceleration!.nSamples);
64+ assert.deepEqual(Array.from(back.acceleration!.read(0, 300)), Array.from(run.acceleration!.read(0, 300)));
65+ assert.deepEqual(Array.from(back.taps!), Array.from(run.taps!));
66+ assert.equal(back.displacement!.frames.length, run.displacement!.frames.length);
67+ assert.deepEqual(back.displacement!.times, run.displacement!.times);
68+ assert.deepEqual(Array.from(back.displacement!.frames[2]), Array.from(run.displacement!.frames[2]));
69+ assert.deepEqual(back.energy, run.energy); assert.deepEqual(back.hits, run.hits);
70+ assert.equal(back.complete, false); assert.equal(back.nStepsDone, run.nStepsDone);
71+ assert.equal(back.state!.kind, "cpu"); assert.equal(back.state!.step, run.state!.step);
72+ assert.deepEqual(Array.from(back.state!.arrays.q), Array.from(run.state!.arrays.q));
73+ assert.equal(back.creator, "cymsimweb 0.1.0");
74+ // the state continues the run exactly
75+ const setup = await buildSetup(run.config);
76+ const sim = new CpuSimulator(setup, { recordAcceleration: true });
77+ await sim.importState(back.state!);
78+ const r = await sim.runChunk(20);
79+ assert.equal(r.firstSample, run.audioBaffled.length);
80+});
81+
82+test("Python loads a file written here, and a Python file loads here", { skip: !python && "cymsim is not importable by python" }, async () => {
83+ const run = await shortRun();
84+ const file = path.join(tmp, "web2.cymsim");
85+ writeCymsim(h5, file, run, "cymsimweb 0.1.0");
86+ const pyRead = spawnSync("python", ["-c", `
87+import json, numpy as np, cymsim
88+r = cymsim.load_cymsim(${JSON.stringify(file)})
89+a = r.acceleration.as_float()
90+print(json.dumps({"n": r.n_nodes, "complete": r.complete, "steps": r.n_steps_done, "audio": len(r.pressure_rayleigh),
91+ "p": float(r.pressure_rayleigh[100]), "acc": float(a[150, 3]), "scale": float(r.acceleration.scale[150]), "frames": r.displacement.n_frames,
92+ "kind": r.hits[0].kind, "peak": r.hits[0].peak_force, "creator": r.creator, "state": r.state is None, "yaml_ok": r.config.output.record_acceleration}))
93+`], { encoding: "utf8" });
94+ assert.equal(pyRead.status, 0, pyRead.stderr);
95+ const got = JSON.parse(pyRead.stdout.trim().split("\n").pop()!);
96+ assert.equal(got.n, run.mesh.nNodes); assert.equal(got.complete, false); assert.equal(got.steps, run.nStepsDone);
97+ assert.equal(got.audio, run.audioBaffled.length); assert.ok(Math.abs(got.p - run.audioBaffled[100]) < 1e-9);
98+ assert.ok(Math.abs(got.acc - run.acceleration!.read(150, 151)[3]) < 1e-3 * Math.abs(got.scale) + 1e-9);
99+ assert.equal(got.frames, run.displacement!.frames.length); assert.equal(got.kind, "mallet");
100+ assert.ok(Math.abs(got.peak - run.hits[0].peak_force) < 1e-9); assert.equal(got.creator, "cymsimweb 0.1.0");
101+ assert.equal(got.state, true, "Python must ignore a state written by the web app"); assert.equal(got.yaml_ok, true);
102+
103+ // a file written by Python: a coarse run of the same configuration with the record on
104+ const pyFile = path.join(tmp, "py.cymsim");
105+ const pyWrite = spawnSync("python", ["-c", `
106+import json, cymsim
107+cfg = cymsim.SimulationConfig.from_dict(json.loads(${JSON.stringify(JSON.stringify(fixture.config))}))
108+cfg.numerics.duration = 0.01; cfg.output.record_acceleration = True; cfg.output.displacement_rate = 1000
109+cymsim.Simulator(cfg).run(save_path=${JSON.stringify(pyFile)})
110+`], { encoding: "utf8" });
111+ assert.equal(pyWrite.status, 0, pyWrite.stderr);
112+ const back = readCymsim(h5, pyFile, (y) => parseConfigYaml(y).config!);
113+ assert.equal(back.creator.split(" ")[0], "cymsim"); assert.equal(back.complete, true);
114+ assert.equal(back.config.output.record_acceleration, true); assert.equal(back.mesh.nNodes, run.mesh.nNodes);
115+ assert.equal(back.audioBaffled.length, Math.round(0.01 * back.fs)); assert.equal(back.acceleration!.nSamples, back.audioBaffled.length);
116+ assert.ok(back.displacement!.frames.length >= 10); assert.equal(back.hits[0].kind, "mallet"); assert.equal(back.state, null);
117+ // the two implementations agree on the record itself
118+ const n = Math.min(back.acceleration!.nSamples, run.acceleration!.nSamples);
119+ const a = back.acceleration!.read(0, n), b = run.acceleration!.read(0, n);
120+ let num = 0, den = 0;
121+ for (let i = 0; i < a.length; i++) { num += (a[i] - b[i]) ** 2; den += b[i] ** 2; }
122+ assert.ok(Math.sqrt(num / den) < 1e-3, `acceleration records differ by ${Math.sqrt(num / den)} rel rms`);
123+});
tests/fixtures/python_reference.jsonmodified+1−1View file
@@ -1 +1 @@
1-{"dkt": {"x": [0.0, 0.03, 0.01], "y": [0.0, 0.005, 0.025], "D": 10.0, "nu": 0.3, "Ke": [99406.02555828959, 692.5488717820883, -713.0398000918938, -36670.86471373518, 384.75731089896993, -538.6463817032316, -62735.16084455441, 674.4271620014778, -475.7913680624739, 692.5488717820884, 11.761025240023859, -3.7895479298892223, 168.37642628649147, 4.170287632193504, 1.6536336796122435, -860.9252980685798, 4.749937448064677, -1.4220459418140756, -713.0398000918939, -3.7895479298892223, 10.840958517132316, 620.9273695876681, -1.4471351927083524, 4.599250378723818, 92.1124305042259, -0.17076448794641216, 4.108736496816164, -36670.86471373518, 168.37642628649147, 620.927369587668, 88425.80122352082, 332.56197498173856, 871.2877784879474, -51754.93650978566, 350.8060053588072, 643.0095235321528, 384.7573108989698, 4.170287632193504, -1.4471351927083522, 332.5619749817385, 8.232701300480016, 2.705837322602525, -717.3192858807083, 3.867183339435495, 1.5449642607508982, -538.6463817032317, 1.6536336796122437, 4.599250378723818, 871.2877784879475, 2.7058373226025245, 13.314535668631951, -332.64139678471577, -0.39987497503661085, 4.898433339435494, -62735.1608445544, -860.9252980685798, 92.11243050422591, -51754.93650978565, -717.3192858807083, -332.64139678471577, 114490.09735434003, -1025.233167360285, -167.21815546967892, 674.4271620014778, 4.749937448064677, -0.17076448794641186, 350.80600535880717, 3.867183339435494, -0.39987497503661074, -1025.233167360285, 15.259678369712919, 0.8424879501443864, -475.79136806247385, -1.422045941814075, 4.108736496816164, 643.0095235321528, 1.5449642607508978, 4.898433339435494, -167.218155469679, 0.842487950144387, 8.610934315016134]}, "config": {"material": {"E": 110000000000.0, "nu": 0.34, "rho": 8700.0, "sigma0": 0.9, "sigma1": 0.0005}, "profile": {"radius": 0.2286, "bell_height": 0.013, "bell_top_radius": 0.025, "bell_shoulder_radius": 0.08, "bow_height": 0.03, "bow_power": 1.4, "h_rim": 0.001, "h_shoulder": 0.0017, "h_bell": 0.0026, "max_slope": 0.4}, "imperfections": {"seed": 1, "n_dents": 0, "dent_depth": 0.00025, "dent_sigma": 0.007, "dent_margin": 0.01, "rim_warp": 0.0, "rim_warp_modes": [2, 3, 4, 5], "shoulder_ovality": 0.0, "bell_offset": 0.0}, "mesh": {"element_size": 0.03, "smoothing": 1}, "hits": [{"time": 0.0, "r": 0.13716, "phi": 0.3, "velocity": 8.0, "exciter": {"kind": "mallet", "mass": 0.3, "alpha": 2.5, "compression": 0.012, "radius": 0.012, "gap": 0.0001}}], "listener": {"position": [0.4, 0.3, 0.9], "c_air": 343.0, "rho_air": 1.2, "back_diffraction_gain": 1.0}, "numerics": {"fs": 44100, "duration": 0.02, "cfl_safety": 0.6, "rot_inertia_factor": 0.015625, "inplane_mass_scale": 1.0, "steps_per_block": 500, "dtype": "float64", "nonlinear": true, "n_progress": 4}, "output": {"prefix": "crash", "wav": true, "npz": true, "cascade_plot": true}}, "mesh": {"n_nodes": 227, "n_elements": 402, "xy_first5": [[-2.6020852139652106e-18, -1.734723475976807e-18], [0.019117343221916425, 0.024102211562137932], [-0.009359064545977937, 0.02944032505710612], [-0.029750452483819415, 0.008697493319743578], [-0.02387984322191643, -0.01988300473366113]], "xy_last3": [[0.2125469046740543, -0.08415327274371735], [0.22141811063400504, -0.056850508205885934], [0.2267974207204896, -0.028651177192800043]], "tri_first5": [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 6]], "area_sum": 0.1637414776568517, "n_boundary": 50, "min_edge": 0.02033391325139436, "max_edge": 0.04000169788235948}, "shell": {"mass": 1.9867603122224469, "omega_max": 523630.5046043768, "limiting_element": 391, "max_slope": 0.3199066511168112, "h_e_min": 0.0010336844623136114, "h_e_max": 0.0026, "z0_max": 0.043, "z0_node_first5": [0.043, 0.042650943402618983, 0.042635328560266056, 0.04262251986580999, 0.04261272663125421], "Ke0": [1475858.697091178, 16136.614127767534, -3010.9870566465834, -744974.3738707487, 11362.375060718527, -4072.940123810292, -730884.3232204291, 11974.012833670424, -317.6100596991204, 16136.614127767536, 265.4942758428761, -26.24265371303801, -6441.08010017829, 86.62541964662539, 15.420370323525153, -9695.534027589243, 88.56425314813289, -21.572926833518178, -3010.987056646583, -26.242653713038017, 131.55137337915315, 10758.763195909394, -27.574130665448678, 74.29910824383609, -7747.776139262813, 22.60384569332314, 72.3404240116815, -744974.3738707488, -6441.080100178291, 10758.763195909392, 1700430.0901629245, -5372.6916803654785, 16709.037866806622, -955455.7162921759, -1041.4271338764995, 13982.076315404956, 11362.375060718525, 86.6254196466254, -27.574130665448678, -5372.691680365478, 149.38273125836008, -37.40584143249695, -5989.683380353046, 69.8238263400615, 18.326214585559335, -4072.9401238102923, 15.420370323525159, 74.29910824383607, 16709.037866806622, -37.40584143249694, 270.8565206314472, -12636.09774299633, -8.728469549398342, 92.53883731844594, -730884.3232204291, -9695.534027589243, -7747.776139262813, -955455.716292176, -5989.683380353046, -12636.097742996331, 1686340.0395126056, -10932.585699793926, -13664.46625570584, 11974.012833670424, 88.56425314813289, 22.603845693323144, -1041.4271338764997, 69.8238263400615, -8.72846954939834, -10932.585699793926, 188.57149433565115, 68.53407911594813, -317.61005969912173, -21.572926833518192, 72.3404240116815, 13982.076315404956, 18.326214585559327, 92.53883731844597, -13664.46625570584, 68.53407911594815, 230.30751221998605], "D0": 182.17247097844108, "Cm0": [323383084.57711446, 109950248.75621893, 106716417.91044776], "M_first3": [[0.018925757245507557, 0.018925757245507557, 0.018925757245507557, 1.349581375051811e-07, 1.349581375051811e-07], [0.018301177103390947, 0.018301177103390947, 0.018301177103390947, 1.3318962480538492e-07, 1.3318962480538492e-07], [0.0171465332628693, 0.0171465332628693, 0.0171465332628693, 1.1629463074387797e-07, 1.1629463074387797e-07]], "Rm4_first3": [[1.6642438532559925e-10, -0.15126505910989055, 1.1499294116890349e-05, 6.565421629146718, 0.0], [2.290323631435171e-06, -0.1489751718778917, 0.15825268039444734, 6.565421629146718, 0.0], [2.7975434382580364e-06, -0.14886994806718185, 0.19329964619315146, 6.565421629146718, 0.0]], "checks": {"rigid_tilt": 1.1178412285407855e-17, "curvature": 1.0574874309554616e-11, "rigid_ratio": 8.345767362347624e-17}}, "patch": {"nodes": [[40, 64, 65], [64, 96, 65], [65, 98, 66], [40, 65, 41], [40, 65, 41], [40, 64, 65], [40, 64, 65]], "weights": [[0.2252173731126971, 0.07714084870076315, 0.6976417781865398], [0.1061831804671339, 0.17972030988676246, 0.7140965096461036], [0.885284540249201, 0.040491544716748484, 0.07422391503405051], [0.035068991510846984, 0.6020618382743711, 0.36286917021478193], [0.45395423010845526, 0.3747167884065698, 0.17132898148497494], [0.4586678823965067, 0.25090048155400707, 0.29043163604948624], [0.06406325887112681, 0.48346594958593464, 0.4524707915429385]], "offsets": [8.509094170816925e-05, -1.2100312040630445e-05, -1.4522796111370723e-05, -1.533464731140119e-05, -1.3275742822043551e-05, -1.3347365329926392e-05, -1.6510078092817765e-05], "k_total": 177502680.67297047, "free_contact_time": 0.004052173591888192, "max_compression": 0.012000000000000004}, "timestep": {"dt": 2.2675736961451247e-06, "substeps": 10}, "run": {"hits": [{"time": 0.0, "kind": "mallet", "peak_force": 1408.6936215717985, "contact_time": 0.006321995464852607, "rebound_velocity": 4.626189736796063, "energy_in": 9.6, "energy_out": 3.2102447221255845}], "energy_log": [[0.0011337868480725624, 0.16329717688529438, 0.15764703961621906, 0.18473595175549615, 7.054970683789774, 0.8234470224894345], [0.005668934240362812, 2.4008851343329916, 2.0136837079334446, 1.9261672298383783, 3.167625222077137, 22.656185700120297], [0.01020408163265306, 4.635407698689287, 0.804622411252682, 0.8346449017381632, 3.2102447221255845, 9.208001220602256], [0.01473922902494331, 1.519353425145847, 2.382188983592165, 2.2757874155567825, 3.2102447221255845, 15.882210252263013], [0.01927437641723356, 4.325549291650169, 0.4865859400407113, 1.2862981947244616, 3.2102447221255845, 6.534477357990252], [0.02040816326530612, 4.642862914194414, 0.4144282958465078, 1.0110477059039795, 3.2102447221255845, 4.634266324642433]], "pressure_rayleigh": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.575835953553364e-11, -2.5772988627244747e-08, -2.74223285737792e-07, 5.302211041460007e-08, 9.924913995852767e-07, 3.1284829583108954e-06, 6.111596477627036e-06, 1.0208360211060865e-05, 1.5038878283519835e-05, 2.1174901861935532e-05, 2.7109828302606114e-05, 0.00013174071081781575, 0.0004981054658041094, 0.00021745211481896185, -0.0021583172953782244, -0.007376571426797957, -0.015634723902552917, -0.02686576582144065, -0.040851330992709434, -0.0572411281688479, -0.07565258032854284, -0.09569558597318269, -0.11697823668209054, -0.13906163125687407, -0.16148408911757453, -0.18384748647923946, -0.20578198042363602, -0.2269275913114396, -0.24691263232175387, -0.2654295717873421, -0.2822544173338371, -0.29723598594492207, -0.31026863300101054, -0.32127827176644297, -0.3302815932152237, -0.3373413474011706, -0.3425335697146255, -0.3459226612093522, -0.3476184683933219, -0.3477322385004293, -0.3463882756058122, -0.3437323767050424, -0.3398920999965954, -0.33496115854756203, -0.32907153794020305, -0.32237480335810453, -0.31499113384221655, -0.3069985575998157, -0.298467358360421, -0.2894922164914228, -0.2801525748206787, -0.2705021368003711, -0.26061997123461206, -0.2505810583037687, -0.24045437798048228, -0.23032111625363375, -0.22023997674511164, -0.2102456934383444, -0.20036230432887192, -0.1905953915629843, -0.1809441977983048, -0.17144622970324477, -0.16215024404607253, -0.15311945051207135, -0.14443715922787526, -0.1361495929335207, -0.12831002515000886, -0.12093975816771649, -0.11407779536869257, -0.10779054286234728, -0.10210625496992316, -0.09699871877664099, -0.09246375665568649, -0.08852836044930151, -0.08519051297152383, -0.08242055330890999, -0.08018001508959208, -0.07843664218822997, -0.07713642258873196, -0.07620343996841626, -0.07557484235526651, -0.0752247403923693, -0.0751350873868218, -0.0752945240309624, -0.07571898216637028, -0.0764120307638332, -0.07732779656327819, -0.07840843622313912, -0.07951863337433056, -0.08049471685323671, -0.08119168496572196, -0.08148977086797186, -0.08132291535594917, -0.08062562529779599, -0.0794353072201408, -0.0779105506371264, -0.07628973255178377, -0.07485452600690223, -0.07392454358876288, -0.07383223771974308, -0.07488131737607862, -0.07733765899258718, -0.08142234250399373, -0.0872823658073975, -0.09503697004145706, -0.10471991753308743, -0.11627599470266563, -0.12956758241808813, -0.14442950720325667, -0.16066767051016198, -0.1780423953167816, -0.1963379619104433, -0.21541511992391196, -0.23523440782992186, -0.2558565047744397, -0.2773857414980982, -0.30001004601931036, -0.3239574032266829, -0.34952643781210835, -0.37698511941680846, -0.40655087365201564, -0.438369323573563, -0.4725169378028543, -0.5089856586464783, -0.5476752705400776, -0.5884089607424359, -0.631023765045366, -0.6753078707329411, -0.720969740043964, -0.7676824241972646, -0.8151482526162422, -0.8631286575412364, -0.9113891591842115, -0.9597516078064543, -1.0080895767111637, -1.0563133210694986, -1.1043902933521423, -1.1523084021463257, -1.200028985589835, -1.2474692936327307, -1.29451580584158, -1.34102018485932, -1.3867084118277804, -1.431162650918758, -1.4738339233479543, -1.5140728432410622, -1.5511442854698645, -1.5842636291679255, -1.6126141065927897, -1.6354179027136289, -1.6519681974950244, -1.6616225530471178, -1.663806415017586, -1.6580683970445103, -1.6440856879357468, -1.6216355557015212, -1.5905955775618124, -1.5509404011512578, -1.5027804195882637, -1.4463638084723451, -1.3820009583373272, -1.3100906212760073, -1.2310628613057861, -1.1453069224231653, -1.0531924727690571, -0.9550808232988309, -0.8513973011175298, -0.7426003426973645, -0.6293187538913085, -0.5123883979527536, -0.39286176619347973, -0.2719388510405943, -0.15094271049905036, -0.0313150250438542, 0.08545824646029992, 0.19794767927160933, 0.30471523359717995, 0.4044350232817758, 0.4959064834577797, 0.578034086403436, 0.6498595350247756, 0.7105382525822124, 0.7593445506289264, 0.7957158833266326, 0.8192658579758298, 0.8297489554874915, 0.827093781844046, 0.8113468476887545, 0.7826793646844573, 0.7413453576814673, 0.6876470263367849, 0.6219455392505079, 0.5446519421302731, 0.45618169267378506, 0.35705878813229786, 0.247878900893231, 0.12928928699875022, 0.001999340470972113, -0.13319013375199557, -0.27525813589629156, -0.42292483062289504, -0.5745143404659813, -0.7278242611810914, -0.879952866173318, -1.027134137616146, -1.1646823039231362, -1.286849497025765, -1.3869215936961432, -1.4574815088388693, -1.4908666333287266, -1.479931867246597, -1.4189554879059174, -1.3045871968306202, -1.136672885059627, -0.9187122723575031, -0.6576929645829406, -0.36322935697821546, -0.04627777446545522, 0.2823826311089972, 0.6137912728471113, 0.942147669853103, 1.265171549352772, 1.5833720575929966, 1.898212965179251, 2.2095849192089507, 2.5137258277832473, 2.802633487941564, 3.065959183323637, 3.295114032782332, 3.4877894071200646, 3.64969109637662, 3.7907293749777957, 3.9161558776246532, 4.017712016606288, 4.071407785723286, 4.0440838646432935, 3.9051952350627905, 3.637770939033519, 3.2447578841692666, 2.7501095928314627, 2.1941301844010774, 1.6232759580434535, 1.0766770093654618, 0.5751081923628106, 0.11838786150149716, -0.3073222856880296, -0.7172632605496626, -1.1186385179717198, -1.5097224308794133, -1.8876020844458778, -2.259085025171371, -2.6467726750467437, -3.0851174399630925, -3.605767059633079, -4.21715495629661, -4.888399034046428, -5.5502909848035324, -6.12000420478871, -6.5397597422154545, -6.804068988759096, -6.954981987272402, -7.050117074015239, -7.12909327965323, -7.199147385973155, -7.239191939199615, -7.2096638984249815, -7.061529380749322, -6.747656528821038, -6.238960683242768, -5.539691629324162, -4.691116473996621, -3.757483984984589, -2.7987383331892355, -1.8455733857882617, -0.894632254414114, 0.0722340512807346, 1.063415668566183, 2.0743304052052767, 3.109989261869268, 4.205652176553765, 5.412022427466317, 6.741435928859663, 8.116322360765574, 9.37887588204362, 10.37552331400786, 11.048744715830745, 11.44857438886207, 11.662254798815043, 11.746332439507247, 11.719779690069819, 11.593049856969145, 11.384312620387757, 11.109508587428108, 10.759574073375608, 10.286383455776157, 9.618368851854, 8.705911138064824, 7.561653435385159, 6.259534994274189, 4.8996979379107435, 3.5757336184892905, 2.362897637044849, 1.3144015235884445, 0.44613943972780007, -0.2883361504953875, -1.0021531692294416, -1.8278981347470777, -2.8336504106069724, -3.9696378034862216, -5.102622037398461, -6.110282682120246, -6.938923509581223, -7.570964338007157, -7.96247794367891, -8.047150510892312, -7.80652046505642, -7.314755615180696, -6.706447633214157, -6.108878670529262, -5.592199591686493, -5.146764635085224, -4.686810997228615, -4.088362210826955, -3.2502260181173863, -2.1426662868925446, -0.8180270976397394, 0.6114889612216298, 2.0067698235922093, 3.231712260057755, 4.184093565878481, 4.8341824288823645, 5.249627385033511, 5.565965761977121, 5.906640420992526, 6.3211327303971645, 6.794950510635972, 7.297901886133668, 7.794422855269832, 8.20433611226536, 8.385723410614148, 8.196342469782877, 7.5940091223104496, 6.6832132368854795, 5.670835714795675, 4.7804442663518705, 4.180241466394389, 3.9290442701267176, 3.937802656409591, 3.9791750040967955, 3.769883340394672, 3.0939025587372213, 1.8997458877192217, 0.32406731202167166, -1.3594117790719091, -2.8323976266146733, -3.8344767110027105, -4.251998769938937, -4.1602488591521825, -3.78937988230719, -3.4312147520679073, -3.3466253476239283, -3.705409890442023, -4.537276275548084, -5.683643049119656, -6.800804828477289, -7.473177108312055, -7.409612308894138, -6.599387398363618, -5.315170306695009, -3.969073706476545, -2.9302292321881787, -2.404318553782874, -2.3966560033309645, -2.7330440606856174, -3.1238739164327236, -3.2630387568887222, -2.9289486605096338, -2.0469378488092778, -0.7011564567349509, 0.8911342060328691, 2.43498444048759, 3.640280357501135, 4.313694378271732, 4.425973625958861, 4.124473738852533, 3.6868362094359513, 3.435595406296207, 3.6332513901486685, 4.374059574245549, 5.516700647690707, 6.722313749342146, 7.607554919984433, 7.9278359684993855, 7.677355178594045, 7.057632413066707, 6.361692999821499, 5.86295345963707, 5.751332858855956, 6.092224689152746, 6.789323123453414, 7.586464605223731, 8.144812460148536, 8.164979030171278, 7.487421685490664, 6.140504920300259, 4.338150153597925, 2.423944006098237, 0.76364431871474, -0.3776359509046506, -0.9188914650885391, -0.9785862752969786, -0.830269916142485, -0.8136838482727986, -1.2131741782961887, -2.135064020371247, -3.444080429244688, -4.812167047700893, -5.869112966174045, -6.366547526464649, -6.256882440398833, -5.66807042536157, -4.832759214891268, -4.022760006649624, -3.4858968373999373, -3.367961624205458, -3.6419190930659835, -4.10084677184437, -4.438979158183788, -4.375492725998584, -3.7549207769563164, -2.5985700845808317, -1.109904184012315, 0.3771219178140476, 1.511356488072331, 2.0572721656315944, 1.9848121509177716, 1.4821711552465238, 0.8908827239409784, 0.5809395785928986, 0.8019487886527592, 1.569241872508546, 2.65150709165274, 3.6855186324507008, 4.358185478580408, 4.538022591660641, 4.280330291976275, 3.742144266088529, 3.1046307021850224, 2.548672263711293, 2.242767740148638, 2.2933722297494668, 2.6789765125951375, 3.232651847323981, 3.699297933551687, 3.833661985613389, 3.4909542457259963, 2.685472319947457, 1.6016798698720285, 0.5362420914131173, -0.22708514506317687, -0.5517760935297075, -0.5089100629640276, -0.33190462043011765, -0.30527278272463615, -0.646176921195972, -1.4220788427731026, -2.5320532756839826, -3.7571348160733873, -4.854186210046289, -5.645192898792441, -6.056607797717215, -6.10139013519297, -5.847087718907465, -5.413338970075858, -4.979286218520961, -4.742350652427041, -4.822081749573657, -5.18089722136621, -5.632866805314371, -5.936593781305481, -5.905860727382557, -5.475318015428669, -4.705443203202449, -3.7489585585004135, -2.80137221316622, -2.0420403682277253, -1.5753938436758916, -1.3977769658461812, -1.407395570454602, -1.4482569213151684, -1.3663197926870483, -1.0637607577843344, -0.5373455430059602, 0.12246099498769251, 0.777121074634991, 1.2984418415758452, 1.601570337831135, 1.6481505823574873, 1.4454195583072824, 1.0568577646873643, 0.6044624343271707, 0.2369986046201442, 0.07453883597082155, 0.16859726504532888, 0.4977323821708868, 0.979469320174441, 1.4791240809298218, 1.8303216508841686, 1.8874331143420524, 1.5922409805405546, 1.00892118482568, 0.2995631686146358, -0.34346122049359673, -0.765385977385528, -0.8873474056101719, -0.7166004023047694, -0.33716190313849026, 0.11924196459793197, 0.5104465213211006, 0.7075677049424481, 0.6080156593132787, 0.1661250019781795, -0.5572033935437009, -1.3774214955486264, -2.051273955056781, -2.401830641201638, -2.417296215509066, -2.2500106447281643, -2.123468881811278, -2.2232648288208767, -2.6330000307221457, -3.318272755058941, -4.138201660477664, -4.881173031688546, -5.332170992268334, -5.354279147461268, -4.94007705881226, -4.208021344948336, -3.363488758394568, -2.6565195038789056, -2.336836473459211, -2.583447209439559, -3.415989281435441, -4.648914047944632, -5.948470300793656, -6.973073340918722, -7.510484944093726, -7.541484225106615, -7.215858055209445, -6.761035734808136, -6.364804587420073, -6.092920175528965, -5.885448628161439, -5.615586835099604, -5.155532545384839, -4.411513868596842, -3.3344117445435435, -1.937377615456993, -0.3311600820558539, 1.2600218721027947, 2.5501333125285006, 3.3071105930700417, 3.4677896182582724, 3.1771000917287417, 2.7281442253890837, 2.440468396578446, 2.5358397548939497, 3.060473206330656, 3.8806247400273386, 4.748041420104169, 5.4016859482398125, 5.65961254707818, 5.468474767743822, 4.9066671101889705, 4.153780319607003, 3.436128975726114, 2.9547395453957965, 2.8153152104232593, 2.9892424638539996, 3.321461000536852, 3.580029282664804, 3.532671961297612, 3.0285807380671645, 2.054974594848379, 0.7418754959487806, -0.6915005128435168, -2.027069493066883, -3.125072339734306, -3.9432310421667633, -4.504678033682421, -4.863603110255107, -5.099741549937547, -5.322171290112439, -5.642148183036872, -6.108752762669707, -6.651227273033478, -7.081389988863759, -7.169669590557637, -6.757435052603788, -5.843305133017469, -4.594859542252123, -3.2784972159941734, -2.1490332948679973, -1.366334170131582, -0.9778054572313006, -0.9412545825101128, -1.1370617791678332, -1.3632226934698963, -1.3575356741215012, -0.8778997393705373, 0.18592529657232013, 1.7335251759117207, 3.46200147594746, 4.967289162669015, 5.893257114338846, 6.0652020107595686, 5.55814623512686, 4.667452376898423, 3.7811711377384927, 3.215709809215618, 3.109312797826668, 3.4176099421648245, 3.973532386183609, 4.548397993656476, 4.89396694575281, 4.789698018289969, 4.11266539163385, 2.9091340855493946, 1.4202293795766872, 0.025136107150153148, -0.89216365615612, -1.10022551256518, -0.6289422512172058, 0.22964566492971852, 1.046191388246298, 1.4537679598725886, 1.3119920182775442, 0.7392845189966141, 0.01272687823347688, -0.5745631761291461, -0.8102379371147226, -0.6014830217784538, 0.0034805912941800873, 0.7975881179063049, 1.442035076378583, 1.5714329288725102, 0.9416259018903929, -0.4571865562033891, -2.3756117382557838, -4.375151551115509, -5.963958525719385, -6.7511092814307725, -6.571156877446006, -5.537813295643637, -4.003232284174019, -2.435092844298376, -1.260313635474437, -0.7312334333816136, -0.8491116510188189, -1.363540293671675, -1.8589322479880694, -1.9106059450723674, -1.24909018127887, 0.1360780038430961, 1.9828992144313262, 3.8284431836499366, 5.151737134272497, 5.5585377755041, 4.944948420658237, 3.5623377949980917, 1.942141213112833, 0.7073810354978516, 0.35381378809635916, 1.0893555179181678, 2.7755976763788857, 4.968994187161711, 7.045950710062558, 8.388328850663317, 8.582227763615533, 7.565724038110266, 5.664959537834743, 3.487173443324473, 1.695588398471702, 0.7534526703281554, 0.7490717935643805, 1.380916898190176, 2.109313136009625, 2.401430994084328, 1.9496799376491918, 0.7697083687684695, -0.8317040477305948, -2.3678473586073734, -3.320254789540292, -3.3043324247186017, -2.215036840334529, -0.29222197940086103, 1.9346389127511978, 3.8100023378543564, 4.770717225140723, 4.550522101570911, 3.298758637984624, 1.5498972244072244, 0.023469081284128848, -0.6796435961042923, -0.33918473326360227, 0.8015752828621365, 2.16284294688721, 3.0788590192692227, 3.0485511306330553, 1.9006095516355235, -0.15935546486811858, -2.618529628375375, -4.816547719948776, -6.142141237711191, -6.211896599368568, -4.995118041265115, -2.8557579512805273, -0.4743320300954571, 1.3694614600133406, 2.097456953761631, 1.5774499041769732, 0.1712855935016003, -1.4436512032694693, -2.5754195181042214, -2.784836098239497, -2.0143959749511984, -0.5683720463503187, 1.0076282030632056, 2.1048663963958294, 2.258859829444146, 1.329453970796415, -0.4288021140362268, -2.4463504171980537, -4.032156750488315, -4.609324998109569, -3.92075974394511, -2.1319865435081367, 0.22221366019191846, 2.439325310605854, 3.91950530712456, 4.390097902027011, 3.9914292311557027, 3.198311567445152, 2.6186508932775587, 2.746078704256476, 3.7547230101146685, 5.420174820361624, 7.2102927972262565, 8.502533267602953, 8.814253661392598, 7.9514384466599575, 6.0576875122104665, 3.583613619380389, 1.1758504405107648, -0.520070628786454, -1.0962757596794235, -0.5520257466728419, 0.7039947726920777, 2.0288106159898653, 2.8043866015049668, 2.654482840568598, 1.5398179597572696, -0.27631969647911264, -2.3507391515994955, -4.21323308223219, -5.50265096139334, -6.064154153251193, -5.993552985068652, -5.6067211221781745, -5.323368847373334], "pressure_unbaffled": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.575835953553364e-11, -2.574585591669021e-08, -2.6679847187550807e-07, 1.4535802275241862e-07, 1.302091014154428e-06, 3.941987896191903e-06, 7.74163992677223e-06, 1.3267274123195524e-05, 2.003959506125995e-05, 2.918177656288291e-05, 3.857304191128755e-05, 0.00014773582374848527, 0.0004923108128435231, 4.09479130317451e-05, -0.002884580203808125, -0.009321239794464625, -0.019805865697164773, -0.034680182403907175, -0.05417611870814311, -0.07837643408297586, -0.10714329938163997, -0.13996175315726017, -0.1761943866114521, -0.2149385539936949, -0.25513894354710426, -0.2954370690154299, -0.33440909581786626, -0.3708236298531813, -0.40355920605957096, -0.431690226558733, -0.45444786842084844, -0.4713278162440203, -0.48198111323613746, -0.48623277675353993, -0.48408732651106434, -0.47567376586585763, -0.4612339627922486, -0.44107592503786547, -0.41561544156550706, -0.3853137127245371, -0.3506863851721431, -0.312302079261696, -0.2707088842842842, -0.22648355836409428, -0.18027494409178432, -0.13275720070700267, -0.08459005444812709, -0.03639628222131486, 0.011223154960741721, 0.05764735413290961, 0.10228916357609641, 0.1445917647326519, 0.18402408957158473, 0.2201129498859924, 0.2524456052329417, 0.2806106755597263, 0.3042796937475254, 0.32321668641995593, 0.33728040471115983, 0.34639481265619054, 0.35055651331965676, 0.3497943957320574, 0.34422478597579337, 0.33402126114764397, 0.3194120004772143, 0.3007457074636843, 0.27840813456822955, 0.25288094396923055, 0.22470653358411352, 0.1944539295973376, 0.1627884031935738, 0.13047398334065696, 0.09826742178510134, 0.06688760468866722, 0.03705322318422563, 0.009473218495666458, -0.015239025341912224, -0.03660700981273859, -0.05430029904917626, -0.06814378235445911, -0.07819713372001215, -0.08475140193997156, -0.08828697090391721, -0.08941275721466284, -0.08880506183686897, -0.08711919374474159, -0.08481465324334794, -0.08213018097977273, -0.07892202996586417, -0.07475440084162718, -0.06886795856128035, -0.060259863202605235, -0.047809938112202154, -0.03029765524625029, -0.006682057741398198, 0.023791143437972048, 0.061526510761277256, 0.10653183172908315, 0.15841929843725538, 0.2164036720283508, 0.27940828698809955, 0.3461290623554383, 0.41516788196996557, 0.48515336539054504, 0.5548052081575418, 0.6231026460674357, 0.6893927354341033, 0.7534830395434087, 0.8155802421373773, 0.8763075329318977, 0.9366977188675214, 0.9979908638885215, 1.0614581825119793, 1.12823647337649, 1.1991928029272731, 1.2748451453827627, 1.3552360443015177, 1.439859817116415, 1.5276286070836183, 1.6170196770594107, 1.706115641908587, 1.7927280410072963, 1.8744827473050192, 1.9489576509570798, 2.0138151050350217, 2.0669166677733735, 2.106319592486578, 2.1304406125495445, 2.1381257377120293, 2.1286419214538674, 2.1016073756884115, 2.0569590861505036, 1.9949875737974168, 1.9162544679594227, 1.8215420363686805, 1.711848444915822, 1.5882813210293165, 1.4520050574575896, 1.3042270269417207, 1.1460855350358625, 0.9785644703797163, 0.8024120620449253, 0.618250163052529, 0.4265449220935662, 0.2276897250825114, 0.02206073325916824, -0.18983218596693385, -0.40718108044968004, -0.6288023353756322, -0.8529907295359268, -1.0774535103947627, -1.2992905876734333, -1.515056693594659, -1.7209976256225754, -1.913241806528262, -2.0880292438250834, -2.241936829858799, -2.3720760400101857, -2.4762238173300224, -2.5528310871594697, -2.600933668449454, -2.620051915026333, -2.610093975678777, -2.571148995678329, -2.5034744700982206, -2.4074924320278615, -2.283890212013045, -2.1336001199737487, -1.9579521450456285, -1.7587312518931415, -1.5381477792813791, -1.2987968011920974, -1.0435476249798576, -0.7755256195206579, -0.49804205250219585, -0.21440439425661223, 0.07197443027741537, 0.35773260631331666, 0.6395957391973539, 0.9143884297409014, 1.1790750795480418, 1.4307546633431825, 1.6666870739664075, 1.8842949882833433, 2.081154960951134, 2.2548673960444305, 2.403055894189084, 2.523251690471608, 2.61287611489354, 2.6691714367614545, 2.68922463085362, 2.6700442431842863, 2.608615637153929, 2.5019208932079136, 2.347127221989443, 2.1415969646243083, 1.8828631108763312, 1.5686587569181265, 1.1970164302661401, 0.7664106735482894, 0.2758574281310798, -0.27475091802890417, -0.8843421987779224, -1.5501690415805185, -2.2673811955215153, -3.0286059221366393, -3.823431133512564, -4.638166275092879, -5.455897312354745, -6.256816352291025, -7.019025444960352, -7.719653664913817, -8.336315412857056, -8.848609704828215, -9.23947719108403, -9.496043358118989, -9.60985153373531, -9.576656626740908, -9.395901654051375, -9.06989623599345, -8.602901182808118, -8.000859815281212, -7.2716149223223665, -6.425556584303687, -5.476382382479825, -4.441088084054989, -3.3383785065380622, -2.1849717955210077, -0.9902381348084783, 0.24891784209227907, 1.5494609103682184, 2.9367152999091863, 4.431558842040968, 6.03476325555158, 7.715790137330995, 9.411073633482019, 11.032994038061059, 12.487466046312965, 13.695920382943854, 14.614778815282046, 15.242977784110916, 15.611986154306718, 15.762154593637016, 15.719117581912117, 15.485243774627147, 15.051453524711848, 14.420499269325791, 13.624899000964106, 12.726012202152265, 11.792532718568284, 10.86962170355377, 9.956425684905613, 9.003499595377424, 7.929420017652687, 6.6458105119605735, 5.082169292139753, 3.211244936398013, 1.073296540528668, -1.2223988897915445, -3.5404830970254957, -5.784543214618795, -7.928096315820029, -9.988719502216473, -11.97786713867337, -13.867872471939842, -15.589750745073875, -17.054314665867963, -18.18562012888822, -18.956319414503604, -19.410259453881885, -19.65339099568976, -19.80650099300627, -19.941910207454693, -20.045125220866126, -20.02887507312069, -19.78988064141498, -19.265819118335664, -18.44973626505936, -17.356287293608077, -15.97691636016583, -14.271304457649146, -12.21112452100736, -9.836283474843421, -7.254954260451957, -4.56932617851866, -1.8001589573135348, 1.1040500244079041, 4.186833125282371, 7.421266548361095, 10.711551429795497, 13.92988322688484, 16.951140399513413, 19.672379079294117, 22.011401462843246, 23.89161873446043, 25.235794662924, 25.980496368077457, 26.09598044805761, 25.596488831111458, 24.54665145171421, 23.061911469806017, 21.28377062368372, 19.330910478167358, 17.25688445761683, 15.039957103019088, 12.611041796275694, 9.912091235955778, 6.956568533853606, 3.84755215052729, 0.7310107664440224, -2.2779528321666205, -5.121294647745466, -7.751820006598502, -10.083991960146019, -12.023406196888207, -13.549846142869177, -14.752898821020114, -15.784162107509607, -16.781982766305767, -17.81358766361233, -18.83481328476644, -19.68368122621503, -20.13464374773803, -19.993060810870894, -19.173713829617437, -17.729425959726342, -15.830900493544332, -13.709936628039348, -11.581405941621364, -9.567780339095195, -7.652553872583379, -5.691054793911563, -3.4971161542124625, -0.9707723027637014, 1.8251009225363246, 4.698857450934047, 7.425414755385236, 9.801742518770544, 11.638790618937978, 12.762585170948945, 13.077696064441763, 12.647624511825786, 11.70938099706413, 10.605951605019435, 9.686978696852377, 9.212601705269853, 9.262618428888729, 9.679132056001446, 10.102634359814303, 10.11594340451327, 9.427694600445411, 7.995433933882307, 6.027555959221774, 3.880969390620164, 1.9287558121192463, 0.4536145631422146, -0.42494101201654066, -0.7823253039335047, -0.8552754413529282, -0.9517788514371217, -1.3556215968320013, -2.2512346999964805, -3.652429004809631, -5.344804291543535, -6.908627822478962, -7.874329771125442, -7.958617190355286, -7.23230759191518, -6.097247990885442, -5.090800070182944, -4.652251473184276, -4.971737856523722, -5.950886568529382, -7.251336072177448, -8.412926138929238, -9.015374109171876, -8.821834689272322, -7.8406761731896735, -6.291718681071352, -4.513027605641742, -2.8537150101939655, -1.582993178325209, -0.8264119765541018, -0.5319130429110039, -0.4789848755198056, -0.3450267118059842, 0.18436421986485563, 1.2957685466468423, 2.952608895790124, 4.867799308016498, 6.593139297903363, 7.713796911887796, 8.045275657874322, 7.713513497493045, 7.078449043657773, 6.562998129521695, 6.490939837608676, 6.9943741316710515, 7.985791725132195, 9.180238305630136, 10.177876742446516, 10.600435099549848, 10.224964763411958, 9.05531823381253, 7.320829416979231, 5.415866445253551, 3.788025631538569, 2.7939091686107007, 2.569827732352263, 2.9725410904508878, 3.6165821554614106, 3.9938183202317195, 3.6388278983275413, 2.293924610905825, 0.016253678259429805, -2.830313803450335, -5.715600782118457, -8.15351817694562, -9.866796210227308, -10.828351316383209, -11.200963797144254, -11.250655778809815, -11.270762195584705, -11.500544245246285, -12.030685927572394, -12.738903845128556, -13.320158988470663, -13.41840820376335, -12.781507154021849, -11.354004017693132, -9.29429672470422, -6.941004844663606, -4.725407549848657, -3.0321383822376315, -2.0641389336770533, -1.7742164308593347, -1.880393423946598, -1.9559307428909867, -1.577184890106272, -0.4878305407043202, 1.2886942734153335, 3.45345572764232, 5.570617571335526, 7.275520299990028, 8.424985178819579, 9.102890716349759, 9.518570039682501, 9.906290091824683, 10.475271834716002, 11.369796474610125, 12.601920051634798, 13.999267141919567, 15.234947710182064, 15.940700015271602, 15.842742342662623, 14.865161080968612, 13.177978195504288, 11.172923510879286, 9.34799531630865, 8.117730531428931, 7.631186345849666, 7.702785361590464, 7.895338999569489, 7.704012478582831, 6.7541574856479425, 4.937649084239981, 2.443182126653964, -0.3211501879801002, -2.8769317661024667, -4.838906903408689, -6.0283269608142405, -6.495858309652149, -6.474146344887157, -6.31027494759386, -6.387127890829162, -7.0090000641690136, -8.272269865317416, -10.00026849828193, -11.802189166245256, -13.234838154636588, -13.979622393278163, -13.947461928127733, -13.281406531420942, -12.28340168136789, -11.302905781982671, -10.613164948290878, -10.31006750205115, -10.280417087325223, -10.256397880860508, -9.925471003098075, -9.047874604687806, -7.546199474249154, -5.542818699708786, -3.330234896001602, -1.2827253113446029, 0.25970415371454947, 1.0987075580288344, 1.2443229127644742, 0.9202536354140006, 0.505206228148382, 0.4201743604911041, 0.9878821872069219, 2.318923902794333, 4.284865226829484, 6.584618523117825, 8.848520212088207, 10.731345261952969, 11.99229905622694, 12.562082273713912, 12.566022688952671, 12.273815922830345, 11.989044690570202, 11.930156571973914, 12.157956474680207, 12.572343828717473, 12.960378572160844, 13.069951979618628, 12.69571944426429, 11.753048847874968, 10.305632331616952, 8.541932430637667, 6.73114325233928, 5.176295415647112, 4.14563740383382, 3.7729920428573336, 3.9716511541579527, 4.434633791156964, 4.751529104092555, 4.586501307946044, 3.8141330413671475, 2.5519476674331205, 1.1012731394272919, -0.1634851336075065, -0.9257549054243461, -1.0483060966968853, -0.6390685334621269, -0.01884671461707388, 0.3998167703121238, 0.25591831232212536, -0.6651270015944477, -2.3989945037443126, -4.798477763887101, -7.54428656077855, -10.207338537613547, -12.387440646798673, -13.86960004004541, -14.69905039501533, -15.13605930188438, -15.526938288716392, -16.1482131556798, -17.07766012400372, -18.14853430095782, -19.015704638136516, -19.299046418879342, -18.730569064417466, -17.24267029854012, -14.978524790872687, -12.251701331060117, -9.484219434824482, -7.112783148109965, -5.45032784031993, -4.547700150756488, -4.14080305709207, -3.7355105781809015, -2.8012011807079853, -0.9821465855473264, 1.7664542501528717, 5.167897419922738, 8.734244817171923, 11.950555482734694, 14.46314348367851, 16.19582607613981, 17.34248762457328, 18.24567772932372, 19.228777632632678, 20.457458398370665, 21.871730368947194, 23.19861455824997, 24.035875247526597, 23.97818941163982, 22.748346835747885, 20.30069449706098, 16.863618739599502, 12.891802851092486, 8.932421500421459, 5.451143562210569, 2.6811374543711843, 0.5600841534324279, -1.2073598807837254, -2.993998651759104, -5.091167142028789, -7.620570221891081, -10.524949597540182, -13.601221903768002, -16.54939307699744, -19.039839725600952, -20.802472800404892, -21.715755295636804, -21.855749625183993, -21.475308352008664, -20.9107997619189, -20.44345571390805, -20.175670011199742, -19.994321667851512, -19.642617931394735, -18.842876076568913, -17.39064538232123, -15.19285376710661, -12.274554844551474, -8.779129283380952, -4.961824781061908, -1.1611328217361685, 2.266918326912445, 5.0434032725226965, 7.049935376031055, 8.361114920053652, 9.214732871999644, 9.920675400054979, 10.725092282727706, 11.697289689105395, 12.72209753811948, 13.602288295573803, 14.183671725877183, 14.414811986938389, 14.330146902429421, 14.00441164678259, 13.52269171162676, 12.975397995944023, 12.457307400328714, 12.04887573443271, 11.78166503021385, 11.60817225912897, 11.396317330681933, 10.96599968815745, 10.174479806618947, 9.01715276449831, 7.668821045203113, 6.4134345592187625, 5.495555160182889, 4.9925924785160145, 4.78711416598698, 4.632886608226907, 4.242072361106925, 3.343759015199359, 1.7328403390324176, -0.6616317252216235, -3.7185016838506275, -7.131752123136132, -10.491066133084153, -13.396626711008327, -15.561584283889296, -16.87387709575991, -17.409512709443174, -17.398418884347105, -17.147100772228466, -16.935155774783265, -16.923515282084853, -17.113497554813236, -17.365807075009066, -17.4613279842267, -17.18343052179591, -16.399822207653663, -15.109847914938143, -13.435540436427232, -11.570261098612756, -9.712409473733365, -7.997016637895531, -6.435027692910917, -4.882543409391321, -3.0657776384872077, -0.6707361636929376, 2.5255923423852713, 6.538642001933392, 11.130931430330003, 15.851651172444939, 20.136406349330738, 23.439333540544425, 25.36706075663594, 25.775344191924958, 24.801450836403014, 22.822300909714635, 20.339222363304067, 17.8164664703552, 15.53520981641338, 13.52513884028874, 11.598108974207829, 9.468138010050069, 6.908424595641558, 3.8697047600692756, 0.5028429596657145, -2.9026970967603574, -6.010162559430823, -8.5271478534633, -10.290810366536382, -11.321365861687491, -11.812602544543788, -12.059670618969513, -12.353942791571605, -12.875241648793624, -13.60709636210658, -14.307357572593519, -14.56838711566466, -13.976329706549691, -12.316223926877628, -9.709963324342924, -6.595095168312724, -3.5578689761824096, -1.122081318440983, 0.40818519907302964, 1.0074771274997931, 0.8932094492821854, 0.424656878868813, -0.02147526174268677, -0.15481148668689393, 0.16593236614035334, 0.9018819332794976, 1.8263068557217754, 2.5648261457763293, 2.7213473980627594, 2.0680478010069896, 0.6920285627738086, -1.0098410905948332, -2.4916362161491885, -3.274764941749116, -3.109341707283343, -2.0303970112485556, -0.32502491803791334, 1.5523540036724701, 3.1034120530868123, 3.940160934487785, 3.9172536850622057, 3.1664060017256137, 2.0200245201375964, 0.8844439264289372, 0.11559515096560435, -0.08787934484194482, 0.2507013262754807, 0.9056790697143249, 1.561005507827249, 1.9638229583077904, 2.038975282938555, 1.9083302165980633, 1.8228323377828308, 2.0568560138015597, 2.802469100928767, 4.081389973605192, 5.710246014635688, 7.363532757874328, 8.714749429982541, 9.56420348983364, 9.883795758161476, 9.793152210077531, 9.5164194862913, 9.330890341474952, 9.483737805934012, 10.076577998509693, 10.97762002973027, 11.841971062540662, 12.2481504710546, 11.8606570166334, 10.518826236295999, 8.232991364628235, 5.138043292375536, 1.4538926715421305, -2.5362098134644486, -6.51083223256929, -10.163185124172191, -13.270314358889145, -15.733272288499052, -17.5607892940292], "fs": 44100}, "run_linear": {"hits": [{"time": 0.0, "kind": "mallet", "peak_force": 1977.553084535146, "contact_time": 0.004492063492063492, "rebound_velocity": 4.849030136533902, "energy_in": 9.6, "energy_out": 3.5269639897520992}], "energy_log": [[0.0011337868480725624, 0.11518240667885472, 0.19065997418634467, 0.11451987457233755, 7.022382852819921, 0.6860066068981031], [0.005668934240362812, 0.5570099533337556, 2.8770921846038275, 2.6003136787430403, 3.5269639897520992, 23.43797422196923], [0.01020408163265306, 4.998916708394579, 0.1307667480176439, 0.8429981585032716, 3.5269639897520992, 7.36942830859002], [0.01473922902494331, 1.4294124659295904, 2.1731314274331015, 2.3215972995204033, 3.5269639897520992, 15.067711563105279], [0.01927437641723356, 3.334860836020404, 1.2724056899637306, 1.2420828517676603, 3.5269639897520992, 13.382669747904702], [0.02040816326530612, 0.9979042635872203, 2.389129283330328, 2.450891765985065, 3.5269639897520992, 17.103206826435265]], "pressure_unbaffled": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.575835953553448e-11, -2.5745855916083203e-08, -2.667984702553921e-07, 1.4535817882720368e-07, 1.3020939219515675e-06, 3.94200956174839e-06, 7.74173673202151e-06, 1.3267591433321903e-05, 2.0040431107102075e-05, 2.9183643117710726e-05, 3.8576680284117305e-05, 0.00014774211913339387, 0.0004923205147802023, 4.096054478851008e-05, -0.0028845728998242327, -0.00932128030702288, -0.019806099200608038, -0.03468098424022304, -0.054178274480636814, -0.07838132545190035, -0.10715299441964092, -0.13997884185058584, -0.17622134260587013, -0.2149763557355056, -0.25518465009053304, -0.29548006118489434, -0.33442570593574095, -0.3707699601584844, -0.403362014622779, -0.4312359296844236, -0.4535698344251444, -0.46979233598320275, -0.47947266968753843, -0.48233934939972545, -0.47828672137668826, -0.4673218842156348, -0.44955627643774976, -0.4251628383868588, -0.39442259104279737, -0.35766770603424325, -0.3152960529508156, -0.26777532964377004, -0.21557520265492947, -0.1592208985370125, -0.0993402804517789, -0.036619576623667494, 0.028235016390353085, 0.09451969861139581, 0.16151892490055525, 0.22846611056564847, 0.2946007192248025, 0.35916844966230055, 0.4214214662061847, 0.4806556222459323, 0.5362177831234832, 0.5874518328469904, 0.6337837069988869, 0.6747353360823061, 0.7099299578234962, 0.7390647340327439, 0.7619196491088664, 0.7783157393483066, 0.7881715959825628, 0.7914700194732956, 0.7882506330841365, 0.778671933673678, 0.7629222270024162, 0.7412758427152082, 0.7140501699263486, 0.68156494493065, 0.6442128151735648, 0.6024632752390858, 0.5567579330674153, 0.5074975733415592, 0.455105069241882, 0.40003796930920044, 0.3427369996691762, 0.2836275728539337, 0.22315079263311713, 0.1617843382687413, 0.09998157961451182, 0.038174476430275134, -0.023209872099540618, -0.08374290989872087, -0.1430195534841236, -0.2006690061908739, -0.25628568565069954, -0.30950196687286613, -0.35989205677331043, -0.40709823601215933, -0.45077630800884155, -0.4906152674711578, -0.526362314554282, -0.5577068859901175, -0.5844307515265869, -0.6063936151757886, -0.6235036540928064, -0.6357109519367689, -0.6430031146882986, -0.6454415433680832, -0.6431058468815186, -0.6361385714713705, -0.6247105501231083, -0.609009872997285, -0.5893231567646925, -0.5659678036453314, -0.5392688762378166, -0.5095344586411966, -0.4771441828796046, -0.4424926987874236, -0.4059090072023054, -0.36773729470793254, -0.3283553099303184, -0.28815609828906597, -0.24753682876876576, -0.20684377141380733, -0.16640554212837028, -0.12656048129258013, -0.08769844227670626, -0.05014927464940949, -0.014236073471829536, 0.019753561834203903, 0.05154994172402194, 0.08090910112995764, 0.10761819603426176, 0.13150680978554752, 0.15234774264769102, 0.1699478002261925, 0.18417229423818782, 0.19493339735248205, 0.20214479162087612, 0.20571190099255154, 0.2056117221734508, 0.2018568230467967, 0.19448363833204435, 0.1835997742555468, 0.16933274174914187, 0.15182952255804044, 0.13133090656074375, 0.10812970317321463, 0.08253558728180732, 0.05486763541571393, 0.025555248345380643, -0.00494603608515054, -0.03612842676457251, -0.06748281285988189, -0.09849197087704686, -0.12862263187224504, -0.15738398900282685, -0.18432611279485903, -0.20904513484488768, -0.23115948049999627, -0.25029059035054513, -0.2661532546394521, -0.278540025970051, -0.28729732234658173, -0.29229215657138385, -0.29344614512087763, -0.29076291355215456, -0.2842887389224225, -0.27409971186925486, -0.2603227853860632, -0.24316396899913797, -0.22281527945164925, -0.1994777368240899, -0.173372951843111, -0.14477474633465853, -0.11391747974034602, -0.08108645012521576, -0.04662497892784223, -0.010898417570278346, 0.025706899928953225, 0.06282030208303684, 0.10005046576328235, 0.1369570398332438, 0.1732013986213488, 0.2083768244689646, 0.2420947943753819, 0.273999530595877, 0.3037382556937499, 0.3309954903930602, 0.355464351149086, 0.3768659378438025, 0.39495137036521827, 0.4095496920197965, 0.42051876735804505, 0.42779381784582177, 0.4313543309072328, 0.4312472383468971, 0.42755473873583905, 0.42039009748726225, 0.4099127714664322, 0.39633445794819966, 0.3798485554553681, 0.360829500067939, 0.33975364450091056, 0.31701258978395414, 0.2928572846802016, 0.2674465270769317, 0.24097058099213145, 0.21357436230323879, 0.18542589531372816, 0.15672676701555394, 0.12778847619906394, 0.09875992731634096, 0.06961274438361818, 0.04027198061580789, 0.010690811248782267, -0.019098225682785464, -0.04897279108827819, -0.07873568348043453, -0.10825045045491397, -0.13752115557415442, -0.16654889012518803, -0.1953046459890166, -0.2237200319335242, -0.25154745177240867, -0.2783985142516599, -0.30383143174502936, -0.32747880010371, -0.3488782927179727, -0.3675638207967634, -0.3831408907553073, -0.3952135551566219, -0.4033987360147211, -0.40738791678856995, -0.40690928373261576, -0.401750858711294, -0.3917910315617405, -0.37696749024448617, -0.35729446767171735, -0.33287767174932215, -0.30391409993518237, -0.27071086564361463, -0.233596025749998, -0.1929274420265012, -0.14909498566130133, -0.10250741197166416, -0.05359555715209188, -0.0027890514649915182, 0.0494874400586939, 0.10278126536573196, 0.15657553247131994, 0.21038300100999074, 0.263719801884969, 0.3160761165828311, 0.3669461848496597, 0.41581675550907227, 0.46218933216595876, 0.5056577016669264, 0.5457829262052001, 0.5821887885324321, 0.6145781808581229, 0.6426779673737347, 0.6662304088619969, 0.6850455395190848, 0.698964058600469, 0.7078889476555669, 0.7117688947348704, 0.7106039891056708, 0.704468627438445, 0.6934343297376934, 0.6775776521005316, 0.6570002310320956, 0.6318339273174459, 0.6022293148923848, 0.5684055087099762, 0.5305503580506712, 0.48892285749869413, 0.4438331414788714, 0.39563832166192553, 0.3446942091499976, 0.29140258931893737, 0.2362396092717739, 0.17970764807395034, 0.12232133351843846, 0.06458919060012847, 0.007027249296623942, -0.04982558763642966, -0.1054594107869141, -0.15932101962483605, -0.21087282159707216, -0.25967809475027026, -0.3052491317463476, -0.3472188569933091, -0.3852500822894598, -0.41905958850564196, -0.4484083709712725, -0.4730522996364495, -0.49285319127079197, -0.5077469855167062, -0.5177000015758806, -0.5227265929061716, -0.5228362726550874, -0.5181465663434579, -0.5087849406278282, -0.4949700038243606, -0.47692634649513105, -0.454929481700631, -0.4292681610610947, -0.4002748519238013, -0.36831893714584274, -0.333788840865493, -0.29707009500331666, -0.2586236001564925, -0.2188933654630073, -0.17835629495344285, -0.1375338699340005, -0.09692922256263473, -0.056996934888865904, -0.018239557010696496, 0.01884556496874374, 0.05381874044908204, 0.08626727057960186, 0.11583677504224635, 0.14221428472260672, 0.16516088490846606, 0.18448751402377828, 0.2001218864045442, 0.21201209950029193, 0.22017687536463632, 0.22469049221921852, 0.22574239304392552, 0.2235415350951347, 0.2183110516365888, 0.21031135404725054, 0.19984861068619741, 0.18719717082522086, 0.17264483621892693, 0.15644838382896503, 0.13886071131014788, 0.12017751794459584, 0.10065483009777437, 0.080498057661179, 0.059910801225220016, 0.03909685682297399, 0.018259348107379954, -0.0023556131127335095, -0.022530127681013472, -0.04206737788339736, -0.060768628174055206, -0.07842089188210077, -0.09486067711773735, -0.10994019023630905, -0.12344520886505654, -0.1351672586249507, -0.1449809317401365, -0.15273614281394648, -0.15828333748257212, -0.1614775934800401, -0.16219863281892494, -0.1603522564155378, -0.1558507246240839, -0.14858710429842625, -0.13846578763798809, -0.12545325889724712, -0.10959703559537931, -0.09089777407076177, -0.06937996224173881, -0.04511119588731477, -0.018208026350481625, 0.011142501823598525, 0.042746573886373346, 0.07633014388883805, 0.11155589955113077, 0.14810868565742602, 0.18565476091208188, 0.2238389846194933, 0.2622582423620546, 0.3004892522014648, 0.338153200173249, 0.3748157466387668, 0.41004143535212734, 0.4433862169901308, 0.47440692414136076, 0.5026511694801781, 0.5276878293532569, 0.5490993728371832, 0.566420563655846, 0.5792360087053633, 0.5871537615540516, 0.5898271580388859, 0.5869640719816556, 0.5783043687992026, 0.5636660486683005, 0.5429318888866281, 0.5160669981431497, 0.4831555912990559, 0.44441307568907257, 0.40017162781072474, 0.35085002992943165, 0.2969215843185642, 0.23890962837823748, 0.17743551511758482, 0.11319780017482224, 0.046876944310040955, -0.020810130426023254, -0.08915819110692191, -0.15744726599391234, -0.22501938121770249, -0.2912353137522511, -0.3554583180271623, -0.41711207544107803, -0.47567317970324613, -0.5306773237345335, -0.5816957737198738, -0.6283321066830223, -0.6702315486918671, -0.7070577596323633, -0.738523510094296, -0.764329436750254, -0.7842085203179325, -0.7979984349096101, -0.8055531101101141, -0.806774328257889, -0.8016044372549951, -0.7900427734744129, -0.7721750816676748, -0.7481456050827914, -0.718119773759958, -0.6823866959067701, -0.6413108983218878, -0.5952770588399652, -0.5447603770485355, -0.4902752802626848, -0.43243240295838975, -0.3718299468643143, -0.3090810604495603, -0.24486757678628496, -0.1798100811331429, -0.11452996602847353, -0.04962307469029654, 0.014330147450122607, 0.07682227447427792, 0.13734506600139315, 0.19537380610034172, 0.2505050327071677, 0.3023301874835454, 0.3504653659727936, 0.3946083476634585, 0.43444713246360994, 0.4697220631330356, 0.5002026003378481, 0.5256474671924732, 0.545871546800912, 0.5607259422029138, 0.5701592788773642, 0.5741439910686548, 0.572704700718939, 0.5658945670805633, 0.5538790133575172, 0.5368967542267628, 0.5152593047431365, 0.48930604852195003, 0.4594439149892613, 0.42612768086570296, 0.38985208338483385, 0.35106962966081895, 0.3103072608218581, 0.2681383930147075, 0.2250731458219927, 0.18163789736563668, 0.13834704874402573, 0.09565950928804082, 0.05399181772396379, 0.013735445059038787, -0.02476541460855967, -0.06114766994427698, -0.09507789260470736, -0.12631843476948426, -0.15470507558499413, -0.18006951614936967, -0.20228943205367345, -0.22125913903753353, -0.23697978394760166, -0.24943796485783698, -0.25868822808792785, -0.2648409710314299, -0.26802221789272057, -0.26839159844730964, -0.26612947160751754, -0.2613779219195226, -0.25430492639221386, -0.24510912415663116, -0.2340268807754845, -0.22122434507696193, -0.206880644677344, -0.19112285154910513, -0.17412510189630043, -0.15601618463409633, -0.13683850362322109, -0.11670495262309384, -0.09575323038266705, -0.07411824717060053, -0.05191818012319564, -0.029270060239526288, -0.006329513633778282, 0.016695481859843195, 0.039615218521455275, 0.06219927971869425, 0.0841948227400825, 0.10532452211782088, 0.12526231078249336, 0.1436640370065658, 0.16021995981821135, 0.17456273718605234, 0.18634529644783085, 0.19521958211047633, 0.2008869313880153, 0.20302656126297033, 0.20140960985223416, 0.19590364910231942, 0.18636411759012647, 0.1727039897371955, 0.1548430723125125, 0.13281758288860562, 0.10671830190848222, 0.076663097664702, 0.042883075038593094, 0.005655919594920317, -0.03470205056362338, -0.07779300444445489, -0.12320923617131645, -0.17050115280197164, -0.21914614931756618, -0.2686064951053488, -0.3183239462909291, -0.3676955433468359, -0.416118504455403, -0.4629517230840695, -0.50753463962425, -0.5492343123128072, -0.58742912409312, -0.6215133959404885, -0.6509220645661407, -0.6751414361444827, -0.693754660060718, -0.7063616118824618, -0.7126318469386578, -0.7122926647974539, -0.7051379984501792, -0.6910470379588429, -0.6699935640105668, -0.6420175866059271, -0.6072666178358135, -0.5659776739801612, -0.5184290736407986, -0.4649573873658694, -0.4060373697672965, -0.34218838567304677, -0.27395145814113997, -0.20193698357033912, -0.12678884451938777, -0.04922650041343154, 0.02998566817218591, 0.1100330586220047, 0.19008398445815194, 0.2692780794312762, 0.34671247659765175, 0.4215279618290825, 0.49294664004216493, 0.5601888017526108, 0.6224721316651733, 0.6790673337042815, 0.7293557718076243, 0.772749457312452, 0.8087145431967455, 0.836839560161274, 0.8567874425724172, 0.868382985682693, 0.8714770762716023, 0.8660083079973772, 0.8520799166682743, 0.8298566209543075, 0.7996221727725406, 0.7617549595580518, 0.716674979292849, 0.6648883493546326, 0.6069784678396312, 0.543619136272169, 0.4755580396084116, 0.40356624920000617, 0.3285133892188586, 0.25130985774833375, 0.17285322602572056, 0.09402410729954637, 0.015693670257519526, -0.0612908552449028, -0.13608636648000103, -0.20790058750329843, -0.27601292924750986, -0.33977834480358593, -0.3985930920830195, -0.451962898776589, -0.4995052202687672, -0.5409057630247528, -0.5759551836709802, -0.6045488985992522, -0.6266772570552501, -0.6424008580134111, -0.6518253743739777, -0.6551877448230092, -0.6527686083135413, -0.6448517498727795, -0.6317531718977698, -0.6138345852523893, -0.5915006860978701, -0.5652023598466627, -0.535398260685349, -0.5025431239683694, -0.4671168483867119, -0.42956484560099634, -0.3903228619120159, -0.34987634963405617, -0.30869890618992496, -0.2672853045830281, -0.22611766579752515, -0.18561752552272004, -0.14624052634214382, -0.10838536566009359, -0.07245524829294255, -0.038804486210010106, -0.007720653448678987, 0.020561223587501797, 0.045879385179941334, 0.06809828384422802, 0.08721211333408549, 0.10320613507921553, 0.11617224679273087, 0.12620637321201053, 0.1334001228912685, 0.13794474580931188, 0.1400502363033028, 0.1398927565504433, 0.1377079997017662, 0.13368337847353828, 0.12798812246795382, 0.12072817741453383, 0.112075414859546, 0.10220403282571233, 0.09126365487032059, 0.07936329251617336, 0.06661621743842976, 0.053161234945031804, 0.03913753573937859, 0.024737099302204094, 0.01012067805718335, -0.004561821376713349, -0.019120287136494593, -0.0333475173445639, -0.047112834224522254, -0.060256636546910394, -0.07265695011089307, -0.084168678008951, -0.09465189199040971, -0.10401753152092522, -0.1121838829765392, -0.11900742596374086, -0.12439850211571163, -0.12827661719258057, -0.1305401989156667, -0.13105208750639158, -0.12970738372629664, -0.1264439296415125, -0.12119158465584223, -0.11387637470423563, -0.10446398029620144, -0.09293308802094716, -0.07930024683123715, -0.06361996289901253, -0.0459714781099114, -0.026474061273041756, -0.005325096227417118, 0.017251073447021807, 0.041053725741670266, 0.0657915345625997, 0.09118096686653657, 0.1169729292774722, 0.1429057621938702, 0.1687087386432651, 0.1941729783497823, 0.21903755935392683, 0.24313125082933396, 0.26627576694687427, 0.288326058949792, 0.3091319552018772, 0.32853649304925464, 0.3463959502707512, 0.3626196740481276, 0.37709739174616064, 0.3897273445338495, 0.40039187917664043, 0.40893332628470774, 0.4151955859304769, 0.41897256151356604, 0.4200341521879748, 0.41818557120224464, 0.4132536373582154, 0.4050533465464329, 0.3934175442785697, 0.37818521166966856, 0.3592439875389295, 0.33650960639104954, 0.30996595156152323, 0.27959316214701496, 0.24548980700198925, 0.20777798312590967, 0.16654949808497993, 0.12199784660051971, 0.07440434313924173, 0.024162928797389772, -0.02834111728355146, -0.08270477819888208, -0.1384415209428089, -0.1950541092448348, -0.2520392642689835, -0.30886882423264594, -0.3649503304145496, -0.4196846311942969, -0.4724495012681571, -0.5225749606743066, -0.5694300369148165, -0.6123855612922828, -0.6508434144341441, -0.6842477855457305, -0.7120677295380842, -0.7338686144860648, -0.7492569059956615, -0.7579009344282894, -0.7595971843718035, -0.7542072381729817, -0.7416851562953478, -0.7220527778241165, -0.6954133562833598, -0.661992655401915, -0.6221384963244513, -0.576269435031473, -0.5249018673315797, -0.4686177218238276, -0.4080382803671126, -0.34384258408228174, -0.27674716489654605, -0.20749517260158487, -0.13688119240799, -0.06572301523178684, 0.005145184354395482, 0.07485979744754345, 0.14258406477298619, 0.20752444483656007, 0.2689679553034332, 0.32622384894718054, 0.3786739985856401, 0.42580141239889596, 0.4672159634655321, 0.5026131093704431, 0.5317844641436494, 0.5546279165679344, 0.5711364255529481, 0.58138746952773, 0.5855521309211857, 0.5838717294550781, 0.576646939558256, 0.5643468587111969, 0.5474169249867294, 0.5262970552332147, 0.5014468947130502, 0.47333118377318706, 0.4424440870227143, 0.4092645553242591, 0.37426212890965593]}}
\ No newline at end of file
1+{"dkt": {"x": [0.0, 0.03, 0.01], "y": [0.0, 0.005, 0.025], "D": 10.0, "nu": 0.3, "Ke": [99406.02555828959, 692.5488717820883, -713.0398000918938, -36670.86471373518, 384.75731089896993, -538.6463817032316, -62735.16084455441, 674.4271620014778, -475.7913680624739, 692.5488717820884, 11.761025240023859, -3.7895479298892223, 168.37642628649147, 4.170287632193504, 1.6536336796122435, -860.9252980685798, 4.749937448064677, -1.4220459418140756, -713.0398000918939, -3.7895479298892223, 10.840958517132316, 620.9273695876681, -1.4471351927083524, 4.599250378723818, 92.1124305042259, -0.17076448794641216, 4.108736496816164, -36670.86471373518, 168.37642628649147, 620.927369587668, 88425.80122352082, 332.56197498173856, 871.2877784879474, -51754.93650978566, 350.8060053588072, 643.0095235321528, 384.7573108989698, 4.170287632193504, -1.4471351927083522, 332.5619749817385, 8.232701300480016, 2.705837322602525, -717.3192858807083, 3.867183339435495, 1.5449642607508982, -538.6463817032317, 1.6536336796122437, 4.599250378723818, 871.2877784879475, 2.7058373226025245, 13.314535668631951, -332.64139678471577, -0.39987497503661085, 4.898433339435494, -62735.1608445544, -860.9252980685798, 92.11243050422591, -51754.93650978565, -717.3192858807083, -332.64139678471577, 114490.09735434003, -1025.233167360285, -167.21815546967892, 674.4271620014778, 4.749937448064677, -0.17076448794641186, 350.80600535880717, 3.867183339435494, -0.39987497503661074, -1025.233167360285, 15.259678369712919, 0.8424879501443864, -475.79136806247385, -1.422045941814075, 4.108736496816164, 643.0095235321528, 1.5449642607508978, 4.898433339435494, -167.218155469679, 0.842487950144387, 8.610934315016134]}, "config": {"material": {"E": 110000000000.0, "nu": 0.34, "rho": 8700.0, "sigma0": 0.9, "sigma1": 0.0005}, "profile": {"radius": 0.2286, "bell_height": 0.013, "bell_top_radius": 0.025, "bell_shoulder_radius": 0.08, "bow_height": 0.03, "bow_power": 1.4, "h_rim": 0.001, "h_shoulder": 0.0017, "h_bell": 0.0026, "max_slope": 0.4}, "imperfections": {"seed": 1, "n_dents": 0, "dent_depth": 0.00025, "dent_sigma": 0.007, "dent_margin": 0.01, "rim_warp": 0.0, "rim_warp_modes": [2, 3, 4, 5], "shoulder_ovality": 0.0, "bell_offset": 0.0}, "mesh": {"element_size": 0.03, "smoothing": 1}, "hits": [{"time": 0.0, "r": 0.13716, "phi": 0.3, "velocity": 8.0, "exciter": {"kind": "mallet", "mass": 0.3, "alpha": 2.5, "compression": 0.012, "radius": 0.012, "gap": 0.0001}}], "listener": {"position": [0.4, 0.3, 0.9], "c_air": 343.0, "rho_air": 1.2, "back_diffraction_gain": 1.0}, "numerics": {"fs": 44100, "duration": 0.02, "cfl_safety": 0.6, "rot_inertia_factor": 0.015625, "inplane_mass_scale": 1.0, "steps_per_block": 500, "dtype": "float64", "nonlinear": true, "n_progress": 4}, "output": {"prefix": "crash", "wav": true, "npz": true, "cascade_plot": true, "record_acceleration": true, "displacement_rate": 0.0}}, "mesh": {"n_nodes": 227, "n_elements": 402, "xy_first5": [[-2.6020852139652106e-18, -1.734723475976807e-18], [0.019117343221916425, 0.024102211562137932], [-0.009359064545977937, 0.02944032505710612], [-0.029750452483819415, 0.008697493319743578], [-0.02387984322191643, -0.01988300473366113]], "xy_last3": [[0.2125469046740543, -0.08415327274371735], [0.22141811063400504, -0.056850508205885934], [0.2267974207204896, -0.028651177192800043]], "tri_first5": [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 6]], "area_sum": 0.1637414776568517, "n_boundary": 50, "min_edge": 0.02033391325139436, "max_edge": 0.04000169788235948}, "shell": {"mass": 1.9867603122224469, "omega_max": 523630.5046043768, "limiting_element": 391, "max_slope": 0.3199066511168112, "h_e_min": 0.0010336844623136114, "h_e_max": 0.0026, "z0_max": 0.043, "z0_node_first5": [0.043, 0.042650943402618983, 0.042635328560266056, 0.04262251986580999, 0.04261272663125421], "Ke0": [1475858.697091178, 16136.614127767534, -3010.9870566465834, -744974.3738707487, 11362.375060718527, -4072.940123810292, -730884.3232204291, 11974.012833670424, -317.6100596991204, 16136.614127767536, 265.4942758428761, -26.24265371303801, -6441.08010017829, 86.62541964662539, 15.420370323525153, -9695.534027589243, 88.56425314813289, -21.572926833518178, -3010.987056646583, -26.242653713038017, 131.55137337915315, 10758.763195909394, -27.574130665448678, 74.29910824383609, -7747.776139262813, 22.60384569332314, 72.3404240116815, -744974.3738707488, -6441.080100178291, 10758.763195909392, 1700430.0901629245, -5372.6916803654785, 16709.037866806622, -955455.7162921759, -1041.4271338764995, 13982.076315404956, 11362.375060718525, 86.6254196466254, -27.574130665448678, -5372.691680365478, 149.38273125836008, -37.40584143249695, -5989.683380353046, 69.8238263400615, 18.326214585559335, -4072.9401238102923, 15.420370323525159, 74.29910824383607, 16709.037866806622, -37.40584143249694, 270.8565206314472, -12636.09774299633, -8.728469549398342, 92.53883731844594, -730884.3232204291, -9695.534027589243, -7747.776139262813, -955455.716292176, -5989.683380353046, -12636.097742996331, 1686340.0395126056, -10932.585699793926, -13664.46625570584, 11974.012833670424, 88.56425314813289, 22.603845693323144, -1041.4271338764997, 69.8238263400615, -8.72846954939834, -10932.585699793926, 188.57149433565115, 68.53407911594813, -317.61005969912173, -21.572926833518192, 72.3404240116815, 13982.076315404956, 18.326214585559327, 92.53883731844597, -13664.46625570584, 68.53407911594815, 230.30751221998605], "D0": 182.17247097844108, "Cm0": [323383084.57711446, 109950248.75621893, 106716417.91044776], "M_first3": [[0.018925757245507557, 0.018925757245507557, 0.018925757245507557, 1.349581375051811e-07, 1.349581375051811e-07], [0.018301177103390947, 0.018301177103390947, 0.018301177103390947, 1.3318962480538492e-07, 1.3318962480538492e-07], [0.0171465332628693, 0.0171465332628693, 0.0171465332628693, 1.1629463074387797e-07, 1.1629463074387797e-07]], "Rm4_first3": [[1.6642438532559925e-10, -0.15126505910989055, 1.1499294116890349e-05, 6.565421629146718, 0.0], [2.290323631435171e-06, -0.1489751718778917, 0.15825268039444734, 6.565421629146718, 0.0], [2.7975434382580364e-06, -0.14886994806718185, 0.19329964619315146, 6.565421629146718, 0.0]], "checks": {"rigid_tilt": 1.1178412285407855e-17, "curvature": 1.0574874309554616e-11, "rigid_ratio": 8.345767362347624e-17}}, "patch": {"nodes": [[40, 64, 65], [64, 96, 65], [65, 98, 66], [40, 65, 41], [40, 65, 41], [40, 64, 65], [40, 64, 65]], "weights": [[0.2252173731126971, 0.07714084870076315, 0.6976417781865398], [0.1061831804671339, 0.17972030988676246, 0.7140965096461036], [0.885284540249201, 0.040491544716748484, 0.07422391503405051], [0.035068991510846984, 0.6020618382743711, 0.36286917021478193], [0.45395423010845526, 0.3747167884065698, 0.17132898148497494], [0.4586678823965067, 0.25090048155400707, 0.29043163604948624], [0.06406325887112681, 0.48346594958593464, 0.4524707915429385]], "offsets": [8.509094170816925e-05, -1.2100312040630445e-05, -1.4522796111370723e-05, -1.533464731140119e-05, -1.3275742822043551e-05, -1.3347365329926392e-05, -1.6510078092817765e-05], "k_total": 177502680.67297047, "free_contact_time": 0.004052173591888192, "max_compression": 0.012000000000000004}, "timestep": {"dt": 2.2675736961451247e-06, "substeps": 10}, "run": {"hits": [{"time": 0.0, "kind": "mallet", "peak_force": 1408.6936215717985, "contact_time": 0.006321995464852607, "rebound_velocity": 4.626189736796063, "energy_in": 9.6, "energy_out": 3.2102447221255845}], "energy_log": [[0.0011337868480725624, 0.16329717688529438, 0.15764703961621906, 0.18473595175549615, 7.054970683789774, 0.8234470224894345], [0.005668934240362812, 2.4008851343329916, 2.0136837079334446, 1.9261672298383783, 3.167625222077137, 22.656185700120297], [0.01020408163265306, 4.635407698689287, 0.804622411252682, 0.8346449017381632, 3.2102447221255845, 9.208001220602256], [0.01473922902494331, 1.519353425145847, 2.382188983592165, 2.2757874155567825, 3.2102447221255845, 15.882210252263013], [0.01927437641723356, 4.325549291650169, 0.4865859400407113, 1.2862981947244616, 3.2102447221255845, 6.534477357990252], [0.02040816326530612, 4.642862914194414, 0.4144282958465078, 1.0110477059039795, 3.2102447221255845, 4.634266324642433]], "pressure_rayleigh": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.864957007685976e-12, 1.4224871935802989e-09, 7.739936481353484e-09, -2.7172940330189813e-08, -7.105816671843467e-09, -3.1180841016679705e-08, -5.7475718537335256e-08, 8.735480505143961e-08, -2.037165517152576e-07, 3.82582078142909e-07, -4.500606007031987e-07, 7.824396487632116e-07, -6.664616119496105e-07, 1.097354183782923e-06, -7.082907600548676e-07, 1.405986926834465e-06, -1.9256225389210849e-07, 9.869638697593504e-05, 0.0004999396075811432, 0.0003631825926885198, -0.001776337325154036, -0.006670483711366612, -0.014506045644569183, -0.02521239945576352, -0.03855711007884904, -0.05417985062123011, -0.07168167518979349, -0.09067829176021656, -0.11077711489419795, -0.131543034037668, -0.15253083180693408, -0.17335777372962885, -0.1936920500054449, -0.21320871608168654, -0.2315847690476343, -0.24855009516870127, -0.2639310268712022, -0.27762503119095994, -0.2895513467898741, -0.2996577062267057, -0.30797542580822623, -0.31460460804382756, -0.31966401217295415, -0.3232771274861402, -0.32557730102140475, -0.3266916006418487, -0.32674993409310266, -0.3258927394041293, -0.3242294345467551, -0.32185823347095954, -0.3189022460312292, -0.31549993458854186, -0.3117683266994248, -0.3077830982769918, -0.30361343658277745, -0.29935478077782096, -0.29510931536386736, -0.2909646556430327, -0.2869953088755106, -0.283279082016505, -0.2798970528428116, -0.2769243856495553, -0.27443615991573617, -0.2725004689078396, -0.2711681568706019, -0.27047464872375915, -0.27044362757281676, -0.2710867274269915, -0.27240875552164046, -0.2744187651501829, -0.2771266858982103, -0.28051138503194994, -0.2845002619767863, -0.28899328464529794, -0.29389017137470896, -0.2990727822954411, -0.30439580547771133, -0.3097040875981831, -0.31485895525839597, -0.31976103091150865, -0.32434250112252844, -0.3285716457862203, -0.33249123803683617, -0.33622664065524194, -0.3399753940405798, -0.34400141384607885, -0.34862084700045065, -0.35417344218924046, -0.36097208333500574, -0.36925701445073905, -0.37917328960001145, -0.3907373753642637, -0.4038155995502918, -0.4181076721224082, -0.43315399183907133, -0.448386544024397, -0.4632097042391442, -0.4770604577390046, -0.48942913214106054, -0.4999008254303464, -0.5082109038950892, -0.5142898727812344, -0.5182436826066619, -0.5203114981474753, -0.5208565927282489, -0.5203659249653112, -0.519415382220154, -0.5185762337013343, -0.5183833067049698, -0.5193416618715015, -0.5218709990909662, -0.5262553264261127, -0.53262110767776, -0.5409611119666887, -0.5511843718389736, -0.5631312081529141, -0.5765901203506839, -0.5913437044853165, -0.6072431982160361, -0.6242551490241074, -0.6424465234590098, -0.661959024020254, -0.6829823045591921, -0.7057426063423353, -0.7304928073210017, -0.757466797066075, -0.7868172903407157, -0.8186095760127674, -0.8528390680122265, -0.88940660113288, -0.928087896133354, -0.9685619613005458, -1.0104699059690216, -1.0534171457311505, -1.0969252266472889, -1.1404695141881167, -1.1835668965051094, -1.225782540912985, -1.2667268534516611, -1.3060479344696203, -1.3434488871031323, -1.3787276687762098, -1.4117520017881675, -1.4424195313471158, -1.470651822196353, -1.4963755935672294, -1.5195194530332239, -1.5400300558285747, -1.557843812151457, -1.572847268231941, -1.584879248003563, -1.593737785434962, -1.599158050174012, -1.600779667590285, -1.5981734189692376, -1.5908983865056316, -1.5784974673230514, -1.5605004132263727, -1.5364808119947873, -1.5061099311739965, -1.4691762323978594, -1.4255616644004236, -1.3752368062933578, -1.3182434163659473, -1.2546763800649265, -1.1846764955016325, -1.1083962906796931, -1.0260100591152852, -0.9377249598719484, -0.8437679436004416, -0.744435325217647, -0.6401345084979836, -0.5314010153328776, -0.4189308197822335, -0.30362680162845274, -0.18663201447216, -0.06928839623447104, 0.046920000968025684, 0.16041354104221167, 0.26958145111064546, 0.3728631232942975, 0.46880601380382997, 0.5561148712257232, 0.6336627047991468, 0.7005044804430265, 0.7559020445613925, 0.7993013821905287, 0.8303064124243476, 0.8486672912056542, 0.8542900461578619, 0.8472228233412786, 0.8276332611014715, 0.7957743435698355, 0.7519467952747096, 0.696461407568667, 0.6296148235557004, 0.5516902601608555, 0.46293733022669475, 0.36356611457879895, 0.2538148638695549, 0.13403086605174205, 0.0047206399826955035, -0.13340456259085934, -0.27938334622497873, -0.4319228983955691, -0.589296814293584, -0.7493140967481418, -0.9092759045012412, -1.0659117970137486, -1.2153613039573, -1.353194365776805, -1.4744896853152232, -1.5739540808336083, -1.6461345226651976, -1.685720637298801, -1.6879071822017873, -1.6488548149854652, -1.566140302095685, -1.4391476727939194, -1.2693412401449389, -1.060304783563807, -0.8174450551085474, -0.547342066007762, -0.256943386285029, 0.04728663883246528, 0.3601999655050138, 0.6784618591833521, 1.0004321508213168, 1.3253993380669218, 1.6522456138429105, 1.9780954051484922, 2.2975738561006738, 2.603155671634926, 2.8868835450355217, 3.1428821193901393, 3.369249106466477, 3.567477024735285, 3.7385564438270413, 3.8773130974455516, 3.968825453251545, 3.9903300011714933, 3.9181014331506065, 3.7354349264279625, 3.438111117616545, 3.036576308237488, 2.555359609332791, 2.02899536085348, 1.4936913995913275, 0.9767871004817028, 0.48920358830563304, 0.025624440632697375, -0.4277649131495429, -0.8831982312858919, -1.3451401396089788, -1.8111036342245166, -2.2774618128597344, -2.7449863495775335, -3.219592308605701, -3.70778853053832, -4.210436594441777, -4.71986344607684, -5.223221401035644, -5.709352686644291, -6.171868035201643, -6.604119806452072, -6.990664166812417, -7.304361820789162, -7.514057282278072, -7.599647134024658, -7.563079791059567, -7.422953461643126, -7.193171623081143, -6.862618165738873, -6.394630115410487, -5.749815877054611, -4.918401900156065, -3.941121904428078, -2.9022921985165997, -1.8923331696565662, -0.9575995205785357, -0.07178659788308456, 0.8455486818187273, 1.8741261011248473, 3.0450614039535218, 4.3355420774490545, 5.698777374433923, 7.0916851004517305, 8.472908556495168, 9.778797804067516, 10.91265236397854, 11.775334058643637, 12.322695434334504, 12.598684078128787, 12.710676837968666, 12.767555258287498, 12.82618367495046, 12.872243326022653, 12.83562976513537, 12.627221391408183, 12.175748832463754, 11.446586458476565, 10.442640783513262, 9.202182452470815, 7.799803834750815, 6.33987141689424, 4.934464421790848, 3.673871972730759, 2.601454142307764, 1.6975074665631635, 0.8781900790163378, 0.01998290364959219, -0.9888609318969835, -2.188102225477437, -3.509981167511128, -4.796753530836327, -5.8694514378661875, -6.60932364073468, -7.0013535712865345, -7.116514353819466, -7.05706451582785, -6.911712766849298, -6.740773670148957, -6.573306401952023, -6.3994493514099915, -6.16745456114833, -5.7969600900676355, -5.204347670173138, -4.335769229461589, -3.2028154550018364, -1.89818078258079, -0.5667491089749496, 0.6589239387539799, 1.715011622451777, 2.615372057722939, 3.41475280008528, 4.16467711413818, 4.897407077637133, 5.636608702923251, 6.403267415180137, 7.194807481520995, 7.954748897699069, 8.573130236227467, 8.93179851369806, 8.963830967048594, 8.686881908775746, 8.196579695550897, 7.628307886660624, 7.102590390535834, 6.67695000965548, 6.332725192555439, 6.008970858736462, 5.65683284290157, 5.263528984516098, 4.8231187576527565, 4.290771887991611, 3.5786436076684693, 2.6095409451618425, 1.3889924886544849, 0.03686372961454763, -1.2512426868430224, -2.2885513200556056, -2.9757477058115733, -3.337516651481377, -3.5064826189302924, -3.66078188143196, -3.943600979498847, -4.410143189533004, -5.027220225846232, -5.705638623579213, -6.32604456182345, -6.745637282991787, -6.813210401955904, -6.422420734121429, -5.588284736220283, -4.487483763599853, -3.4114015362187673, -2.6417780595753957, -2.32032226433445, -2.389867747400374, -2.631576852827606, -2.7651262876970524, -2.5608213609951886, -1.91996272800493, -0.8937193902486947, 0.3593022909514964, 1.6421624853295569, 2.7759484772623746, 3.6304774454172635, 4.142832880768742, 4.338017588163146, 4.342330482617939, 4.361165367471721, 4.606332591324657, 5.196253154873299, 6.084102530299149, 7.065795058347884, 7.873257929773339, 8.30021643379076, 8.289974118338908, 7.948543152264689, 7.4902039964728, 7.1463823209621635, 7.07739638957242, 7.321151120575612, 7.789869592711889, 8.300972268207923, 8.623710655555529, 8.535439677512096, 7.886271168340566, 6.66049284591455, 5.008201571519904, 3.216630323629947, 1.6127741719051247, 0.434232965564575, -0.2613713786945528, -0.5969145023445148, -0.7966795158802278, -1.084548609373438, -1.6097584085083354, -2.413404039593372, -3.4260534121851087, -4.489864781595971, -5.40430290991213, -5.987187886018297, -6.133267109520856, -5.853600731407051, -5.284238115680887, -4.6531240480984914, -4.200223021498405, -4.071663556123111, -4.23996963465077, -4.504707311402984, -4.5866560383842, -4.267487864820643, -3.493167428206745, -2.3844610029153195, -1.163987705051275, -0.05853916650769867, 0.7712831832547418, 1.2599317944626995, 1.434080640228617, 1.391996428310392, 1.278150813646822, 1.2577806734815429, 1.479842996411741, 2.018244405213544, 2.8128929665894638, 3.6605932020428713, 4.2892163431602395, 4.489585305945847, 4.227194297018656, 3.6601762937996596, 3.0515823780396536, 2.6336458619355367, 2.507316568247432, 2.626818832788864, 2.856543011240326, 3.047773132300946, 3.089001766332049, 2.9174383133736383, 2.5115369264810354, 1.8931278554736621, 1.1437297721491035, 0.40625043903158037, -0.15732082753890195, -0.4444409505378957, -0.4813969586318743, -0.43322564834591276, -0.5367740572973385, -0.9879115053560495, -1.8435540950602454, -2.991650501553891, -4.204346411288071, -5.242552680145271, -5.952638724248966, -6.307899204117032, -6.38686919112441, -6.316075988962917, -6.216278593562966, -6.175025140794337, -6.239455276345083, -6.411113676901315, -6.638368429073379, -6.819274380527118, -6.828886501090124, -6.57153158247346, -6.036697172825588, -5.319974500330324, -4.581960507831481, -3.962286244133343, -3.5063640180291573, -3.1563533762700264, -2.807174730441914, -2.3796749534760937, -1.85843881489849, -1.2789388755523574, -0.6902884539485893, -0.13192759945893553, 0.36039112565155706, 0.738653734683433, 0.9474826321941311, 0.957506488479628, 0.8027777414776759, 0.586671796103624, 0.43788561302931883, 0.4348504238024335, 0.5509931139444908, 0.6712098915116903, 0.6788555107501297, 0.5495047151585475, 0.373821971469034, 0.28786001034429587, 0.36682985410354774, 0.5658047500348894, 0.7457744933432944, 0.7556532664323854, 0.5121303652449757, 0.03712305285914667, -0.5572420121054356, -1.1238772218022943, -1.5457784502558836, -1.7714837576775995, -1.8019342953838955, -1.654308188289326, -1.3512958351958975, -0.9529746250804252, -0.5926220235086527, -0.4582923140511314, -0.7046620431651591, -1.3488136766695935, -2.2336460713914517, -3.098951476949469, -3.71818939349838, -4.0120499945336885, -4.072579911481045, -4.093151886400564, -4.252950957088111, -4.625577887933587, -5.160344863329777, -5.731310402979294, -6.204325816312877, -6.475918891452867, -6.4799135986960685, -6.191132707199144, -5.64891408836297, -4.986568761042991, -4.424384588497108, -4.196945853850586, -4.439515662527567, -5.107550543120341, -5.9930565948571, -6.831255269722438, -7.4248821260250475, -7.708801258790748, -7.72860784194115, -7.565736850695759, -7.2683359349846945, -6.830919376098973, -6.22258150343696, -5.427685094469057, -4.463010758177507, -3.365667358608559, -2.1728894277866595, -0.9163761124903943, 0.36137879096554987, 1.5797318354355507, 2.6106708732565176, 3.3194653860139636, 3.6500287469716834, 3.6933076618068816, 3.666482643221596, 3.7953600128886382, 4.1780314261210725, 4.731288892948624, 5.255831034804247, 5.562093269165056, 5.563179671759798, 5.28715309173302, 4.828886286703602, 4.290875353256244, 3.7499569514816726, 3.2582673769628676, 2.858548251541191, 2.5827481766932086, 2.421125533726246, 2.287454372256565, 2.030698881009271, 1.5161615583233972, 0.7282281715808968, -0.19585726676486667, -1.0475547934003113, -1.6901462924281174, -2.1492698099022505, -2.5807286964473644, -3.1514244787158745, -3.9291584582765844, -4.847802793674688, -5.751503458810123, -6.480372423841459, -6.944412737705986, -7.141065430992303, -7.110732759281836, -6.8732362132353515, -6.405796923331603, -5.6887911118954575, -4.779143626591031, -3.830357233159338, -3.017706227260004, -2.4228144398380604, -1.9816584159065707, -1.5456737428010958, -1.003614395793547, -0.3625029867687212, 0.2721534323194341, 0.7940157126960447, 1.1940056745055923, 1.5819891026281798, 2.109451526656467, 2.849469967149818, 3.7287315057914054, 4.564982093702076, 5.179133935023433, 5.494295151134827, 5.548493038868911, 5.42598016710451, 5.185036538221932, 4.85230020448712, 4.472572715865143, 4.141005099272556, 3.966988071162242, 3.9918655850878735, 4.129337508376461, 4.181968945802687, 3.9323692828040544, 3.2590072862668804, 2.2101403967442215, 0.9900763713463945, -0.13502850356942828, -0.9514111958069825, -1.365042866060111, -1.3979039706151157, -1.1383457267253616, -0.6924781893546339, -0.1683416358196741, 0.31507441684677173, 0.6309823246041831, 0.6852983054439756, 0.4737060597200923, 0.10127461205938981, -0.26986151193097274, -0.5227963051215914, -0.6706752491881348, -0.8578765335358532, -1.266388439644519, -1.988962474671162, -2.9583727360919703, -3.9759558165012985, -4.805525090696607, -5.261900054774647, -5.249273196647145, -4.755421354324392, -3.8363530347623636, -2.615639629341322, -1.2877333753660494, -0.09085762122259322, 0.7698616027333717, 1.2230898820968656, 1.3910296565592144, 1.548975879213041, 1.984927902887759, 2.833399491012815, 3.9847196614187967, 5.126580095364503, 5.891318305761251, 6.024679393803493, 5.493961165652231, 4.497159626334934, 3.3848747722484918, 2.5383763761762754, 2.2517149959505134, 2.652285439406509, 3.673431384733992, 5.0705162845121245, 6.466034792817608, 7.428618783121181, 7.599746845906098, 6.842514244607176, 5.331766873227935, 3.508791969399716, 1.901978005478164, 0.902200856250331, 0.610180888417411, 0.8292291574066969, 1.1946995577422101, 1.3608989150380666, 1.1454771766134964, 0.5706330585326272, -0.18914110183846997, -0.8937378601450485, -1.304989998222459, -1.228467428026077, -0.561582293634449, 0.6343878641545759, 2.0835004485061512, 3.348019820080955, 4.008488673295948, 3.877794748822644, 3.1011063861230235, 2.0677757770668252, 1.1996618937990755, 0.7542654391750891, 0.7423757679848169, 0.9708849219785604, 1.1591470657778578, 1.0635194324500756, 0.562058606120284, -0.31960746087742575, -1.4317034776732147, -2.5452649242505143, -3.3958685369414376, -3.7332920891950137, -3.400658205207423, -2.4293624012209323, -1.0798277957825482, 0.23513079566298536, 1.1249355636863279, 1.395881124759673, 1.123757311017509, 0.5872164581421232, 0.106514636216637, -0.11756919018178714, -0.07871463420175195, 0.0719798697079214, 0.13288806549368465, -0.0436519303535185, -0.49963841273236076, -1.175428514119905, -1.9374525394507318, -2.5993134279383625, -2.941087367859239, -2.7602959719125955, -1.9660280745361935, -0.666992951188492, 0.8277193273097122, 2.1317321831016782, 2.9725788712617764, 3.3345844872102304, 3.4608123757763134, 3.711294937267622, 4.361201992106564, 5.449089706194265, 6.749469806098547, 7.875806061764028, 8.452779002173187, 8.26471405849999, 7.313821343888985, 5.788011167402008, 3.9865121676560484, 2.247746073711234, 0.8877270495678934, 0.13237639396550918, 0.0395738754639507, 0.44593815202054693, 0.995680069401332, 1.2762105081062034, 1.01002815655586, 0.1936596459572742, -0.9105639790874942, -1.9320158309397821, -2.599006204789846, -2.870107774591352, -2.927001828272055, -3.055597834108101, -3.4947677736400036, -4.330043741539082, -5.469592581421209], "pressure_unbaffled": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.864957007685976e-12, 1.4201889436356433e-09, 7.3365431139504735e-09, -3.0258375303974346e-08, -1.1180030870753046e-08, -4.0306635634107305e-08, -6.618817077905314e-08, 7.339562355164716e-08, -2.1415615508663449e-07, 3.747447038336681e-07, -4.491000967147785e-07, 8.164863930629004e-07, -6.384281459459999e-07, 1.2241789208577827e-06, -6.447054793864078e-07, 1.6874189948363527e-06, -1.1719756543466181e-07, 9.883805793005384e-05, 0.0004730596775882034, 0.00015095172260865813, -0.002583839793651497, -0.008797866158098187, -0.019029866236698743, -0.033648514693316714, -0.05289274710983981, -0.07687078879868221, -0.10544457914353834, -0.13813257881387428, -0.1742959832100735, -0.21304766439934053, -0.2533373825605386, -0.29382266081770547, -0.3330828047344596, -0.36989879197476755, -0.40316250165147227, -0.43195392885737005, -0.4555209803934867, -0.4733540012715862, -0.4850903797302919, -0.4905269869436585, -0.48964656167388493, -0.4825739836233155, -0.4695538765743478, -0.45090871762133883, -0.4270333988877145, -0.39837513608091707, -0.36543422924744706, -0.3287352828280299, -0.2887988453488817, -0.24619708653988162, -0.201564173648823, -0.15555631951168508, -0.10883732981581537, -0.06203188381010091, -0.01574989493476142, 0.029371823265794128, 0.07269341324206169, 0.11361023972288664, 0.15158072062788908, 0.18611492005661234, 0.21676225145242095, 0.24311160158308082, 0.2648007580165857, 0.28155366942849774, 0.29318469610898035, 0.29958832483179476, 0.30073418348240494, 0.2966840715510796, 0.2875882017920408, 0.2736677936789093, 0.2552266484252136, 0.2326630893709335, 0.20647686700031576, 0.17725099413286133, 0.1456238401990405, 0.11230693478639642, 0.0780811089571935, 0.04376282984606983, 0.010165712696009188, -0.02193936540873659, -0.05184095292843577, -0.07891266466632563, -0.10266685162168315, -0.12280556772585355, -0.1392504758748399, -0.15214071461602022, -0.1618233196512876, -0.16883272815167497, -0.17382580400965061, -0.17748761122606138, -0.18044283174531991, -0.1831616981765992, -0.18586118855245592, -0.188402612086507, -0.19025145597744222, -0.1905145848161171, -0.18802601262807345, -0.18144398279984392, -0.1693379234852826, -0.15034119990322337, -0.12334027058483576, -0.08761913862764392, -0.04291062876404911, 0.010581376952636612, 0.07216805048239117, 0.14069837025166032, 0.21464983616416944, 0.29231370104553545, 0.3719265074243737, 0.45177251100096216, 0.5303417540904614, 0.6064860586862046, 0.6795349820693573, 0.7493310642674792, 0.8161952511919967, 0.8809109549479779, 0.9446589849144981, 1.0088584043396542, 1.0749500706174668, 1.144195960615468, 1.2175597789993131, 1.2956197572202652, 1.3784663785396085, 1.4656256429905774, 1.5560561284449996, 1.648229250908558, 1.7402395842026142, 1.8298950153281586, 1.9148031153310634, 1.992509847292022, 2.0606685296960063, 2.1171346467029633, 2.1600032661770947, 2.1876794052938164, 2.1989912675663215, 2.1932002323444477, 2.169907141306621, 2.1290441459999094, 2.0708818652064895, 1.996014598407068, 1.905302072064007, 1.7997830364018277, 1.6806463332831247, 1.5491907677511456, 1.4067353605597832, 1.2545243765258929, 1.0936370754101385, 0.9249091366629976, 0.7489071927493096, 0.5659687205541912, 0.37627129233828294, 0.17992590840433853, -0.02285194968298132, -0.23154386349060774, -0.4451905768346476, -0.6622805403205828, -0.8806460808811514, -1.0974468746788806, -1.3092970025854807, -1.5124744607369696, -1.7031493713691694, -1.8775993356385, -2.032439445339188, -2.164780251031435, -2.2723018969655397, -2.3532764780565687, -2.406489129580055, -2.4311624136026344, -2.426886832713124, -2.3935142967332403, -2.331159874520371, -2.2402227605944893, -2.121433886006133, -1.9759121472172232, -1.805214264513868, -1.61137918356815, -1.3968809475602744, -1.1645548793903464, -0.917504776471231, -0.6590102171198501, -0.39241330332697966, -0.12104294836553936, 0.15183075283077707, 0.42304408445952346, 0.6895723096274313, 0.9485715264185482, 1.1973726693503568, 1.4334788865393904, 1.6545628411827193, 1.858446908381941, 2.043032816474269, 2.206211993451297, 2.3457741247541826, 2.45931977251192, 2.5441806166992675, 2.5974017335400967, 2.6157901824467356, 2.5959606590370927, 2.5344124279587703, 2.427687107752128, 2.272535156273685, 2.0659945913540776, 1.8054526980560306, 1.4887178301345592, 1.1140980316875608, 0.6805011484342377, 0.18753391160417698, -0.3643243171788477, -0.9734530224999468, -1.6367774055665691, -2.349452209276044, -3.1045263640630605, -3.8925909699396, -4.701558593414294, -5.516609725219237, -6.320335542906101, -7.09316749513235, -7.814060454709087, -8.461446944115384, -9.014379047038773, -9.453700705276354, -9.763027239853924, -9.929420123014804, -9.943835427465308, -9.8013564840092, -9.501122757139541, -9.046159896225754, -8.443331361161487, -7.703329352725997, -6.840641596878965, -5.873064939498652, -4.82038563693469, -3.7020621845831614, -2.5338048776114412, -1.3236085735966596, -0.06859955817161145, 1.245180633896993, 2.6381737947642385, 4.1277646387104605, 5.716336019104988, 7.381168854505733, 9.069908786058175, 10.704187564194466, 12.192699439104167, 13.452094789249859, 14.42873497323746, 15.110166387280694, 15.518574668409608, 15.689150098463172, 15.646873059545012, 15.39713244211924, 14.935909677210674, 14.271424576692212, 13.441374283197279, 12.512649722573688, 11.561584305603683, 10.644788151656476, 9.776065544261511, 8.919816353069438, 7.999619150921918, 6.913042991107485, 5.549865056927208, 3.824290924132036, 1.7244465483189275, -0.6538014344523457, -3.1347189933201443, -5.5447097815134345, -7.78295771774778, -9.83309244921536, -11.725858536890843, -13.487609175247957, -15.10225272140878, -16.50395598514104, -17.606119550742317, -18.353886155853832, -18.770514799188234, -18.96491149838672, -19.08632393101361, -19.245703229092722, -19.449608853900862, -19.590791180888328, -19.505460094447063, -19.06089547380294, -18.21311111000735, -16.99748647676787, -15.471543800523168, -13.666041793088755, -11.585649211139343, -9.248937851874171, -6.715958618368434, -4.064036339106888, -1.331085225225035, 1.5133044216871046, 4.535229343253675, 7.7680461864225165, 11.158765249356453, 14.560357164515246, 17.771631443331245, 20.60059818122175, 22.91165727058697, 24.63137597949209, 25.72533129262548, 26.18132073640412, 26.016203409174167, 25.29194438958011, 24.117984080014757, 22.627999178091294, 20.933914228995235, 19.079008426005874, 17.024950604920395, 14.689532578351773, 12.014473823787451, 9.023489242687274, 5.838276377404771, 2.643006330290066, -0.38355283868273116, -3.129029301657356, -5.566500146461217, -7.727132909900548, -9.658244845597169, -11.404156402924027, -13.010688081091526, -14.522832260159591, -15.963167568051945, -17.311467511799083, -18.49949185003512, -19.41654910491202, -19.93308081881162, -19.95059663759934, -19.44973057671073, -18.494661994146252, -17.193899826510183, -15.656444147743445, -13.969925371089325, -12.191562468494716, -10.332787055494812, -8.340880629159052, -6.106408663077016, -3.5220759697851545, -0.5784844292737814, 2.5673565826012537, 5.6160716891723155, 8.237722914629938, 10.195158932689496, 11.408859912635414, 11.950314330276141, 11.986488444065657, 11.706306536225082, 11.266503533952811, 10.782706241576221, 10.3513584965117, 10.057496662822036, 9.93933992484229, 9.931748737436127, 9.848704591770424, 9.446802553846785, 8.546886119699353, 7.138388224684452, 5.395326812610342, 3.5943399438141896, 1.9946410339607081, 0.7486723537471631, -0.13232763716610885, -0.7621892725501493, -1.3195929044249426, -1.9686833438122526, -2.8046774769578136, -3.8417286206727006, -5.016713649534193, -6.184612665656578, -7.1232955529252155, -7.588743524181249, -7.428718463783602, -6.699501759656759, -5.699030790143579, -4.86749163430141, -4.59310001404497, -5.031659103653806, -6.040880315086547, -7.250312225121065, -8.213939439938443, -8.575858206925577, -8.189164980533334, -7.1422412857253255, -5.689078400316168, -4.134939597614447, -2.7395896155882267, -1.6633623189107074, -0.9446163376756225, -0.4931046016440961, -0.10542774345942973, 0.477419178941922, 1.469565490670313, 2.9329600483056995, 4.720114672608181, 6.509980396724815, 7.932359169239486, 8.722451965168261, 8.83081881041803, 8.443100848570962, 7.905354140247199, 7.584982271843509, 7.724496611601859, 8.351559555174218, 9.278246395875795, 10.17425961821614, 10.674319225467087, 10.48919066196481, 9.501605157104459, 7.824383133068878, 5.792449884024792, 3.8713428171852966, 2.49805774489222, 1.9131062452699146, 2.0641814817908357, 2.6313393955526867, 3.1547075517802927, 3.1957693180566453, 2.4680996436529505, 0.9092245746181793, -1.3123972958142311, -3.8560041608367506, -6.318706974848332, -8.358136123210313, -9.783256954743141, -10.592649484673874, -10.960669505094208, -11.172136658203694, -11.509178278108907, -12.1209927080079, -12.937440301503301, -13.682999649099198, -13.999024550662913, -13.615480514825423, -12.47668059712246, -10.7551510664373, -8.764766702397017, -6.839663366353123, -5.2368364718984495, -4.0836505063112725, -3.370024501532449, -2.971365016183835, -2.679455324268274, -2.236861100313925, -1.3985882449120586, -0.029337385372563585, 1.808984509553313, 3.849707579358987, 5.725441833008228, 7.141578779174514, 8.02104569210773, 8.53032316585125, 8.974491050945579, 9.635619248656807, 10.650596649438103, 11.97539002388507, 13.421372115915602, 14.725700690997312, 15.624606876846062, 15.912399387535439, 15.48739626181355, 14.39501169856655, 12.853726077952034, 11.220461420795555, 9.875253014539052, 9.06726026536657, 8.799536791511327, 8.814253117621679, 8.692015279321945, 8.02362869894999, 6.577090943284157, 4.387597140493962, 1.7386081557161592, -0.9482417889913384, -3.262766744734792, -4.93707069732174, -5.914160686725401, -6.339449955096615, -6.4933773434469, -6.698694189388161, -7.225184839889512, -8.205438170468563, -9.58415458041347, -11.127455888709097, -12.501031351923267, -13.397704203663391, -13.665139980982467, -13.366803574756297, -12.735335311118945, -12.04597300891671, -11.489922004115417, -11.115026617040815, -10.843367461056992, -10.528376061248526, -10.009872898175908, -9.152673499967165, -7.879348190394417, -6.2073835975617735, -4.280124228680828, -2.36162324857585, -0.7703534684835472, 0.2389832501340574, 0.5943593795717441, 0.45810264250682486, 0.17051333737393076, 0.10706206321077216, 0.5279831801832987, 1.5030977734934592, 2.939055115020405, 4.66505414937945, 6.50349886193239, 8.28722605360385, 9.849610851922092, 11.039650704644586, 11.773446567150355, 12.080284954556356, 12.099869759909838, 12.026873457927906, 12.029369099591177, 12.174615194760678, 12.395403727943854, 12.521640428438769, 12.36947660031512, 11.837402410751753, 10.948485080109409, 9.818583468070564, 8.586723431115896, 7.366693531977171, 6.249161974311475, 5.326499550371112, 4.685446492163269, 4.351227114852548, 4.230617144125743, 4.116381922188619, 3.769135365397773, 3.037508731007465, 1.95072453431529, 0.7234835578350163, -0.34210856973227344, -1.0039536900911878, -1.1889662078915633, -1.011648204530771, -0.7146258271110089, -0.5782339451546141, -0.842063258284905, -1.6577738321670363, -3.06565456903229, -4.978277563427801, -7.177492210887257, -9.357737421660445, -11.229397950592258, -12.63781695792579, -13.623793329139517, -14.385032866060769, -15.159074573277366, -16.088844769195713, -17.13755470047915, -18.093566125787856, -18.657703875383234, -18.563182690756022, -17.67179359077749, -16.016603393384752, -13.79196665302011, -11.306036313733685, -8.911194378026371, -6.92254037402901, -5.5305895017137745, -4.720178752271037, -4.230374777497573, -3.6074539595751545, -2.3717571251420737, -0.2397402628262011, 2.7216233957975593, 6.1114428796046845, 9.381535713379805, 12.081964226143661, 14.029655790084806, 15.33382714545882, 16.29835347781946, 17.2643672757236, 18.462347160070724, 19.92682685352876, 21.48933047403605, 22.828425528954227, 23.548055633384106, 23.273948252693707, 21.772108599510528, 19.070767388820073, 15.519627265544376, 11.711536668157427, 8.263123844807879, 5.557666696742463, 3.5988267276364105, 2.054931240135905, 0.44893983829329276, -1.6205142570646265, -4.325020668163075, -7.5657425332664, -11.041063049789386, -14.371181968059643, -17.21317012451962, -19.33039350664128, -20.621776154976907, -21.132761988515625, -21.057765430634714, -20.714316336241993, -20.450266124627266, -20.484438887284774, -20.765646568131842, -20.964064098198982, -20.625924851157716, -19.40152316796498, -17.20835864371601, -14.245438389308783, -10.873030201633492, -7.4454556945161565, -4.198712616670322, -1.2405174753330157, 1.3952575657213668, 3.7044894619918676, 5.713014356632886, 7.4943527170212505, 9.155550102689778, 10.769631861514473, 12.29442354088389, 13.558032167470401, 14.35133263925654, 14.5707962359899, 14.30445329406914, 13.801985991393813, 13.356425901990479, 13.171342494739537, 13.279404038608563, 13.543122707952072, 13.728751163932259, 13.610212479541222, 13.048990546249009, 12.023396669416119, 10.62158232889171, 9.022509685905991, 7.469489345991959, 6.225245744232709, 5.499283476493974, 5.359519199259401, 5.670466249517225, 6.107515800228494, 6.263017308458171, 5.8012763558128135, 4.579619222822763, 2.670695286492049, 0.287207094581425, -2.3274449160938735, -4.970063873007043, -7.4878703700862745, -9.764249193644815, -11.723985728578532, -13.357740534269173, -14.72635949653684, -15.916350595256745, -16.965128034977056, -17.81010064370237, -18.30650009890505, -18.311442974638666, -17.782284180344522, -16.825548304919288, -15.664164883420941, -14.53807965506321, -13.592895748790875, -12.822999091835763, -12.10076804699247, -11.26129184107996, -10.17662973483475, -8.775930269706064, -7.02204772987062, -4.885148850366714, -2.340054332535721, 0.6138928255155758, 3.927556437918315, 7.488734101320593, 11.12869395199811, 14.647378970237606, 17.848746884756398, 20.5644360857973, 22.644281944814217, 23.930200329926407, 24.266681686086148, 23.571716887407074, 21.918060880972817, 19.547356129236878, 16.791778395233795, 13.94982781297186, 11.191486641759909, 8.543708856786294, 5.9526724695217546, 3.368931256702396, 0.7928929608208833, -1.739327322373848, -4.195558617607846, -6.563375751114683, -8.822814492097498, -10.901709533180648, -12.6654253896127, -13.972928914822617, -14.764046537287527, -15.092814070221303, -15.064147413575594, -14.729770561491723, -14.043420608985814, -12.917702508839291, -11.328954109271656, -9.379392129648643, -7.272174533562452, -5.227298702469552, -3.400628851726009, -1.851702332080853, -0.5670927538721985, 0.4854657972086115, 1.3092250761851612, 1.8700903283210768, 2.1382456247914408, 2.143662744787769, 1.9821673255595944, 1.7531770982426487, 1.4881928739654113, 1.1441039842755172, 0.6689453201433159, 0.07987157359301511, -0.5124168929176383, -0.9520763075578483, -1.1239302751671805, -1.0150099475413177, -0.7098736782570929, -0.32805792207782664, 0.04699482167361127, 0.3975474479115847, 0.7464289999306049, 1.105224409750861, 1.4416445749297926, 1.6952991456981055, 1.8255846204680295, 1.8402807057470354, 1.7734693300661195, 1.6404219247053344, 1.4277882314388284, 1.143087317064078, 0.8825287509095876, 0.8443735745373226, 1.2510672513052352, 2.2207181496552386, 3.6741895502207678, 5.337711024042642, 6.83965560397015, 7.856835492821636, 8.24748352950881, 8.107389314217956, 7.717749350367758, 7.4155649651458155, 7.461326910303686, 7.965901365417263, 8.887174224275894, 10.063764741057929, 11.248243645986511, 12.136071849764791, 12.422013892508147, 11.901066070642235, 10.568246005871305, 8.633085210410615, 6.4088213566848555, 4.133262320010704, 1.839661762144066, -0.6354246674346533, -3.515272631954445, -6.905091659080624, -10.674430344418477, -14.455036558892385, -17.74587829394475], "fs": 44100, "acceleration_nodes": [0, 50, 120], "acceleration": [[0.0004886548267677426, -0.00013149736332707107, 0.0407407283782959, 0.22140520811080933, 0.6068167090415955, 1.2373335361480713, 2.149203062057495, 3.367065906524658, 4.896137237548828, 6.714727401733398, 8.856837272644043, 11.248292922973633, 13.93703556060791, 16.84406280517578, 19.97190284729004, 23.29538345336914, 26.844892501831055, 30.552736282348633, 34.46366882324219, 38.502620697021484, 42.653892517089844, 46.90629196166992, 51.16707992553711, 55.42264175415039, 59.66634750366211, 63.79960632324219, 67.81583404541016, 71.60871887207031, 75.27910614013672, 78.50220489501953, 81.48623657226562, 83.99956512451172, 86.14461517333984, 87.91350555419922, 89.17379760742188, 90.0323486328125, 90.60301208496094, 90.74420928955078, 90.70276641845703, 90.33379364013672, 89.896240234375, 89.38263702392578, 88.78160858154297, 88.37352752685547, 88.15674591064453, 88.2781753540039, 88.7342300415039, 89.51399993896484, 90.9157485961914, 92.91678619384766, 95.47439575195312, 98.68276977539062, 102.76556396484375, 107.41162109375, 112.73294830322266, 119.0634994506836, 125.9742202758789, 133.63748168945312, 142.22470092773438, 151.357421875, 161.17706298828125, 171.47409057617188, 182.30923461914062, 193.27537536621094, 204.3165283203125, 215.47410583496094, 226.18402099609375, 236.6522979736328, 246.50814819335938, 255.60516357421875, 263.9377136230469, 271.2222900390625, 277.77764892578125, 283.3702392578125, 288.3716735839844, 292.6327819824219, 296.59881591796875, 300.3644104003906, 303.9371643066406, 307.2981262207031, 310.4302062988281, 313.1714782714844, 315.072021484375, 316.01165771484375, 315.58837890625, 313.65301513671875, 309.8836975097656, 304.3907775878906, 297.3275451660156, 288.9261169433594, 279.36279296875, 269.1493225097656, 258.4661560058594, 247.93617248535156, 237.86769104003906, 228.3988494873047, 219.69549560546875, 212.190673828125, 205.5400390625, 199.50096130371094, 194.09730529785156, 188.79295349121094, 183.04275512695312, 176.64564514160156, 169.09764099121094, 160.62081909179688, 151.14654541015625, 140.97451782226562, 130.8704071044922, 121.04141235351562, 112.19670867919922, 104.97191619873047, 99.7295150756836, 96.55734252929688, 95.57489776611328, 96.58094024658203, 99.23757934570312, 103.05680084228516, 107.4911117553711, 111.80146789550781, 115.20112609863281, 116.82377624511719, 116.08509063720703, 112.5006103515625, 105.80203247070312, 96.0546646118164, 84.00532531738281, 69.91370391845703, 54.68535614013672, 39.06890869140625, 23.37810516357422, 7.870761394500732, -7.93543815612793, -24.351024627685547, -41.752079010009766, -60.869239807128906, -81.88562774658203, -105.7901840209961, -132.37939453125, -161.43324279785156, -193.62896728515625, -228.1389923095703, -264.50543212890625, -301.8463134765625, -339.1673583984375, -375.9035949707031, -410.1273193359375, -441.35150146484375, -468.954833984375, -492.01904296875, -511.10107421875, -526.4083251953125, -539.0662231445312, -549.6083984375, -559.7005615234375, -569.2352294921875, -579.3589477539062, -589.4011840820312, -599.2916259765625, -608.0990600585938, -615.2883911132812, -619.1939086914062, -619.3702392578125, -615.05224609375, -604.8997802734375, -588.8446044921875, -567.123779296875, -540.223876953125, -508.9389953613281, -474.61773681640625, -439.3596496582031, -405.3616943359375, -373.90887451171875, -347.0606384277344, -325.9042663574219, -310.6383361816406, -301.6698913574219, -298.25726318359375, -299.5970458984375, -304.5348815917969, -311.7232666015625, -320.5085144042969, -330.40728759765625, -340.65228271484375, -351.52386474609375, -362.8426818847656, -374.6775207519531, -387.3981628417969, -400.7610778808594, -414.59271240234375, -428.1007995605469, -440.6622314453125, -450.2330322265625, -455.6725769042969, -454.8341979980469, -445.5118713378906, -425.9705810546875, -394.8982849121094, -351.57794189453125, -297.28948974609375, -232.69921875, -159.58685302734375, -82.00090789794922, -1.2817362546920776, 79.3797607421875, 159.65403747558594, 239.51022338867188, 319.9906005859375, 401.5708923339844, 485.36883544921875, 570.8408813476562, 657.2865600585938, 741.2294311523438, 819.1077880859375, 885.8934936523438, 939.0918579101562, 981.1112060546875, 1013.6815795898438, 1042.06787109375, 1076.075439453125, 1122.1107177734375, 1183.03173828125, 1257.875, 1341.655517578125, 1423.8057861328125, 1496.76171875, 1554.6082763671875, 1600.2952880859375, 1639.614990234375, 1678.962646484375, 1721.4139404296875, 1760.3814697265625, 1782.33984375, 1774.2091064453125, 1724.052001953125, 1631.99169921875, 1513.442626953125, 1389.815185546875, 1287.0389404296875, 1224.42919921875, 1200.6973876953125, 1203.2020263671875, 1199.1201171875, 1159.6361083984375, 1060.9892578125, 897.0004272460938, 679.5586547851562, 427.0540771484375, 155.95358276367188, -130.95591735839844, -442.3665771484375, -792.5679321289062, -1176.4635009765625, -1567.312255859375, -1919.205078125, -2188.466796875, -2347.05224609375, -2397.919189453125, -2374.9638671875, -2331.539306640625, -2320.972900390625, -2376.630615234375, -2496.924072265625, -2646.192626953125, -2768.05224609375, -2804.47265625, -2715.97021484375, -2502.544189453125, -2203.52880859375, -1893.9271240234375, -1647.9739990234375, -1510.892578125, -1490.5966796875, -1523.3409423828125, -1523.155029296875, -1390.6143798828125, -1070.34912109375, -564.7540893554688, 51.7779541015625, 670.3196411132812, 1169.3575439453125, 1457.353759765625, 1517.29296875, 1395.9390869140625, 1204.122802734375, 1072.1571044921875, 1103.1907958984375, 1333.9654541015625, 1707.0958251953125, 2087.31103515625, 2316.691162109375, 2254.1455078125, 1859.1375732421875, 1208.443603515625, 465.5884094238281, -171.81040954589844, -557.3665161132812, -654.3944702148438, -558.0892333984375, -444.55078125, -516.3609008789062, -900.6063842773438, -1601.767333984375, -2482.967041015625, -3303.06884765625, -3796.4794921875, -3769.190185546875, -3175.15625, -2136.273193359375, -916.0177001953125, 169.46343994140625, 865.1509399414062, 1043.72802734375, 771.2467041015625, 240.24942016601562, -289.0227355957031, -611.301025390625, -649.9263305664062, -479.4981994628906, -290.9169921875, -302.89581298828125, -661.9470825195312, -1357.6168212890625, -2205.862548828125, -2900.584228515625, -3111.14794921875, -2613.736083984375, -1391.2501220703125, 336.32080078125, 2164.9189453125, 3640.927734375, 4414.7080078125, 4365.0380859375, 3638.9638671875, 2588.900634765625, 1631.693115234375, 1089.9296875, 1084.24462890625, 1496.613525390625, 2044.2186279296875, 2401.0400390625, 2344.6845703125, 1852.3719482421875, 1113.689208984375, 462.4859924316406, 233.2947540283203, 619.5477905273438, 1564.297607421875, 2767.5791015625, 3779.716064453125, 4170.68310546875, 3697.36572265625, 2402.851806640625, 605.4533081054688, -1219.9832763671875, -2613.513671875, -3291.27294921875, -3229.287353515625, -2653.25244140625, -1926.342529296875, -1408.05517578125, -1314.833984375, -1644.794677734375, -2190.958984375, -2637.697509765625, -2702.614501953125, -2265.809326171875, -1439.3380126953125, -539.859375, 30.720338821411133, -54.4587516784668, -903.8648681640625, -2338.124267578125, -3944.328857421875, -5216.64208984375, -5735.5185546875, -5322.48779296875, -4092.954833984375, -2406.26708984375, -735.0150756835938, 505.2071228027344, 1091.064208984375, 1054.01953125, 644.1608276367188, 215.7724609375, 75.93345642089844, 358.3236999511719, 969.312255859375, 1632.98388671875, 2008.6708984375, 1851.5555419921875, 1127.6646728515625, 52.78118133544922, -979.5720825195312, -1554.15478515625, -1396.9620361328125, -496.7936096191406, 883.1296997070312, 2283.903564453125, 3210.953369140625, 3307.771240234375, 2487.60693359375, 970.128173828125, -790.0398559570312, -2258.915283203125, -3006.6494140625, -2855.577392578125, -1934.725341796875, -621.7293701171875, 603.288330078125, 1351.9512939453125, 1465.27685546875, 1059.4775390625, 451.6275939941406, 6.3354082107543945, -22.532169342041016, 402.9012145996094, 1094.950927734375, 1719.3245849609375, 1930.8302001953125, 1516.0133056640625, 490.4237976074219, -891.739013671875, -2211.50341796875, -3021.186767578125, -3017.070068359375, -2158.41796875, -705.0401611328125, 862.8784790039062, 2011.738037109375, 2357.159423828125, 1807.7076416015625, 598.6199951171875, -797.3411254882812, -1859.8289794921875, -2207.888427734375, -1734.58544921875, -630.504638671875, 703.0234985351562, 1818.1058349609375, 2387.634765625, 2317.006103515625, 1784.5213623046875, 1152.1480712890625, 827.5982666015625, 1085.34521484375, 1936.9864501953125, 3105.076904296875, 4115.1220703125, 4479.9150390625, 3899.831787109375, 2408.5849609375, 381.2461242675781, -1591.3070068359375, -2915.020263671875, -3205.3349609375, -2429.14794921875, -904.7682495117188, 812.6758422851562, 2133.684326171875, 2640.213134765625, 2230.673583984375, 1134.6348876953125, -182.85276794433594, -1207.5556640625, -1580.1689453125, -1233.743408203125, -418.73004150390625, 407.1639404296875, 770.761962890625, 390.12042236328125, -685.0908813476562, -2089.888671875, -3277.029052734375, -3734.0205078125, -3191.255126953125, -1731.947265625, 229.3806915283203, 2078.98193359375, 3216.514892578125, 3258.52294921875, 2173.6953125, 297.88726806640625, -1778.83544921875, -3413.862060546875, -4134.5029296875, -3791.158203125, -2602.89697265625, -1059.3402099609375, 279.01141357421875, 996.7908325195312, 982.8366088867188, 447.3516540527344, -184.74530029296875, -474.9302062988281, -156.6373291015625, 756.5104370117188, 1970.9930419921875, 3036.233642578125, 3514.684814453125, 3161.1181640625, 2031.8226318359375, 480.6268005371094, -946.7965698242188, -1708.8209228515625, -1462.03564453125, -202.16041564941406, 1721.601318359375, 3713.44091796875, 5157.01513671875, 5622.3076171875, 5020.7158203125, 3607.060791015625, 1871.0079345703125, 336.3086853027344, -621.9144287109375, -888.858642578125, -611.9176635742188, -115.55443572998047, 258.7685241699219, 288.30804443359375, -35.85421371459961, -499.4434509277344, -768.0789184570312, -528.8629150390625, 358.0486755371094, 1766.3040771484375, 3317.2744140625, 4502.708984375, 4865.14697265625, 4164.59033203125, 2459.698974609375, 92.4573974609375, -2427.298583984375, -4585.31201171875, -6004.63330078125, -6532.11865234375, -6246.32177734375, -5388.73828125, -4256.33740234375, -3091.80078125, -2005.3035888671875, -977.8575439453125, 90.6236572265625, 1269.9351806640625, 2507.957763671875, 3598.002685546875, 4223.8994140625, 4083.193115234375, 3031.5703125, 1178.0091552734375, -1124.305908203125, -3370.42431640625, -5059.7041015625, -5849.45849609375, -5639.421875, -4573.1689453125, -2970.64453125, -1206.965576171875, 407.6117858886719, 1706.443359375, 2692.9169921875, 3491.54443359375, 4251.43505859375, 5040.18603515625, 5774.0107421875, 6222.12548828125, 6092.7001953125, 5167.01025390625, 3429.679443359375, 1132.0648193359375, -1251.1661376953125, -3172.07275390625, -4179.01513671875, -4077.60400390625, -2983.035400390625, -1278.3681640625, 509.1638488769531, 1876.7078857421875, 2497.27978515625, 2307.590087890625, 1503.2574462890625, 448.4341735839844, -473.46063232421875, -1008.1451416015625, -1123.3563232421875, -995.17236328125, -905.5796508789062, -1095.531982421875, -1626.5235595703125, -2335.4130859375, -2892.402587890625, -2944.810546875, -2279.362060546875, -935.7296142578125, 783.3550415039062, 2392.34814453125, 3387.48876953125, 3416.4833984375, 2410.103271484375, 626.6546630859375, -1416.106689453125, -3093.817138671875, -3886.59375, -3555.58447265625, -2231.493896484375, -370.4250793457031, 1413.919921875, 2579.2666015625, 2841.411376953125, 2257.2177734375, 1168.7911376953125, 37.257232666015625, -748.6631469726562, -1024.5416259765625, -893.4281616210938, -665.7588500976562, -707.593505859375, -1262.44189453125, -2311.970947265625, -3538.04931640625, -4396.3349609375, -4306.0771484375, -2891.132568359375, -166.55738830566406, 3400.409423828125, 6994.67578125, 9697.8818359375, 10794.00390625, 9999.1259765625, 7550.63427734375, 4096.27099609375, 472.0940246582031, -2568.316650390625, -4555.8056640625, -5402.11279296875, -5346.9599609375, -4811.39892578125, -4196.8310546875, -3711.982421875, -3295.382568359375, -2667.296630859375, -1493.4010009765625, 396.9219055175781, 2846.09033203125, 5337.3154296875, 7119.1337890625, 7453.8251953125, 5904.90771484375, 2535.31298828125, -2069.7373046875, -6950.87109375, -11052.0224609375, -13518.9296875, -13928.4013671875, -12377.3125, -9406.115234375, -5801.73046875, -2329.48828125, 489.3265686035156, 2497.196044921875, 3862.005615234375, 4902.83447265625, 5866.0478515625, 6762.09716796875, 7318.724609375, 7102.7607421875, 5731.64306640625, 3105.02880859375, -464.974609375, -4289.73779296875, -7488.83642578125, -9253.078125, -9107.09375, -7059.8369140625, -3606.99951171875, 418.8547058105469, 4090.378662109375, 6657.333984375, 7742.88134765625, 7413.89208984375, 6093.0625, 4352.67724609375, 2689.391357421875, 1349.0933837890625, 296.42913818359375, -691.0894775390625, -1834.751953125, -3184.266845703125, -4533.40283203125, -5473.49853515625, -5548.345703125, -4464.72705078125, -2244.45654296875, 721.2177734375, 3757.146484375, 6086.58642578125, 7071.07568359375, 6418.0947265625, 4288.013671875, 1255.011474609375, -1873.2642822265625, -4312.119140625, -5548.69287109375, -5474.30126953125, -4377.4609375, -2777.205810546875, -1196.6837158203125, 36.58488082885742, 876.7765502929688, 1511.546630859375, 2209.434814453125, 3136.957275390625, 4233.94482421875, 5197.30908203125, 5580.8642578125, 4970.90673828125, 3171.032958984375, 346.41265869140625, -2958.1005859375, -5937.0205078125, -7761.05126953125, -7850.2646484375, -6092.76904296875, -2906.64306640625, 880.6314697265625, 4296.4453125, 6544.40869140625, 7231.60546875, 6455.2373046875, 4697.21240234375, 2606.837646484375, 749.7689208984375, -575.6755981445312, -1389.9852294921875, -1954.39306640625, -2599.76171875, -3521.784912109375, -4636.67578125, -5556.56591796875, -5727.44970703125, -4661.72705078125, -2190.04541015625, 1386.5135498046875, 5303.41552734375, 8538.1015625, 10133.0693359375, 9519.970703125, 6722.5859375, 2359.025390625, -2552.100830078125, -6900.21728515625, -9807.3544921875, -10856.56640625, -10162.423828125, -8266.2314453125, -5911.5224609375, -3750.928955078125, -2121.761474609375, -967.0537109375, 65.17801666259766, 1391.5987548828125, 3227.850830078125, 5407.79296875, 7387.72265625, 8424.7001953125, 7884.36669921875, 5537.7060546875, 1710.7587890625, -2754.616943359375, -6745.33984375, -9224.8447265625, -9572.1884765625, -7781.1533203125, -4457.87451171875, -617.04736328125, 2656.180908203125, 4560.845703125, 4833.0810546875, 3772.654052734375, 2080.22216796875, 551.9348754882812, -245.25270080566406, -170.03976440429688, 480.3011169433594, 1150.1700439453125, 1302.35302734375, 676.6812133789062, -571.7677001953125, -1927.76123046875, -2723.187744140625, -2416.100341796875, -837.6094360351562, 1699.1519775390625, 4465.8125, 6542.12890625, 7130.22998046875, 5851.4169921875, 2898.718505859375, -992.2174072265625, -4785.2783203125, -7476.77978515625, -8430.458984375, -7557.22265625, -5312.81494140625, -2486.54541015625, 93.71648406982422, 1854.7652587890625, 2642.752197265625, 2703.734619140625, 2510.656982421875, 2507.911865234375, 2892.546142578125, 3517.089111328125, 3938.244873046875, 3605.085693359375, 2121.947265625, -518.6810913085938, -3846.5107421875, -7005.03076171875, -9017.6328125, -9131.84375, -7105.52880859375, -3317.60400390625, 1332.7847900390625, 5716.14697265625, 8831.978515625, 10104.123046875, 9514.0283203125, 7530.02587890625, 4887.50341796875, 2313.5927734375, 299.7771301269531, -1004.7820434570312, -1764.3004150390625, -2297.935791015625, -2868.993408203125, -3512.350830078125, -3981.172119140625, -3837.993408203125, -2667.310302734375, -315.54522705078125, 2950.590576171875, 6443.88623046875, 9234.1552734375, 10445.8544921875, 9562.5107421875, 6622.59228515625, 2218.358154296875, -2679.244384765625, -7015.427734375, -9956.24609375, -11108.85546875, -10584.646484375, -8900.48046875, -6744.7802734375, -4706.1328125, -3076.125244140625, -1789.9287109375, -531.2720947265625, 1034.897216796875, 3027.272705078125, 5207.46240234375, 7021.626953125, 7795.9296875, 7023.27685546875, 4612.04833984375, 985.3843383789062, -3020.7353515625, -6390.47265625, -8243.505859375, -8102.126953125, -6035.2177734375, -2645.83056640625, 1122.3665771484375, 4277.4208984375, 6080.142578125, 6265.20849609375, 5093.1748046875, 3211.011474609375, 1377.8321533203125, 162.7469024658203], [-2.326927824469749e-05, 1.8048658603220247e-05, -0.0006885756738483906, -0.004222987685352564, -0.011357531882822514, -0.029305266216397285, -0.055534958839416504, -0.09376639127731323, -0.145790696144104, -0.21290598809719086, -0.29593250155448914, -0.4214816987514496, -0.5421730279922485, -0.7159668803215027, -0.9157422184944153, -1.1895514726638794, -1.4420809745788574, -1.836837887763977, -2.270862102508545, -2.73988676071167, -3.3937997817993164, -4.174905300140381, -5.090822696685791, -6.238437652587891, -7.540770530700684, -9.198102951049805, -11.032724380493164, -13.257007598876953, -15.893448829650879, -18.853759765625, -22.264616012573242, -26.264326095581055, -30.64760398864746, -35.43143844604492, -40.881614685058594, -46.78151321411133, -53.28074645996094, -60.14594650268555, -67.65863800048828, -75.57426452636719, -83.90316009521484, -92.6510009765625, -101.67159271240234, -111.09393310546875, -120.8963851928711, -130.7372283935547, -140.8578338623047, -151.1826934814453, -161.45108032226562, -171.68707275390625, -181.88681030273438, -192.0093994140625, -201.9651336669922, -211.44146728515625, -220.5368194580078, -229.08815002441406, -236.95872497558594, -244.12860107421875, -250.03350830078125, -255.0198211669922, -258.6030578613281, -260.8245849609375, -261.3992614746094, -260.24658203125, -257.4360656738281, -252.7838134765625, -246.27366638183594, -238.07705688476562, -227.87924194335938, -216.1581268310547, -202.6925048828125, -187.78042602539062, -171.65713500976562, -154.34814453125, -136.099365234375, -117.21222686767578, -97.7616195678711, -78.2287826538086, -58.7359504699707, -39.5791015625, -21.082490921020508, -3.434455633163452, 12.995287895202637, 28.058889389038086, 41.465084075927734, 53.031864166259766, 62.47975540161133, 69.70883178710938, 74.73368072509766, 77.17980194091797, 77.35396575927734, 74.91259002685547, 70.03999328613281, 62.6734504699707, 53.030277252197266, 41.109169006347656, 27.12456512451172, 11.145931243896484, -6.295029640197754, -25.262977600097656, -45.342403411865234, -66.10214233398438, -87.16321563720703, -108.2612075805664, -128.94970703125, -148.7980499267578, -167.5899658203125, -184.83685302734375, -200.29270935058594, -214.0695343017578, -225.81723022460938, -235.58274841308594, -243.61599731445312, -250.03765869140625, -255.17796325683594, -259.2936706542969, -262.61651611328125, -265.5647277832031, -268.4795227050781, -271.4799499511719, -274.6645202636719, -278.4521179199219, -282.5225524902344, -286.8565368652344, -291.1723937988281, -294.90875244140625, -297.9718322753906, -299.4073791503906, -298.8744201660156, -295.9765930175781, -289.50421142578125, -279.2409362792969, -264.3943786621094, -245.00875854492188, -220.6348419189453, -190.69793701171875, -155.3922576904297, -115.40747833251953, -70.57796478271484, -22.26665496826172, 28.671981811523438, 81.58368682861328, 135.1434783935547, 187.38897705078125, 237.51681518554688, 283.9706726074219, 325.45361328125, 360.8489685058594, 389.61505126953125, 410.4261779785156, 423.3257751464844, 427.9797058105469, 425.0516357421875, 414.5091247558594, 397.27197265625, 374.6761169433594, 347.7303161621094, 317.2312316894531, 284.85809326171875, 251.4286346435547, 217.69737243652344, 184.671875, 152.61756896972656, 122.02897644042969, 92.98725128173828, 66.06549072265625, 41.02457809448242, 18.363605499267578, -1.3428469896316528, -17.998144149780273, -30.356945037841797, -37.63129806518555, -38.97078323364258, -33.15865707397461, -19.081045150756836, 3.902491569519043, 36.05615997314453, 77.55513763427734, 128.2191619873047, 186.6639404296875, 250.9496307373047, 319.3066101074219, 389.4766540527344, 458.1557312011719, 523.0272216796875, 581.12158203125, 630.7000732421875, 669.0634765625, 695.9219970703125, 710.3073120117188, 712.5518188476562, 703.1182861328125, 683.9503784179688, 657.1199951171875, 623.9813842773438, 587.6361694335938, 550.092041015625, 513.1712646484375, 479.08843994140625, 448.8179626464844, 423.92730712890625, 404.49127197265625, 390.9345703125, 382.5982666015625, 379.88885498046875, 381.59735107421875, 387.0757751464844, 395.624755859375, 404.5106506347656, 413.68988037109375, 419.83355712890625, 421.4366760253906, 414.4392395019531, 397.3197021484375, 366.9095458984375, 318.6419372558594, 252.18702697753906, 163.1211700439453, 49.533267974853516, -89.11598205566406, -253.0658416748047, -444.42767333984375, -658.6510620117188, -893.3809814453125, -1143.2322998046875, -1402.3004150390625, -1659.691162109375, -1904.55419921875, -2128.58642578125, -2322.201416015625, -2478.836181640625, -2593.798828125, -2658.314208984375, -2674.346435546875, -2636.785400390625, -2551.091552734375, -2426.7646484375, -2267.968994140625, -2088.308349609375, -1894.5899658203125, -1698.0277099609375, -1504.9952392578125, -1325.6207275390625, -1161.0538330078125, -1011.71728515625, -880.3507690429688, -764.112060546875, -663.0576782226562, -581.9730834960938, -513.7501220703125, -450.1274108886719, -381.10711669921875, -287.83221435546875, -161.7767333984375, -3.726611852645874, 178.5421142578125, 376.6557922363281, 587.3772583007812, 819.5811157226562, 1082.3680419921875, 1375.642333984375, 1685.84521484375, 2003.54248046875, 2311.553955078125, 2597.65087890625, 2852.4482421875, 3061.604736328125, 3216.046875, 3303.689697265625, 3329.250732421875, 3306.33447265625, 3265.3779296875, 3227.214111328125, 3203.900634765625, 3189.493408203125, 3164.1513671875, 3106.111083984375, 2994.214111328125, 2812.190185546875, 2548.6484375, 2211.5341796875, 1803.9007568359375, 1346.6268310546875, 867.8922729492188, 392.2816162109375, -57.88332748413086, -464.839599609375, -813.6243286132812, -1080.3917236328125, -1245.8509521484375, -1265.7418212890625, -1125.487548828125, -806.9638061523438, -340.0925598144531, 224.4303436279297, 806.7035522460938, 1317.5980224609375, 1665.9912109375, 1785.8856201171875, 1643.0596923828125, 1235.2161865234375, 611.0223388671875, -157.0793914794922, -970.240966796875, -1741.0462646484375, -2397.69384765625, -2900.97509765625, -3238.0673828125, -3402.120849609375, -3388.091064453125, -3188.42333984375, -2807.138671875, -2268.7353515625, -1629.6778564453125, -970.6721801757812, -381.2438049316406, 61.01915740966797, 295.9758605957031, 286.972412109375, 26.794986724853516, -453.44757080078125, -1072.6168212890625, -1718.68505859375, -2257.613037109375, -2567.307373046875, -2585.78271484375, -2319.97314453125, -1841.0654296875, -1247.3114013671875, -633.275634765625, -58.70154571533203, 450.1065979003906, 897.2578735351562, 1297.9876708984375, 1671.998291015625, 2023.0428466796875, 2339.954833984375, 2591.160888671875, 2740.07666015625, 2744.01513671875, 2572.923583984375, 2231.587890625, 1765.991943359375, 1258.4952392578125, 791.8529052734375, 423.1858215332031, 154.2442626953125, -63.9633903503418, -299.1048278808594, -610.4043579101562, -1018.5982055664062, -1496.5772705078125, -1977.8792724609375, -2379.3251953125, -2614.837890625, -2626.49462890625, -2400.277587890625, -1975.269287109375, -1440.8056640625, -908.21142578125, -481.8084411621094, -213.93516540527344, -92.8371810913086, -52.422157287597656, -6.929152965545654, 105.9848861694336, 306.25775146484375, 566.649658203125, 828.98583984375, 1027.8148193359375, 1116.8658447265625, 1087.0269775390625, 969.3905029296875, 833.02099609375, 765.4121704101562, 841.2230834960938, 1090.9873046875, 1483.763671875, 1933.1864013671875, 2324.380615234375, 2562.664794921875, 2601.822998046875, 2464.037841796875, 2225.038818359375, 1977.76123046875, 1798.1041259765625, 1711.02294921875, 1693.2005615234375, 1685.588623046875, 1611.8568115234375, 1400.912353515625, 1003.0510864257812, 409.7738952636719, -330.9503173828125, -1120.5341796875, -1829.1600341796875, -2338.541259765625, -2572.553955078125, -2516.0986328125, -2209.353759765625, -1715.036865234375, -1081.343994140625, -330.0781555175781, 536.8734741210938, 1512.5037841796875, 2557.42431640625, 3591.265380859375, 4498.28564453125, 5143.29736328125, 5394.98974609375, 5151.908203125, 4375.2939453125, 3097.447509765625, 1441.0313720703125, -399.9226379394531, -2172.10107421875, -3613.243896484375, -4505.84912109375, -4734.60107421875, -4298.3955078125, -3304.00244140625, -1907.886962890625, -284.41259765625, 1393.0531005859375, 2962.464599609375, 4267.99365234375, 5169.9560546875, 5556.49267578125, 5352.91796875, 4542.876953125, 3171.0146484375, 1348.17529296875, -764.6238403320312, -2967.68212890625, -5039.00732421875, -6756.64599609375, -7944.380859375, -8503.5439453125, -8446.4560546875, -7879.6240234375, -6965.29833984375, -5880.7392578125, -4777.103515625, -3774.999755859375, -2953.456298828125, -2358.951904296875, -1998.6412353515625, -1844.576416015625, -1836.9971923828125, -1891.13525390625, -1915.9647216796875, -1835.7236328125, -1608.7645263671875, -1229.2132568359375, -718.2264404296875, -116.67681121826172, 521.4552001953125, 1122.855712890625, 1608.212646484375, 1898.95263671875, 1943.1502685546875, 1718.1015625, 1243.6737060546875, 564.6923217773438, -251.88278198242188, -1128.1280517578125, -1973.746826171875, -2685.69580078125, -3148.0361328125, -3251.073974609375, -2907.6162109375, -2082.850341796875, -793.0380859375, 904.3507080078125, 2922.00927734375, 5144.28515625, 7423.80419921875, 9596.7294921875, 11500.6845703125, 13010.5390625, 14041.39453125, 14551.99609375, 14520.44140625, 13937.951171875, 12800.310546875, 11118.634765625, 8928.5107421875, 6303.47802734375, 3368.441162109375, 307.2147216796875, -2651.484619140625, -5271.6708984375, -7347.8466796875, -8745.73046875, -9416.0078125, -9410.392578125, -8881.2783203125, -8061.4658203125, -7215.25634765625, -6561.416015625, -6218.29931640625, -6186.05224609375, -6370.8857421875, -6630.02880859375, -6821.431640625, -6847.34814453125, -6655.85107421875, -6235.146484375, -5588.7001953125, -4709.703125, -3595.936767578125, -2260.389404296875, -751.88671875, 843.9403076171875, 2415.393310546875, 3834.68017578125, 4968.833984375, 5702.7001953125, 5962.60888671875, 5762.77490234375, 5213.3720703125, 4501.69580078125, 3838.45263671875, 3400.59033203125, 3291.73583984375, 3513.873046875, 3982.377197265625, 4541.1748046875, 5004.5986328125, 5189.490234375, 4950.03955078125, 4201.01513671875, 2935.5224609375, 1231.18994140625, -752.6134033203125, -2824.26513671875, -4797.0068359375, -6525.38525390625, -7901.837890625, -8836.0498046875, -9246.0576171875, -9055.19921875, -8225.37109375, -6789.48291015625, -4873.58203125, -2682.685302734375, -456.6502685546875, 1583.123779296875, 3281.05224609375, 4573.33349609375, 5484.44384765625, 6115.3935546875, 6620.26953125, 7152.50830078125, 7821.890625, 8640.189453125, 9505.4775390625, 10225.2802734375, 10563.7314453125, 10300.0361328125, 9269.568359375, 7395.93359375, 4697.8095703125, 1284.540283203125, -2662.21533203125, -6900.96728515625, -11142.193359375, -15059.4892578125, -18309.14453125, -20571.6328125, -21591.119140625, -21221.9453125, -19444.203125, -16377.783203125, -12283.0927734375, -7537.22900390625, -2587.04248046875, 2111.4990234375, 6165.81396484375, 9305.671875, 11405.115234375, 12478.8876953125, 12650.015625, 12102.7099609375, 11035.6630859375, 9632.8056640625, 8043.9521484375, 6377.24462890625, 4699.93310546875, 3054.4599609375, 1474.9351806640625, 12.545909881591797, -1255.7828369140625, -2225.22265625, -2791.469970703125, -2885.039306640625, -2510.244384765625, -1745.2353515625, -726.5167846679688, 385.1603088378906, 1437.2388916015625, 2309.793701171875, 2921.265625, 3226.044677734375, 3212.56640625, 2891.654541015625, 2288.349853515625, 1443.305908203125, 399.8255310058594, -791.3062744140625, -2066.523681640625, -3342.944580078125, -4514.60498046875, -5463.2392578125, -6082.986328125, -6306.255859375, -6113.1640625, -5526.4755859375, -4598.8955078125, -3397.221435546875, -2004.2880859375, -508.2046813964844, 998.6906127929688, 2430.172607421875, 3714.91162109375, 4788.8583984375, 5589.35302734375, 6049.1953125, 6088.62939453125, 5636.767578125, 4654.41650390625, 3166.9130859375, 1273.3779296875, -868.8308715820312, -3075.798095703125, -5159.13427734375, -6932.990234375, -8225.3798828125, -8890.3017578125, -8839.984375, -8056.2255859375, -6599.79638671875, -4592.185546875, -2198.03955078125, 396.4053649902344, 3000.39111328125, 5436.25732421875, 7551.74072265625, 9232.37890625, 10413.640625, 11086.482421875, 11290.251953125, 11088.5322265625, 10551.5009765625, 9731.591796875, 8655.62890625, 7332.2587890625, 5750.32666015625, 3909.052734375, 1824.6683349609375, -452.24810791015625, -2841.332763671875, -5239.0908203125, -7523.74560546875, -9585.0537109375, -11320.6826171875, -12652.357421875, -13522.6640625, -13897.8017578125, -13768.80078125, -13155.1962890625, -12102.642578125, -10685.6455078125, -9013.83984375, -7237.99072265625, -5524.11572265625, -4021.00537109375, -2801.181640625, -1839.702880859375, -1025.627685546875, -208.56729125976562, 760.4664306640625, 1978.9022216796875, 3474.14208984375, 5191.46435546875, 7007.0546875, 8754.525390625, 10262.501953125, 11370.1875, 11950.5810546875, 11926.689453125, 11286.98828125, 10063.5537109375, 8325.6689453125, 6152.55419921875, 3644.546142578125, 952.2072143554688, -1692.83984375, -3987.6708984375, -5610.57177734375, -6294.7822265625, -5901.22998046875, -4457.59033203125, -2166.255859375, 618.2501831054688, 3452.29150390625, 5879.865234375, 7505.82666015625, 8063.0458984375, 7452.0380859375, 5747.98388671875, 3185.813720703125, 110.57550048828125, -3091.5244140625, -6057.2568359375, -8476.78125, -10104.33984375, -10761.509765625, -10351.0859375, -8898.1396484375, -6569.775390625, -3656.220458984375, -541.739501953125, 2358.51904296875, 4663.005859375, 6090.74658203125, 6502.22607421875, 5906.8623046875, 4440.71240234375, 2347.70458984375, -36.70686340332031, -2316.924072265625, -4093.6748046875, -5055.74560546875, -5057.86279296875, -4146.5439453125, -2524.37109375, -471.70050048828125, 1724.1322021484375, 3821.683837890625, 5626.96826171875, 6989.634765625, 7784.62548828125, 7906.94287109375, 7288.43359375, 5922.49462890625, 3881.4169921875, 1318.98193359375, -1539.0703125, -4422.451171875, -7038.232421875, -9106.3408203125, -10418.0009765625, -10883.6123046875, -10546.1015625, -9558.4111328125, -8107.087890625, -6357.2890625, -4421.25634765625, -2377.06640625, -285.2873840332031, 1769.020751953125, 3668.833740234375, 5267.3486328125, 6403.11376953125, 6943.8818359375, 6810.728515625, 6002.57470703125, 4605.88916015625, 2789.88037109375, 790.26708984375, -1128.2886962890625, -2717.2861328125, -3774.592041015625, -4175.140625, -3850.71484375, -2790.549560546875, -1027.796142578125, 1332.62060546875, 4109.9443359375, 7040.65869140625, 9783.232421875, 11954.828125, 13168.1318359375, 13086.6044921875, 11486.0830078125, 8313.9404296875, 3729.079345703125, -1883.8349609375, -7935.40478515625, -13697.7080078125, -18412.6875, -21442.23828125, -22395.779296875, -21195.212890625, -18061.96484375, -13450.7177734375, -7962.71240234375, -2249.826416015625, 3081.97998046875, 7535.052734375, 10753.857421875, 12524.7685546875, 12769.8505859375, 11550.146484375, 9068.5771484375, 5669.34326171875, 1804.6953125, -2005.4217529296875, -5238.3515625, -7449.65478515625, -8355.8994140625, -7900.56396484375, -6267.86474609375, -3819.43212890625, -1013.551025390625, 1694.159423828125, 3924.467529296875, 5429.0390625, 6098.51806640625, 5952.4619140625, 5103.0283203125, 3723.76953125, 2027.6337890625, 255.60256958007812, -1345.816650390625, -2548.173828125, -3169.662109375, -3098.559814453125, -2298.629638671875, -824.3981323242188, 1175.7899169921875, 3462.59423828125, 5736.93212890625, 7693.93505859375, 9069.2861328125, 9674.6494140625, 9424.7919921875, 8345.4326171875, 6567.32275390625, 4294.51708984375, 1760.1343994140625, -815.97314453125, -3250.33447265625, -5419.84765625, -7249.8720703125, -8690.9677734375, -9685.125, -10152.9501953125, -10013.115234375, -9222.4140625, -7812.30029296875, -5903.3994140625, -3688.6962890625, -1388.757568359375, 788.9358520507812, 2696.648681640625, 4255.50341796875, 5464.8603515625, 6370.35546875, 7038.64208984375, 7505.01611328125, 7745.81201171875, 7661.904296875, 7099.888671875, 5890.9638671875, 3919.27880859375, 1164.7464599609375, -2240.926025390625, -6027.91650390625, -9815.4951171875, -13182.859375, -15751.927734375, -17243.1328125, -17505.900390625, -16536.412109375, -14462.0380859375, -11510.08984375, -7960.61572265625, -4114.52197265625, -291.4644775390625, 3182.91796875], [-0.0002363668754696846, 3.248758366680704e-05, -0.02272299863398075, -0.12427648901939392, -0.34072595834732056, -0.703326404094696, -1.232876181602478, -1.9435216188430786, -2.855067729949951, -3.9797043800354004, -5.326785087585449, -6.928105354309082, -8.770445823669434, -10.852550506591797, -13.169245719909668, -15.811121940612793, -18.636123657226562, -21.797142028808594, -25.179851531982422, -28.840913772583008, -32.78102111816406, -36.91926193237305, -41.3305778503418, -46.019779205322266, -50.900203704833984, -56.06928634643555, -61.439117431640625, -67.01573944091797, -72.70178985595703, -78.61245727539062, -84.76376342773438, -90.9416732788086, -97.38601684570312, -103.75486755371094, -110.29390716552734, -116.89073944091797, -123.549560546875, -130.27244567871094, -136.9250030517578, -143.63209533691406, -150.2451934814453, -156.88145446777344, -163.5145721435547, -170.10797119140625, -176.6138458251953, -183.12374877929688, -189.7237091064453, -196.17567443847656, -202.8488006591797, -209.4646453857422, -216.0310516357422, -222.84776306152344, -229.68264770507812, -236.56321716308594, -243.751220703125, -250.90606689453125, -258.15631103515625, -265.528076171875, -272.8392028808594, -280.353759765625, -287.7794494628906, -295.25079345703125, -302.5528869628906, -309.7589111328125, -316.6422119140625, -323.4906311035156, -330.00390625, -336.10040283203125, -341.81884765625, -347.0174865722656, -351.86834716796875, -356.2604064941406, -359.9493713378906, -363.2879638671875, -365.9469299316406, -367.94561767578125, -369.63323974609375, -370.5509948730469, -371.0988464355469, -371.1474304199219, -370.6478576660156, -369.6492004394531, -368.1997985839844, -366.28912353515625, -363.8592834472656, -361.1094055175781, -357.93487548828125, -354.1636657714844, -350.0964660644531, -345.64862060546875, -340.77557373046875, -335.6390380859375, -330.2416687011719, -324.6484680175781, -318.8221130371094, -313.1126403808594, -307.27679443359375, -301.7760925292969, -296.4519958496094, -291.5194396972656, -287.00946044921875, -283.2714538574219, -280.09564208984375, -277.6102600097656, -275.93194580078125, -275.1328430175781, -274.88739013671875, -275.31304931640625, -276.4383544921875, -278.1855163574219, -280.06463623046875, -282.43084716796875, -284.76226806640625, -287.0846252441406, -289.295166015625, -291.0511779785156, -292.3878173828125, -293.0793151855469, -293.0560302734375, -292.30181884765625, -290.7598876953125, -288.2427673339844, -284.7197265625, -280.4508056640625, -274.9118347167969, -268.16229248046875, -260.41650390625, -251.06556701660156, -240.39898681640625, -228.19793701171875, -214.24591064453125, -198.48007202148438, -181.07228088378906, -162.2152862548828, -141.3441925048828, -118.656494140625, -94.83497619628906, -69.5404052734375, -43.51698303222656, -16.69999122619629, 10.053811073303223, 36.546539306640625, 62.15155029296875, 86.54090881347656, 109.29095458984375, 130.40858459472656, 149.13720703125, 165.24200439453125, 178.8687286376953, 189.562744140625, 197.32164001464844, 202.56809997558594, 204.77410888671875, 204.4911651611328, 201.37680053710938, 195.64906311035156, 187.659423828125, 177.24093627929688, 164.68846130371094, 150.02548217773438, 132.96485900878906, 114.22663116455078, 93.28460693359375, 70.99272918701172, 46.976261138916016, 22.021831512451172, -3.938359260559082, -30.049535751342773, -55.7281494140625, -80.99165344238281, -104.7804183959961, -127.41825866699219, -147.80810546875, -166.16172790527344, -182.03317260742188, -195.9050750732422, -207.1226043701172, -216.16432189941406, -222.91697692871094, -227.3524932861328, -230.2783203125, -231.16677856445312, -230.179931640625, -227.1015167236328, -221.44454956054688, -213.36459350585938, -201.1605682373047, -185.46578979492188, -164.8919677734375, -139.18470764160156, -107.83908081054688, -70.6612548828125, -28.420026779174805, 19.327058792114258, 71.23908996582031, 126.88404846191406, 184.2034912109375, 242.44003295898438, 299.83453369140625, 354.9646911621094, 405.49566650390625, 451.1397399902344, 490.09844970703125, 521.6666259765625, 546.2083129882812, 562.4176635742188, 570.9651489257812, 572.4923095703125, 567.3732299804688, 557.0477905273438, 540.9713134765625, 520.9962158203125, 496.6778564453125, 469.5596618652344, 438.1189880371094, 402.8114929199219, 363.8863220214844, 318.8277587890625, 268.2273254394531, 209.4225616455078, 141.82810974121094, 64.84532165527344, -21.459810256958008, -117.2166519165039, -217.75852966308594, -321.61822509765625, -426.5128173828125, -526.3145751953125, -621.0978393554688, -706.2302856445312, -779.8753662109375, -836.8190307617188, -874.1867065429688, -887.973388671875, -874.917724609375, -836.6166381835938, -775.3381958007812, -699.667236328125, -610.9678955078125, -518.9967041015625, -431.0195617675781, -351.4302978515625, -276.72003173828125, -208.39427185058594, -142.88864135742188, -77.00467681884766, -15.658034324645996, 37.46088409423828, 83.68240356445312, 117.5245361328125, 157.80328369140625, 209.10302734375, 283.77825927734375, 378.8138427734375, 481.6645812988281, 570.981201171875, 632.8842163085938, 668.0609741210938, 688.4481201171875, 715.4008178710938, 758.97509765625, 822.363525390625, 894.840576171875, 972.9986572265625, 1050.4849853515625, 1119.0775146484375, 1161.558837890625, 1165.3875732421875, 1125.8204345703125, 1060.7391357421875, 997.093505859375, 980.5383911132812, 1027.4986572265625, 1134.110595703125, 1268.3563232421875, 1387.0577392578125, 1449.7337646484375, 1432.2366943359375, 1330.046142578125, 1154.240234375, 925.5941772460938, 677.6231079101562, 451.2135009765625, 274.8551330566406, 157.1724395751953, 76.30075073242188, -10.710590362548828, -148.2183837890625, -361.41217041015625, -624.9678955078125, -882.1837158203125, -1055.739013671875, -1087.8406982421875, -949.1927490234375, -664.9271850585938, -295.29913330078125, 77.86738586425781, 377.20556640625, 561.4716186523438, 622.37109375, 583.8590087890625, 506.7720642089844, 442.4771728515625, 443.3363952636719, 523.3622436523438, 662.5413208007812, 805.88720703125, 884.4549560546875, 845.5563354492188, 687.0132446289062, 448.7643127441406, 205.550048828125, 30.213180541992188, -26.825973510742188, 49.984779357910156, 231.02804565429688, 454.8700866699219, 640.7724609375, 704.717041015625, 593.3175659179688, 304.6881103515625, -112.51225280761719, -563.2665405273438, -940.1329956054688, -1176.14501953125, -1255.9515380859375, -1222.1287841796875, -1158.8177490234375, -1137.6416015625, -1191.4417724609375, -1301.456298828125, -1402.65771484375, -1418.637451171875, -1280.2213134765625, -953.2261352539062, -448.0205993652344, 181.86842346191406, 854.53173828125, 1480.692138671875, 1994.85546875, 2362.3994140625, 2601.220703125, 2768.274658203125, 2946.142578125, 3203.093017578125, 3564.52685546875, 3991.070068359375, 4395.51904296875, 4673.94287109375, 4737.03515625, 4531.298828125, 4037.683349609375, 3273.033447265625, 2283.727294921875, 1144.8916015625, -53.005863189697266, -1224.4285888671875, -2309.746826171875, -3280.29296875, -4139.8505859375, -4892.82470703125, -5517.21435546875, -5943.33154296875, -6065.89013671875, -5788.15234375, -5064.44677734375, -3922.423095703125, -2462.654541015625, -829.7693481445312, 819.794189453125, 2347.264404296875, 3652.291015625, 4681.42138671875, 5420.25830078125, 5883.39208984375, 6093.98828125, 6071.06982421875, 5822.51220703125, 5347.69677734375, 4637.35986328125, 3689.18701171875, 2521.71240234375, 1193.7880859375, -194.14291381835938, -1515.9163818359375, -2643.49658203125, -3472.145751953125, -3938.042236328125, -4025.937744140625, -3769.199462890625, -3236.79345703125, -2516.842041015625, -1685.1591796875, -789.5820922851562, 151.14181518554688, 1124.533935546875, 2098.440673828125, 3014.59326171875, 3800.001708984375, 4383.7001953125, 4717.5185546875, 4778.37158203125, 4578.3681640625, 4159.162109375, 3587.0029296875, 2945.420654296875, 2320.309326171875, 1788.0955810546875, 1397.5155029296875, 1156.9755859375, 1032.646240234375, 952.8920288085938, 837.4827270507812, 629.1459350585938, 315.9784851074219, -72.85401153564453, -484.92901611328125, -880.1256713867188, -1245.720947265625, -1610.6669921875, -2024.7088623046875, -2528.98779296875, -3119.8447265625, -3757.277587890625, -4374.05810546875, -4894.6162109375, -5237.45751953125, -5320.89111328125, -5075.52978515625, -4467.6015625, -3517.525146484375, -2302.465576171875, -933.9813232421875, 478.22589111328125, 1858.8638916015625, 3171.23828125, 4407.6552734375, 5570.146484375, 6650.74462890625, 7624.39013671875, 8449.2314453125, 9073.544921875, 9438.9150390625, 9468.30859375, 9074.3056640625, 8172.30859375, 6707.52197265625, 4683.4013671875, 2174.573974609375, -677.87646484375, -3682.12451171875, -6631.23046875, -9326.8798828125, -11585.943359375, -13246.78125, -14182.1318359375, -14313.4423828125, -13636.3603515625, -12220.130859375, -10198.9580078125, -7765.607421875, -5138.533203125, -2548.977783203125, -205.90142822265625, 1715.43701171875, 3106.053466796875, 3926.87060546875, 4223.35009765625, 4103.0751953125, 3716.6142578125, 3218.493408203125, 2738.912109375, 2367.11865234375, 2152.8017578125, 2123.531982421875, 2278.150390625, 2593.81689453125, 3025.030517578125, 3509.8603515625, 3983.3662109375, 4387.51318359375, 4669.609375, 4791.19384765625, 4713.30224609375, 4385.56591796875, 3748.6962890625, 2750.962890625, 1383.4837646484375, -284.6287536621094, -2099.1328125, -3850.143798828125, -5312.41015625, -6294.46728515625, -6666.50634765625, -6379.29345703125, -5462.0517578125, -4020.56982421875, -2207.6513671875, -209.13787841796875, 1792.564697265625, 3622.263916015625, 5129.58837890625, 6190.79443359375, 6706.06689453125, 6598.5419921875, 5822.78173828125, 4377.33447265625, 2329.053466796875, -166.84814453125, -2872.62158203125, -5474.1884765625, -7631.623046875, -9036.2451171875, -9480.2919921875, -8898.5205078125, -7383.169921875, -5172.92822265625, -2601.231689453125, -33.38239288330078, 2196.944580078125, 3817.103271484375, 4637.14501953125, 4558.71826171875, 3583.666748046875, 1814.4066162109375, -559.079345703125, -3277.211669921875, -6045.1650390625, -8557.529296875, -10514.552734375, -11636.60546875, -11694.7666015625, -10554.3681640625, -8214.05859375, -4826.80029296875, -690.1030883789062, 3805.02978515625, 8246.8125, 12277.93359375, 15631.1982421875, 18122.365234375, 19632.451171875, 20084.939453125, 19453.87890625, 17756.185546875, 15055.6884765625, 11459.412109375, 7128.529296875, 2284.021240234375, -2786.289794921875, -7715.8427734375, -12078.9130859375, -15436.0419921875, -17410.572265625, -17794.822265625, -16621.90625, -14187.4208984375, -10975.6416015625, -7539.95703125, -4375.63818359375, -1845.000732421875, -160.9282989501953, 606.0843505859375, 485.6348571777344, -422.3974304199219, -1971.9552001953125, -3980.87939453125, -6227.1923828125, -8462.27734375, -10421.1142578125, -11833.009765625, -12442.3623046875, -12050.052734375, -10577.583984375, -8111.4150390625, -4916.0546875, -1388.5723876953125, 2029.851318359375, 4959.1669921875, 7136.62646484375, 8441.86328125, 8881.5068359375, 8567.65234375, 7688.14697265625, 6481.3779296875, 5198.92919921875, 4087.927734375, 3347.37158203125, 3106.431884765625, 3410.261962890625, 4221.5712890625, 5441.50341796875, 6913.08447265625, 8438.412109375, 9806.66796875, 10798.654296875, 11201.0087890625, 10824.828125, 9539.8671875, 7316.291015625, 4261.80615234375, 624.447265625, -3231.051025390625, -6872.23046875, -9865.1484375, -11838.9658203125, -12549.3681640625, -11922.814453125, -10069.5556640625, -7264.36279296875, -3876.11181640625, -297.4770812988281, 3106.119384765625, 6022.93505859375, 8206.431640625, 9472.951171875, 9708.89453125, 8879.01953125, 7051.22509765625, 4397.2021484375, 1184.5489501953125, -2247.610107421875, -5511.423828125, -8203.9541015625, -9968.119140625, -10550.1474609375, -9853.78125, -7966.07763671875, -5145.45361328125, -1792.5633544921875, 1622.086669921875, 4633.05517578125, 6842.8115234375, 7972.181640625, 7890.85693359375, 6620.333984375, 4335.56494140625, 1325.087646484375, -2044.7247314453125, -5385.09130859375, -8341.19921875, -10632.6826171875, -12076.2119140625, -12588.5078125, -12168.1396484375, -10877.474609375, -8839.8271484375, -6240.8955078125, -3340.42333984375, -442.1082763671875, 2157.6865234375, 4237.52978515625, 5680.91650390625, 6469.55029296875, 6662.8505859375, 6368.435546875, 5741.205078125, 4965.568359375, 4238.25146484375, 3733.57958984375, 3580.625244140625, 3842.301513671875, 4517.7666015625, 5556.83203125, 6881.810546875, 8381.60546875, 9922.767578125, 11344.49609375, 12474.19140625, 13148.3720703125, 13234.712890625, 12650.388671875, 11364.06640625, 9397.482421875, 6825.76611328125, 3783.301025390625, 452.36309814453125, -2947.726318359375, -6178.14013671875, -9004.984375, -11246.1279296875, -12812.8486328125, -13737.3330078125, -14153.0947265625, -14252.0263671875, -14227.3935546875, -14227.7373046875, -14321.2275390625, -14490.4619140625, -14648.4814453125, -14675.41796875, -14448.2958984375, -13867.77734375, -12880.1025390625, -11484.359375, -9717.8388671875, -7635.8994140625, -5285.73046875, -2710.7939453125, 32.79069137573242, 2865.0751953125, 5679.984375, 8361.740234375, 10804.5615234375, 12917.375, 14628.2822265625, 15883.591796875, 16667.18359375, 16998.90234375, 16939.0078125, 16573.23828125, 16009.59375, 15353.0595703125, 14677.29296875, 14009.0859375, 13327.6884765625, 12587.150390625, 11734.5869140625, 10710.1162109375, 9436.666015625, 7812.54541015625, 5728.19970703125, 3106.21337890625, -65.9186782836914, -3714.0986328125, -7677.0341796875, -11712.1767578125, -15521.8525390625, -18775.537109375, -21144.544921875, -22330.4296875, -22126.50390625, -20502.119140625, -17654.05078125, -13994.0546875, -10037.025390625, -6261.07275390625, -3021.83154296875, -522.8541870117188, 1156.9803466796875, 2051.294677734375, 2269.97607421875, 1993.8907470703125, 1440.786865234375, 841.9946899414062, 392.2531433105469, 224.84091186523438, 398.39910888671875, 919.1035766601562, 1789.7647705078125, 3022.39501953125, 4617.04248046875, 6511.61572265625, 8550.2099609375, 10499.400390625, 12094.4306640625, 13102.3740234375, 13360.8095703125, 12790.181640625, 11391.9365234375, 9242.4560546875, 6469.42919921875, 3257.97265625, -147.3967742919922, -3454.0205078125, -6349.5166015625, -8569.9638671875, -9938.689453125, -10382.0498046875, -9907.669921875, -8578.5, -6499.59375, -3817.455810546875, -723.0833129882812, 2534.96435546875, 5665.8095703125, 8359.6513671875, 10318.4072265625, 11288.93359375, 11075.92578125, 9557.6796875, 6704.353515625, 2605.437744140625, -2478.239013671875, -8106.6826171875, -13695.4755859375, -18617.111328125, -22314.767578125, -24397.833984375, -24689.208984375, -23222.43359375, -20222.576171875, -16074.392578125, -11261.6904296875, -6283.24658203125, -1556.822509765625, 2643.444091796875, 6176.98583984375, 9000.55859375, 11121.994140625, 12571.8349609375, 13405.76953125, 13687.75, 13509.576171875, 12979.9892578125, 12218.8740234375, 11319.541015625, 10329.6494140625, 9254.0810546875, 8074.580078125, 6766.17724609375, 5294.84326171875, 3583.685546875, 1523.5899658203125, -998.026611328125, -4019.0029296875, -7425.31591796875, -10930.8984375, -14107.1865234375, -16481.658203125, -17657.03515625, -17418.18359375, -15776.0146484375, -12920.40234375, -9143.2685546875, -4777.7509765625, -157.4120635986328, 4404.6220703125, 8642.4453125, 12349.46484375, 15376.6142578125, 17607.90625, 18940.693359375, 19282.064453125, 18554.671875, 16706.189453125, 13728.853515625, 9675.1748046875, 4685.46533203125, -994.7739868164062, -7023.072265625, -12974.0458984375, -18361.873046875, -22671.083984375, -25432.45703125, -26330.8984375, -25289.396484375, -22475.96875, -18250.75, -13087.7880859375, -7526.29541015625, -2127.56640625, 2584.193603515625, 6185.58740234375, 8407.421875, 9162.837890625, 8551.7333984375, 6859.287109375, 4502.7099609375, 1958.145263671875, -332.29962158203125, -2027.8516845703125, -2924.046875, -2953.84375, -2168.802734375, -704.7134399414062, 1257.2481689453125, 3531.88330078125, 5949.125, 8347.2587890625, 10543.6513671875, 12334.3505859375, 13491.640625, 13798.1572265625, 13072.0361328125, 11197.376953125, 8142.4130859375, 3981.507080078125, -1092.008056640625, -6756.47802734375, -12562.7822265625, -17960.150390625]], "n_steps": 9000}, "run_linear": {"hits": [{"time": 0.0, "kind": "mallet", "peak_force": 1977.553084535146, "contact_time": 0.004492063492063492, "rebound_velocity": 4.849030136533902, "energy_in": 9.6, "energy_out": 3.5269639897520992}], "energy_log": [[0.0011337868480725624, 0.11518240667885472, 0.19065997418634467, 0.11451987457233755, 7.022382852819921, 0.6860066068981031], [0.005668934240362812, 0.5570099533337556, 2.8770921846038275, 2.6003136787430403, 3.5269639897520992, 23.43797422196923], [0.01020408163265306, 4.998916708394579, 0.1307667480176439, 0.8429981585032716, 3.5269639897520992, 7.36942830859002], [0.01473922902494331, 1.4294124659295904, 2.1731314274331015, 2.3215972995204033, 3.5269639897520992, 15.067711563105279], [0.01927437641723356, 3.334860836020404, 1.2724056899637306, 1.2420828517676603, 3.5269639897520992, 13.382669747904702], [0.02040816326530612, 0.9979042635872203, 2.389129283330328, 2.450891765985065, 3.5269639897520992, 17.103206826435265]], "pressure_rayleigh": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.86495700768608e-12, 1.422487193578079e-09, 7.739936462340438e-09, -2.717294123912232e-08, -7.105821443201797e-09, -3.1180815720779964e-08, -5.7475444934873744e-08, 8.735603161766784e-08, -2.037127073740695e-07, 3.825916557199937e-07, -4.500402784955896e-07, 7.824776703384939e-07, -6.663975153177697e-07, 1.0974528303876697e-06, -7.081514692750613e-07, 1.4061667179220331e-06, -1.9235314278638233e-07, 9.86965974171156e-05, 0.0004999397636682225, 0.000363182559037643, -0.0017763379013453714, -0.006670483695719827, -0.014506029684398571, -0.025212289691011747, -0.038556639353066434, -0.05417829711474148, -0.07167739099576172, -0.09066795675937617, -0.11075466153202455, -0.1314982096296922, -0.15244739513042052, -0.17321137662642397, -0.19344788338450752, -0.21281905524101707, -0.23098655295864484, -0.24766274205261318, -0.2626546093708907, -0.2758389797143212, -0.28711380427932187, -0.29640564149784493, -0.3037256202864721, -0.30915553349117886, -0.31279883088132826, -0.31476758686880124, -0.3151885580612037, -0.3141878735239233, -0.31190045175768916, -0.3084779809554727, -0.3040476734370727, -0.29873149565751, -0.29268156472779555, -0.2860698754546422, -0.279050471849909, -0.27173835820562164, -0.26424314725427794, -0.25670044182328905, -0.24925084285453988, -0.24201768980496463, -0.23510726250030364, -0.2286237820557823, -0.22266856023435055, -0.21732982013152735, -0.2126886682510157, -0.20881176702624166, -0.20574107688461796, -0.20349626274681287, -0.20207909453127793, -0.20147582245963863, -0.20166218052339943, -0.202617057532459, -0.20432276411034692, -0.20673466191227902, -0.2097632579107452, -0.21329677047318193, -0.2172306510086483, -0.22145061272148792, -0.2258158897608631, -0.23017093931917967, -0.23436742007335679, -0.2382727623495626, -0.24174505715845196, -0.24462976302528702, -0.24678734425395535, -0.24809147507362672, -0.2484198678508887, -0.2476593417502896, -0.24571528587140581, -0.2425153262274941, -0.23799717753987165, -0.23210574174398427, -0.22481638709198878, -0.21613355122821484, -0.2060836765508131, -0.19469743325028546, -0.18199111889611347, -0.16798093239907802, -0.15270562380153763, -0.13622912824506625, -0.11860792787547828, -0.0998784616510039, -0.08008377543880493, -0.05929571153432335, -0.037590837293707276, -0.015019982299326875, 0.008371559462036453, 0.03250795884272313, 0.057292933000911525, 0.08264334350468594, 0.1084852797667938, 0.13471690830230185, 0.16120323728462566, 0.18780753976964393, 0.2144067013586229, 0.2408677987078058, 0.26701621708601153, 0.29266163174831844, 0.31763540828616355, 0.34178556144432676, 0.3649507936385405, 0.3869490707095752, 0.40759586973984024, 0.42673064360994334, 0.444227528712966, 0.45997870700981447, 0.473874462679175, 0.4858185765496261, 0.4957485274606496, 0.5036258099753024, 0.5094191305750765, 0.5131180212053228, 0.5147594528494028, 0.5144160330415692, 0.5121502128791383, 0.5080159851375344, 0.5021202047408335, 0.49461184743404507, 0.485624750883752, 0.47527768004638443, 0.46370540319539794, 0.4510785513049959, 0.43758282845815766, 0.42338798110213766, 0.4086542222057304, 0.3935515598967784, 0.3782599630817514, 0.3629662278732091, 0.34784405436318117, 0.3330466490512404, 0.3187113901542734, 0.30496849011606136, 0.2919432060703575, 0.2797363750800577, 0.26843524467743307, 0.2581403945446136, 0.24894149045631556, 0.24086894098602696, 0.23391378600675428, 0.22807719275872515, 0.22336175895245997, 0.21973760534919576, 0.2171373966887382, 0.2154879396280004, 0.21471713823512195, 0.2147354890139728, 0.21542813395143648, 0.21666375286534884, 0.21831313536644503, 0.2202308518549672, 0.22225133379509068, 0.22421385304000022, 0.2259502851953928, 0.2272780062973507, 0.2280289831744882, 0.22807264586111528, 0.22729111618190803, 0.22556225621521994, 0.22278150553787623, 0.21887288213107356, 0.21377628613461644, 0.20743880252584782, 0.1998341795467433, 0.19097761381372116, 0.18092079266355302, 0.16972535984013037, 0.15746147086342938, 0.1442276500393414, 0.1301447847308835, 0.11534023271080761, 0.099938439999179, 0.0840614751178069, 0.06783806193249091, 0.051413063775032485, 0.03493435531294177, 0.01854311391722159, 0.002372677489881049, -0.013429161140227667, -0.028693124529193672, -0.04326321246439537, -0.05701171884076633, -0.06982599778948573, -0.08150405494499144, -0.09180966083727522, -0.10060748493029241, -0.10790544564924595, -0.11383716854505073, -0.11851696494170626, -0.12201915646409317, -0.12442956831174577, -0.12571607317772157, -0.12574496333235152, -0.12450262193203052, -0.12212502121942809, -0.11887264943942179, -0.11500412425569412, -0.11071069926192743, -0.10608237794900219, -0.10108299386305286, -0.0957211070911095, -0.09011585379761118, -0.08440466314503073, -0.0787105059079273, -0.07312078174522155, -0.06766230056695159, -0.062307226704582004, -0.05701320077108258, -0.051748794835390556, -0.04647065076909703, -0.04111052406037833, -0.035604029580414656, -0.02991918551929625, -0.024035814937913402, -0.017914760638086388, -0.01152017277677855, -0.00485430180769137, 0.0020556879799562004, 0.009180931650176019, 0.01650598692147458, 0.024005270083733588, 0.03164023304330077, 0.03937839729420733, 0.047199514623801425, 0.05508548716504958, 0.06299524362865738, 0.0708819523116665, 0.078718248719819, 0.08650036549219414, 0.09423634127408613, 0.10191695228502828, 0.10950531215177578, 0.11697013412883887, 0.1242973021263974, 0.13145536473290212, 0.13837680300764818, 0.14497967062175332, 0.15119171702897996, 0.15694590083017085, 0.1621492778473956, 0.16668809369749865, 0.1704670627865477, 0.1734173046607305, 0.1754755897787232, 0.17657797685081134, 0.1766712554050276, 0.17571229574554723, 0.17366339903745664, 0.1705152993574745, 0.1662960378940457, 0.1610446901334526, 0.15480379885743287, 0.14763035955056802, 0.13960215889589278, 0.1308204902481967, 0.12138544131118952, 0.11139279229021457, 0.10094707988250631, 0.09016238641023228, 0.07915726208365849, 0.06803930408828739, 0.0568987669961111, 0.04582624146335412, 0.03492732127214985, 0.0243178686879385, 0.014099289733255192, 0.004344851109694963, -0.004878749951326182, -0.013506488062506069, -0.02148690072060897, -0.028782011994543073, -0.03534610670293066, -0.041137892188523366, -0.046130866961598835, -0.05031265845629352, -0.053683675464265855, -0.0562322797476844, -0.05794009891174513, -0.058805024016155415, -0.05885111564391539, -0.05811491685982905, -0.05663184403565281, -0.054436005755670445, -0.051557069724686024, -0.048038531719218826, -0.04394140350636889, -0.039327684693452145, -0.03426070932093237, -0.02880134324316427, -0.023014765141078485, -0.016994952952883256, -0.010859105582318455, -0.004714535983694985, 0.0013574429245476155, 0.00728438530924071, 0.012974768962179504, 0.01833086396753061, 0.023274821024979367, 0.027736239353751135, 0.03164094436091559, 0.034912368875288674, 0.03748497797881673, 0.03932273730541623, 0.040392255334053245, 0.04064250877346674, 0.04004176211924259, 0.03860255637363287, 0.036367708406564093, 0.03338080885503053, 0.02966813007366493, 0.02526710513834642, 0.02024023968372146, 0.014657454455541676, 0.008579030938933085, 0.0020594779615333955, -0.004814268740726491, -0.011921886512452119, -0.019161189565255674, -0.02647129144011151, -0.033791318409054735, -0.04103943901875875, -0.048130968459200084, -0.055003013793185215, -0.06161979869135835, -0.06794828140803036, -0.07393802201994866, -0.07953387596047579, -0.08467973832470242, -0.08931032003689345, -0.09335089577908187, -0.09672616896523965, -0.09937648887646365, -0.10125077383029332, -0.10229188700417313, -0.10243084085999675, -0.10160635413276613, -0.09977179396071675, -0.09687711189108202, -0.09287420861132449, -0.08773751155824677, -0.08147874648061854, -0.0741371167260346, -0.06576206337177756, -0.05643545369345638, -0.0462785951941942, -0.035422523127373484, -0.02401281741296995, -0.01220949083171091, -0.00017613167328806077, 0.011919669021222212, 0.02392120207342231, 0.03567383580897204, 0.04699718976939981, 0.05771216561601883, 0.06766517489058962, 0.07672609761928734, 0.08477426942386318, 0.09169188564080746, 0.09739002425996497, 0.10181671087294962, 0.10494088824201345, 0.10672599530261279, 0.10712899892852694, 0.10611541688561894, 0.10367668837558246, 0.09982232928257623, 0.094569494907163, 0.08795474197268062, 0.08002709909415373, 0.0708552135541983, 0.060528105435137994, 0.0491405251449604, 0.036804556383202916, 0.02364847699269467, 0.009800320279430102, -0.004624066738345919, -0.019516279713478815, -0.034743321877142457, -0.050138520456767956, -0.06552823978218279, -0.08075747584813171, -0.09568727037356746, -0.11017421772145408, -0.1240817842238562, -0.13729809039806082, -0.1497298915926193, -0.16128140168529126, -0.1718521556529426, -0.18136779099770908, -0.18977525050490643, -0.197016321401414, -0.2030330542107343, -0.2077964527285334, -0.21130791929499668, -0.21357997438649307, -0.21464072461710196, -0.2145458103571554, -0.21337254978992695, -0.21119750698035283, -0.2080888301922713, -0.20412942748022406, -0.1994001165595277, -0.19397802427431732, -0.18794839398057508, -0.18139481668520427, -0.1744095328381715, -0.1670924093733039, -0.1595290031553523, -0.1517863591868956, -0.1439092187441699, -0.1359373043875887, -0.1279308875074788, -0.11994850646508015, -0.11203676677040493, -0.10423571644779459, -0.09658662177053888, -0.08914089188958788, -0.0819543789903913, -0.075079906106577, -0.06856398469374315, -0.06243393279723996, -0.05669842244131924, -0.05136400132795138, -0.046438270598915934, -0.041919764033007706, -0.03779531622103861, -0.03405454259043074, -0.03070737637450447, -0.027766493809763947, -0.02521451011125009, -0.023014528740555592, -0.021143785337295398, -0.01960736471648263, -0.018428554796543723, -0.01761371366696978, -0.01715427139053824, -0.017055369278981256, -0.017339975885650154, -0.018031960062192102, -0.019136133684633978, -0.020641014775676245, -0.02253466398399126, -0.024804405233962372, -0.027414550083063784, -0.03030640889948407, -0.033434388851288514, -0.03676784090810938, -0.040260273521000596, -0.043855878707335955, -0.04750653202203837, -0.05118295530659882, -0.054858727380951024, -0.0584928285249299, -0.06204846204802814, -0.06552478081179323, -0.0689414170788742, -0.07231297879448784, -0.0756390160290149, -0.07891814311484435, -0.08217070674958221, -0.0854127502349544, -0.08863339001527742, -0.09181070967423152, -0.09491911256647742, -0.09792176639101373, -0.10076341923333267, -0.1033568639977757, -0.10562211558159804, -0.10749241052221165, -0.10888331041598759, -0.10969959107728161, -0.10985029906146893, -0.1092629750326316, -0.10788313763283554, -0.10566291604714653, -0.10255764570935448, -0.09854893505974492, -0.09366521196496932, -0.08794969606476478, -0.08143783785392739, -0.07418341026964798, -0.06628433908116489, -0.05786275813073115, -0.04904184299016455, -0.039965021254384725, -0.030796906344872872, -0.02171123630628215, -0.012877630797895149, -0.004466580762756109, 0.0033400556574740355, 0.01036005262620748, 0.016413827242914344, 0.021317404846308646, 0.02488982330792872, 0.02698475756456803, 0.027502787656587088, 0.026354507489516486, 0.023443549775353564, 0.01870809854064092, 0.01215037293775689, 0.003818723161155225, -0.006216154471257583, -0.01787361339099611, -0.03104429007395602, -0.04558238204274299, -0.061320655002243804, -0.07807415505739379, -0.09564498910125868, -0.1138119734457815, -0.132325102674398, -0.15092833398678676, -0.16937052669976008, -0.18741171827987696, -0.20481881137087998, -0.22134166710948444, -0.23673113619834588, -0.2507619985013218, -0.26321395705747186, -0.27386228672071755, -0.2825004855432618, -0.28895381748088056, -0.29307411403619055, -0.2947255528386874, -0.2937959238694246, -0.2902291798720353, -0.284018866313206, -0.27519434763938405, -0.2638122220538027, -0.24996579781875303, -0.23378864499063856, -0.21544306835997346, -0.19512659855640832, -0.1730800322604608, -0.14957926407720581, -0.12492622184721393, -0.09943758297625613, -0.07344244808865683, -0.047278710049761634, -0.021276465108918702, 0.004252238036841908, 0.029018018559948164, 0.05273890129964275, 0.07513368636001615, 0.0959479735641908, 0.11496845574062546, 0.13200542913238464, 0.14688961702778647, 0.15947714987926573, 0.16966256425030596, 0.17738840894519978, 0.182635875031181, 0.1854028031709184, 0.18571731196790303, 0.1836473733396756, 0.17927955484906752, 0.17270766856215855, 0.16403000096346093, 0.15338081083927094, 0.14092517279431213, 0.1268394785173252, 0.11131196506393613, 0.09454451955818295, 0.07676230600329025, 0.05818398227050202, 0.039003489101363774, 0.019417472179671533, -0.00036333431779948675, -0.02011835823319786, -0.039633086387768954, -0.058712977492218044, -0.07717321828404836, -0.09481404887310876, -0.11143175230253811, -0.12684471070480496, -0.14089375827531428, -0.15342630623252618, -0.16429966630130455, -0.1734049833652356, -0.18067088501650133, -0.18603223434538793, -0.18941951502768004, -0.1907835346477663, -0.1901326288276988, -0.187525361059378, -0.18304298616711265, -0.17679315987439992, -0.16892181829272107, -0.15960604597802946, -0.14903738853446147, -0.13741747000184912, -0.1249648999902358, -0.11191006669977097, -0.09848420680134179, -0.08490707086086449, -0.07136633893872334, -0.058034328380090074, -0.04508541946325797, -0.03268658304220696, -0.020984829520682674, -0.010089192827099185, -6.114853402758111e-05, 0.009044716818778956, 0.01716883998263884, 0.02426973053874766, 0.030316338341346175, 0.035277586087875255, 0.039131968307607214, 0.04187289508771648, 0.043495480879707955, 0.043992956307169095, 0.043370297356918816, 0.04166216688369946, 0.03891601743543466, 0.03517782170256201, 0.030507696829346887, 0.02498169543827743, 0.018694042990171442, 0.0117507917117838, 0.004264178625961348, -0.003639654469982503, -0.011844750458491208, -0.02024762094083163, -0.02872864972291278, -0.03715471195584232, -0.045405391654646805, -0.05339480629114802, -0.061058191568573554, -0.06831707573907175, -0.07507660779580279, -0.08125145649328788, -0.08679563457708611, -0.09167766957958443, -0.09584293217331767, -0.0992342704426767, -0.10182483635288077, -0.10361782966664433, -0.10462275589605927, -0.10484880226857408, -0.10431765109065923, -0.10305511790509594, -0.10109803689444145, -0.09850751021180368, -0.09536080079639457, -0.09174262032659097, -0.0877347245083837, -0.0834014714735487, -0.07879043548068364, -0.0739541892409708, -0.06893657514249439, -0.06376711191485052, -0.05845056921056402, -0.05295891345934164, -0.04726426875674069, -0.04134214197949386, -0.035151209900259626, -0.028645945833064488, -0.02178958104662807, -0.014553607453499196, -0.0069046943672962345, 0.0012076306270709654, 0.009812929245217594, 0.01890672033113871, 0.028476503360629932, 0.038501317930625625, 0.048934551356798056, 0.05969908138522379, 0.07070232859478981, 0.08187071866112602, 0.09314251122198244, 0.10441660350005585, 0.11556089754694379, 0.12645028961746657, 0.13696933738380587, 0.14699469319006886, 0.1563832869901595, 0.16497850478268408, 0.17261802203864363, 0.1791449320871992, 0.18441731011609155, 0.18830225592676134, 0.19067859621681585, 0.19144421739126585, 0.1905138652404004, 0.1878106263815395, 0.1832621592753827, 0.17681783144909527, 0.16846914766600388, 0.15824856698039258, 0.14621950729195132, 0.1324731081190646, 0.11712309491294692, 0.10031194519816576, 0.08220645712431772, 0.06300308466124961, 0.0429128154046378, 0.022131869483473055, 0.0008605241579187231, -0.020685958189073005, -0.042268906000103586, -0.06362936792288354, -0.08452209910066025, -0.10471697063701065, -0.1239754009280809, -0.14205191105692136, -0.15871173264666685, -0.17374802061514913, -0.18698044747035308, -0.19822982748726858, -0.20731825229083875, -0.2140875476072969, -0.2183944160342315, -0.22011663254808606, -0.21916240652762176, -0.21547454036212893, -0.20905815061330857, -0.1999658024634424, -0.18827009191590108, -0.174079297543512, -0.15754572366300784, -0.1388696764697347, -0.11827670246879854, -0.09599226747162372, -0.0722668784149964, -0.047395731395316006, -0.02168728200012711, 0.0045544921751415795, 0.031020322601600075, 0.05738776536295004, 0.08333006801264627, 0.10853388114082091, 0.13271495089164567, 0.1556183699272808, 0.17701749162357192, 0.19670079722778164, 0.214461311728703, 0.2301045452154201, 0.24346869821006817, 0.25443662245930126, 0.2629231185750378, 0.26888008045640677, 0.2723024321869849, 0.27322513994757475, 0.2717137960430661, 0.2678604492718898, 0.26179579802585484, 0.25368524032392564, 0.2437037819655897, 0.23203935341432216, 0.2188886703456352, 0.20444825485755264, 0.18892520131643792, 0.17253574404843303, 0.15551680148898725, 0.13810425751262898, 0.12050013992962673, 0.10289786059882731, 0.08550428654705595, 0.06852155720164445, 0.05212627892055766], "pressure_unbaffled": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.86495700768608e-12, 1.4201889436334232e-09, 7.3365430949285306e-09, -3.025837621605691e-08, -1.1180035752596972e-08, -4.030661129420903e-08, -6.618789866688001e-08, 7.33968689257366e-08, -2.1415215752616335e-07, 3.7475496312776406e-07, -4.490775057373301e-07, 8.16530659628517e-07, -6.383491033455577e-07, 1.224309580977902e-06, -6.445037269699388e-07, 1.6877111721197495e-06, -1.1680060684852263e-07, 9.883856155277148e-05, 0.00047306026131592124, 0.0001509522706191473, -0.0025838396453348195, -0.008797865375358697, -0.019029849679726582, -0.03364840374300433, -0.05289226592485294, -0.07686917231736198, -0.10544002411122483, -0.13812130957106417, -0.17427077726771, -0.21299565258640007, -0.2532369127684518, -0.2936390193614835, -0.3327625863869391, -0.3693627638487038, -0.4022968442648761, -0.4305998899701199, -0.45346303391231035, -0.4703068173092647, -0.48068506880063744, -0.4842972639293289, -0.48101566669328666, -0.4708432502558817, -0.45389413746373364, -0.4303552867903823, -0.40048555664137814, -0.3646007930004082, -0.32307979043412854, -0.2763409156171978, -0.22481920753996726, -0.16902634944124734, -0.10956453716543219, -0.047089177515906855, 0.017704096818260684, 0.08412572047506855, 0.15146851053243093, 0.21896795268811192, 0.28582887766205567, 0.3512665511206088, 0.41453853583281586, 0.4749374940627854, 0.5317828516750267, 0.5844250611603737, 0.6322574880844486, 0.6747570512961785, 0.7114905591069608, 0.7421053882128378, 0.7663249873746597, 0.7839634651498555, 0.7949222008493574, 0.7991689008317258, 0.7967443457869325, 0.7877711205506452, 0.772456099565242, 0.7510721979922368, 0.7239266402017881, 0.6913777648936001, 0.6538401228085898, 0.6117614984492961, 0.5655958069829192, 0.5157909368097842, 0.4628080166729427, 0.4071249898682585, 0.3492195178551094, 0.2895571350555982, 0.22858873481657926, 0.1667625984713428, 0.10452471262581628, 0.04230635709056019, -0.01946920091571283, -0.08037508592513637, -0.13999665522419835, -0.19794301644185266, -0.2538441289746489, -0.3073223794004434, -0.357986393458782, -0.4054637319708048, -0.449425231634215, -0.48958571607035106, -0.5256624397184011, -0.557376755284622, -0.5845055081589364, -0.6069026146406982, -0.6244643093749875, -0.6371074058612541, -0.6447989222591619, -0.647588605068814, -0.6455938457811526, -0.6389526785190067, -0.6278219482543946, -0.6124103735198833, -0.5929904924093268, -0.5698619075983047, -0.5433219597303944, -0.5136887937433835, -0.4813436421031856, -0.4466854531131687, -0.4100787227560284, -0.3718737703026728, -0.33244270075684473, -0.29219099545629723, -0.2515258894374884, -0.21081118390987869, -0.17037975138541162, -0.13056982298498698, -0.09173803013066595, -0.054223903389052586, -0.018334689468779197, 0.015644994048549965, 0.04743786961269297, 0.07677891002095155, 0.10345743975570265, 0.12730890240698495, 0.14816220290819238, 0.16583063059021386, 0.18018031157244807, 0.19113682557389006, 0.19861119576466024, 0.20250911294819818, 0.20277995178138308, 0.19944492129766989, 0.19257134837912898, 0.18224036412401265, 0.16857155477929697, 0.15173685134399587, 0.13197108548558767, 0.10955913944479206, 0.0848162321355519, 0.0581040814150266, 0.02981889046840064, 0.00039092667022094796, -0.029706802911195707, -0.05998602867977382, -0.08994665887523384, -0.11907082453772261, -0.1468623125856731, -0.1728963496667445, -0.19680265054211382, -0.21822332838342948, -0.23683190525139736, -0.2523682614086099, -0.26464285520401076, -0.273502573372921, -0.2788262944539917, -0.28054639653894076, -0.2786490142603263, -0.2731668616540026, -0.2641563365948126, -0.25171623819181377, -0.23600073386434697, -0.21717660959846039, -0.19542796862148507, -0.1709696677893098, -0.14403191251398476, -0.11484630830081735, -0.08366777845901838, -0.050794539438907466, -0.016557616991282303, 0.01868786949740625, 0.05455966088501246, 0.09065215030281559, 0.12655950033615854, 0.16189723777653484, 0.196295097721369, 0.2293809917052205, 0.26079005728328, 0.2901849366791501, 0.3172457616907003, 0.34167615914335114, 0.3632085517369758, 0.38160809520962535, 0.3966818777477756, 0.4082898492595874, 0.41634519633583345, 0.4208098562521051, 0.4216788705391291, 0.41900823815259725, 0.4129191330439846, 0.40355968952239407, 0.39109153155398524, 0.37570355634881186, 0.35773271252978933, 0.3376008460310772, 0.3156689548966051, 0.292189687044381, 0.2673251096525093, 0.24124392046651155, 0.21412385875695572, 0.18610863726859928, 0.15742068648912091, 0.1283824440509218, 0.09915673346718853, 0.06977190473316161, 0.04017468632720052, 0.010311999293557167, -0.01977462736982724, -0.04996961017506475, -0.08005030447796839, -0.10985308786987759, -0.13936237918034738, -0.16856623164073115, -0.19743738711313052, -0.2258980614822478, -0.25372444062710997, -0.28056348462719577, -0.30599456093440747, -0.32961043662434086, -0.3509729908368079, -0.3696349128091706, -0.38519036640998683, -0.3972663253473487, -0.4055148789331469, -0.4096006140725249, -0.40923926618890427, -0.4042195850401586, -0.3944126169674449, -0.37976154834896564, -0.3602696361588505, -0.33603472190598593, -0.307244355247301, -0.27414746776723503, -0.23704078963532568, -0.19625950660285324, -0.15219702015475012, -0.10527184651197552, -0.05590752292229828, -0.00452616048361669, 0.04845406312692063, 0.10257321545631211, 0.15732597234799023, 0.21220474460556366, 0.26670372627252537, 0.32029239304819335, 0.3724267688025515, 0.42258103366028343, 0.47026156452875434, 0.5150125481295327, 0.5563890491484988, 0.5939787122363702, 0.6274441230560667, 0.6565085801199988, 0.680933536828475, 0.7005119137537333, 0.7150887071083872, 0.7245585478791841, 0.7288504766130833, 0.7279542493947111, 0.7219288034925684, 0.7108605785021512, 0.6948521125004212, 0.6740213802012739, 0.6485012073450536, 0.6184653597934455, 0.5841165037042874, 0.5456765951361916, 0.5034153695924957, 0.4576564381376929, 0.40876627621821604, 0.35713804308274494, 0.30319352628201696, 0.2473946231409872, 0.19025044643534522, 0.13229964240467704, 0.07407185841500728, 0.016080209591805082, -0.04114994169907282, -0.09708713360795994, -0.15122291710555671, -0.20307777098407004, -0.2521793148465476, -0.2980848291740788, -0.34041487247741964, -0.3788479355279791, -0.4131230467126075, -0.4430120224172903, -0.4683250146963054, -0.48892814428500087, -0.5047524489336989, -0.5157673697897428, -0.5219676409644313, -0.5233901971981928, -0.5201114299553867, -0.5122716162712254, -0.5000675764176161, -0.48371266280426006, -0.4634459401359017, -0.4395307842781722, -0.41226357221933846, -0.38199703951366365, -0.3491126334275306, -0.31399281522441197, -0.277019021863421, -0.23859658381655144, -0.1991785902978654, -0.1592428932022257, -0.11926159209030203, -0.0797124763090245, -0.04108207793296251, -0.0038432490267232416, 0.03155884750018186, 0.06472781740427619, 0.09530912103953622, 0.12295536489284924, 0.1473684710142347, 0.16833537454936698, 0.18572639110445494, 0.19947247658768305, 0.20953305696349875, 0.21593859334336377, 0.2188111852973454, 0.21832418465574677, 0.21467189726346694, 0.2080722306114882, 0.19880460484403803, 0.18718225911416203, 0.17349369293517625, 0.15798545164130426, 0.1409134350703991, 0.12257125156503773, 0.10324530283212105, 0.08318601645144096, 0.06262175901206234, 0.04178478209991021, 0.020920777942454755, 0.0002637727854090527, -0.019969570537970924, -0.0395644432888686, -0.05830468173217875, -0.07598681496936062, -0.09242912701233211, -0.10745718797671597, -0.12089119570892984, -0.13254409018206845, -0.1422497367061224, -0.14986107053882347, -0.15522107987333478, -0.15817557609381183, -0.15860068177616604, -0.15640304756001244, -0.15149770143866334, -0.14377467006911143, -0.1331490978728752, -0.11959789736441351, -0.10312021508833981, -0.08373256062691134, -0.06148730362084258, -0.03648248057566507, -0.008866643354001735, 0.0211801247545651, 0.05343418443797997, 0.08760033623589877, 0.12334976535437285, 0.1603438055863003, 0.1982217856487085, 0.23659780497496016, 0.27505888511275306, 0.313191296033159, 0.3505949805504271, 0.38686657121814827, 0.42157153534329656, 0.45425131288299203, 0.4844633450769737, 0.5117931323261637, 0.5358453288314562, 0.5562081233078101, 0.5724716737382827, 0.584242491060241, 0.5911590133650348, 0.5928919015205278, 0.5891390046841399, 0.5796727989399275, 0.564348886462317, 0.5430818966876207, 0.5158451271395734, 0.4826947194055867, 0.44382497762756135, 0.3995531646547103, 0.35027734012961115, 0.296450613413463, 0.23858269287971645, 0.17727756563692576, 0.1131842861637684, 0.04696048314412413, -0.020718177892086936, -0.08915889605697087, -0.15765594984916476, -0.2255339422141317, -0.29215675337588026, -0.3569163189741752, -0.41923502202524454, -0.478581729068137, -0.5344790069390221, -0.586475277971904, -0.6341475039678314, -0.6771059836744231, -0.7150034865402307, -0.747525691004685, -0.7743756020502028, -0.7953035224438136, -0.8100927264610386, -0.8185637978256805, -0.8206014568302226, -0.8161457265446749, -0.8052091354044456, -0.7878726826749279, -0.7642661074943728, -0.7345818834620927, -0.6990870316766302, -0.6581262617750377, -0.6121229686132563, -0.5615577567242148, -0.5069722705991162, -0.448962957204758, -0.38814873751492407, -0.3251547264681979, -0.2606159672178488, -0.19518020766584782, -0.1294851598328316, -0.06412891024385571, 0.00033746489287580367, 0.06338811621766437, 0.12451843696326013, 0.18326533145248372, 0.23921672338852296, 0.291986502533244, 0.34119962426894584, 0.386515582952908, 0.4276485018829801, 0.46435314888338786, 0.496398799741187, 0.5235459737174418, 0.5455720891964613, 0.5623181600476251, 0.5736940985754039, 0.5796493349572268, 0.5801682974594136, 0.5752968149905425, 0.5651688171670265, 0.5499932409056113, 0.5300315680112049, 0.5055960970785705, 0.4770634030327607, 0.4448835356367186, 0.4095249736182274, 0.37145898917070747, 0.33120483550304985, 0.28930579529406, 0.24629835088559798, 0.20269756666056504, 0.15900601561449137, 0.11571838290354644, 0.07329381603641685, 0.03213629017711475, -0.007393625012544425, -0.044939210700764926, -0.08016282650817479, -0.11278217398095937, -0.14258717585992445, -0.16940111598022634, -0.1930558608502484, -0.21343650058606967, -0.23049675816693502, -0.24423759437201464, -0.2546919404448244, -0.26190690390697857, -0.2659891473782337, -0.2670991051178321, -0.2653931426339194, -0.2610261437128463, -0.2541769510937954, -0.2450608532445281, -0.23389262681107753, -0.22086704163876908, -0.206166446335699, -0.18997306322677898, -0.17247952899051355, -0.15384827859964018, -0.13419756246037517, -0.11365049673102604, -0.09235555993458383, -0.07046230150385169, -0.04810939388931477, -0.025461069671205983, -0.002708995469467495, 0.019945076472169154, 0.04230884731731133, 0.0641762609997013, 0.08529814614527452, 0.10539940653476278, 0.12418219809196361, 0.14133254640146142, 0.1565338140552578, 0.16947036156924536, 0.17984928218865895, 0.1873736702071392, 0.19173480741112234, 0.19266191118085613, 0.18994893562327175, 0.1834526413027173, 0.17307436510012036, 0.15873406934678683, 0.14038842341936913, 0.11805720903890518, 0.09182254859994844, 0.061818466477343986, 0.028224899419049335, -0.008713059989840302, -0.04866906719971198, -0.09126099519474684, -0.1360840764335445, -0.1827111814248967, -0.23067891152534134, -0.27946152595728435, -0.32849495691386654, -0.37720647200426816, -0.42499607361947284, -0.47122361152307335, -0.5152421974664656, -0.5564278196656458, -0.594175208476353, -0.6278784322458626, -0.6569514664086391, -0.6808768173206001, -0.6992062120900526, -0.7115432226995929, -0.717543215923359, -0.7169332763298584, -0.7095204918346734, -0.6951663855041672, -0.6738092956798383, -0.6454902194121611, -0.6103404549810753, -0.5685829383916472, -0.5205112156756888, -0.4665004622498492, -0.40701052675790417, -0.34254795499886737, -0.2736644974115489, -0.20096336158114247, -0.12511669978481765, -0.046869385472898414, 0.03300088675205842, 0.11368898779702924, 0.1943522646873552, 0.2741213360408254, 0.35211643483645033, 0.42747003465562444, 0.4993606518589163, 0.56700212654531, 0.6296273019215337, 0.6865267568585554, 0.7370726869192418, 0.7806975918623481, 0.8168989878021753, 0.8452404983066191, 0.8654029227232135, 0.8771886089296882, 0.8804826276860094, 0.8752602686474201, 0.8616037982796941, 0.839721479356539, 0.8098953614480541, 0.7724557450695186, 0.7278271896746621, 0.6765255331773099, 0.6191447174307332, 0.5563392320504802, 0.4888166828209216, 0.41733954727521094, 0.3427320227799817, 0.2658770656522559, 0.1876563068834275, 0.10893659948573159, 0.030578290807106917, -0.04657414915293542, -0.12170556858235447, -0.1940533334734319, -0.26290226906268493, -0.32758353699760845, -0.3874875364268129, -0.44210307361139056, -0.49101788536655033, -0.5338908054036655, -0.5704944059898848, -0.600720485143904, -0.624534028934592, -0.641950297588399, -0.6530560878625584, -0.6580417874255484, -0.6571694940362548, -0.6507307807665157, -0.6390429523996555, -0.6224449726983096, -0.6013187980938373, -0.5760993953754356, -0.5472428794799065, -0.5152228093379457, -0.48051552248514817, -0.44356767108977924, -0.4048372521076437, -0.3648078161232275, -0.3239501209137956, -0.28274005681693815, -0.24166283529384638, -0.20118809564560378, -0.16175132389669888, -0.12377736901209072, -0.08768010652518626, -0.053821433111907444, -0.0224807395755207, 0.006121495702869857, 0.031790680027996704, 0.05439065901246376, 0.07387161384606789, 0.09025482418976659, 0.10360577642258122, 0.11401543730256267, 0.1216214104971949, 0.12658290890101043, 0.1290617977766217, 0.1292570806063228, 0.12740005783861613, 0.12369987523565915, 0.11831007852476835, 0.11136501127241549, 0.10302193160262121, 0.09344693853435716, 0.08278535099447856, 0.07114718172434062, 0.0586481473894436, 0.045454368734015135, 0.03174847758923953, 0.017704744927194038, 0.0034887515651107065, -0.010725451615060166, -0.024743662549803105, -0.03837568817804904, -0.0514435499436922, -0.06378457837631532, -0.07526052945025591, -0.08574990086210224, -0.09515070839869187, -0.10337864641445046, -0.11034652011460427, -0.11594511151209727, -0.120090850561951, -0.12272518433080105, -0.12379267293790486, -0.12322490884370593, -0.12092535046581912, -0.11682896952704169, -0.11088821408872832, -0.10303293860555598, -0.09320214572909981, -0.08137445925358261, -0.06757593595310617, -0.05185073231937044, -0.034242445178802046, -0.014843362991891557, 0.006190562455258116, 0.028666154757654883, 0.05237336652657846, 0.07706948665277386, 0.10248464293326405, 0.12834304845922684, 0.1543934807271714, 0.1804085116588136, 0.20613603436902056, 0.2313136869112532, 0.25570965201227436, 0.2791264556325074, 0.30138894784389425, 0.3223305941609471, 0.34179378314235476, 0.3596294342405182, 0.37570214577125927, 0.389888226580538, 0.40206544835947566, 0.41210529495085624, 0.41985864408521034, 0.4251556724143158, 0.42781163506747816, 0.4276243973797447, 0.4243984575592099, 0.41796460261985524, 0.4081649283175899, 0.39485377698005153, 0.37791299730820493, 0.35725435377548076, 0.33282691515741036, 0.3046196082715787, 0.2726785872630778, 0.2371046725996182, 0.19801684117962387, 0.15558295386297047, 0.1100376729463412, 0.06168947244745817, 0.01091259242037039, -0.04190562708625236, -0.09636357486536994, -0.15200635419608152, -0.2083387551977451, -0.26485111104567605, -0.32102657271310814, -0.37633501714572604, -0.4302070026435338, -0.4820319401663865, -0.5312028715159286, -0.577115170537769, -0.6191671258319322, -0.6567772998412262, -0.6894056761447686, -0.7165853058178744, -0.7378907761020992, -0.7529277716868026, -0.7613762678226397, -0.7630020970096485, -0.757668139981298, -0.745314150360161, -0.7259473933765811, -0.6996874879501076, -0.6667695445055363, -0.6275085823189801, -0.582280990082902, -0.5315607462390375, -0.4759130827684715, -0.4159528263496696, -0.35233766015297385, -0.2857611097754601, -0.21695115839549023, -0.14666404067657343, -0.07568283037805504, -0.0048387332500639535, 0.06501263002487398, 0.133039592143051, 0.19847137802563275, 0.260582467435336, 0.31869266637340815, 0.3721939658312739, 0.4205592669302418, 0.46335146024094487, 0.5002195970182176, 0.5309151540864034, 0.5553036122135108, 0.573338028216344, 0.58507094738511, 0.5906501891049953, 0.5902852380152545, 0.5842748565185756, 0.5729927339454026, 0.5568809190524867, 0.5364084966186032, 0.512024762580204, 0.4841951137273122, 0.4534197051593557, 0.4202026065579786, 0.3850229012400509], "fs": 44100, "acceleration_nodes": [0, 50, 120], "acceleration": [[0.0004885608213953674, -0.0001315007684752345, 0.04074063524603844, 0.22140513360500336, 0.6068165898323059, 1.2373323440551758, 2.1491942405700684, 3.3670222759246826, 4.895969867706299, 6.714195251464844, 8.855363845825195, 11.270997047424316, 13.928860664367676, 16.827041625976562, 19.982234954833984, 23.2835693359375, 26.847551345825195, 30.553510665893555, 34.43290710449219, 38.46562957763672, 42.55353927612305, 46.73968505859375, 50.83119201660156, 54.95549774169922, 58.99727249145508, 62.73861312866211, 66.32262420654297, 69.62427520751953, 72.51728057861328, 74.97465515136719, 76.97569274902344, 78.31635284423828, 78.99539184570312, 79.02340698242188, 78.3318099975586, 76.95804595947266, 74.86368560791016, 72.11310577392578, 68.62037658691406, 64.5624008178711, 59.9630241394043, 54.79278564453125, 49.18388748168945, 43.22993469238281, 36.86909866333008, 30.346830368041992, 23.560997009277344, 16.756364822387695, 9.927167892456055, 3.0353198051452637, -3.645200729370117, -10.195711135864258, -16.525041580200195, -22.721193313598633, -28.548587799072266, -34.05852127075195, -39.05228805541992, -43.6680793762207, -47.761470794677734, -51.3800048828125, -54.61319351196289, -57.384254455566406, -59.622154235839844, -61.48582077026367, -62.94097900390625, -63.7236442565918, -64.5206527709961, -64.85590362548828, -64.7188720703125, -64.35958862304688, -63.53139114379883, -62.75942611694336, -61.543190002441406, -60.15763473510742, -58.427433013916016, -56.88987350463867, -54.95692443847656, -52.906715393066406, -50.75529479980469, -48.78219223022461, -46.737178802490234, -44.89556884765625, -43.26553726196289, -42.1091194152832, -40.91261291503906, -40.18632888793945, -39.67069625854492, -39.60589599609375, -39.734622955322266, -40.28683853149414, -41.00979995727539, -41.66585159301758, -42.70805740356445, -43.89447784423828, -45.00014877319336, -46.24167251586914, -47.40311050415039, -48.488887786865234, -49.70258331298828, -50.644287109375, -51.7117919921875, -52.51952362060547, -53.26298904418945, -53.76067352294922, -54.020687103271484, -54.221309661865234, -53.96330642700195, -53.37435531616211, -52.55658721923828, -51.35182571411133, -49.77468490600586, -48.154541015625, -46.18711853027344, -44.19318389892578, -42.1761474609375, -40.2806396484375, -38.361148834228516, -36.503387451171875, -34.73833465576172, -33.17403030395508, -31.552581787109375, -30.00942611694336, -28.421737670898438, -26.67473602294922, -24.543752670288086, -22.301637649536133, -19.512527465820312, -16.466201782226562, -13.108220100402832, -9.405001640319824, -5.467735290527344, -1.4199566841125488, 2.634145975112915, 6.459184646606445, 10.026938438415527, 13.314122200012207, 16.106056213378906, 18.494508743286133, 20.38164520263672, 21.89480972290039, 23.0931396484375, 23.933012008666992, 24.75143051147461, 25.34325408935547, 26.126178741455078, 26.883512496948242, 27.94701385498047, 29.060781478881836, 30.41084861755371, 32.03253173828125, 33.59872817993164, 35.471649169921875, 37.10901641845703, 38.8768196105957, 40.58586883544922, 42.43097686767578, 43.8587532043457, 45.44100570678711, 46.95798873901367, 48.61870574951172, 49.998130798339844, 51.520328521728516, 52.97043991088867, 54.34650421142578, 55.6470947265625, 56.65086364746094, 57.35670471191406, 57.986175537109375, 57.881072998046875, 57.488643646240234, 56.59817123413086, 55.00461196899414, 52.94255447387695, 50.21430587768555, 47.05635452270508, 43.48910140991211, 39.53376007080078, 35.418907165527344, 31.159324645996094, 26.768836975097656, 22.661304473876953, 18.438016891479492, 14.304966926574707, 10.457551002502441, 6.6979875564575195, 3.2148523330688477, -0.18688255548477173, -3.5093042850494385, -6.7550048828125, -9.746292114257812, -12.67043685913086, -15.529661178588867, -18.325542449951172, -21.058961868286133, -23.38846778869629, -25.662015914916992, -27.710603713989258, -29.371919631958008, -30.653846740722656, -31.56412124633789, -31.95205307006836, -31.676633834838867, -30.916828155517578, -29.69261932373047, -27.72633171081543, -25.05695152282715, -21.871166229248047, -18.05967140197754, -13.675803184509277, -8.801260948181152, -3.544238805770874, 1.7813854217529297, 7.301084041595459, 12.842830657958984, 18.083616256713867, 23.150028228759766, 27.873062133789062, 31.93977928161621, 35.638031005859375, 38.51985168457031, 40.883522033691406, 42.445125579833984, 43.22197723388672, 43.37806701660156, 42.79373550415039, 41.63644027709961, 39.7938232421875, 37.43247985839844, 34.649009704589844, 31.517337799072266, 28.08041763305664, 24.3397216796875, 20.433622360229492, 16.501657485961914, 12.408496856689453, 8.43137264251709, 4.581759929656982, 0.7032026052474976, -2.84844970703125, -6.199669361114502, -9.483592987060547, -12.397252082824707, -15.221334457397461, -17.797317504882812, -20.26519012451172, -22.46330451965332, -24.6898136138916, -26.627140045166016, -28.420303344726562, -30.06005859375, -31.376771926879883, -32.680240631103516, -33.640567779541016, -34.409908294677734, -34.81864929199219, -34.69770812988281, -34.369815826416016, -33.347286224365234, -31.961177825927734, -30.058460235595703, -27.752952575683594, -24.921266555786133, -21.631149291992188, -18.212295532226562, -14.333695411682129, -10.515436172485352, -6.605999946594238, -2.6249029636383057, 1.230776071548462, 4.760885715484619, 8.295639038085938, 11.286391258239746, 14.070305824279785, 16.459821701049805, 18.622926712036133, 20.208986282348633, 21.738731384277344, 22.700658798217773, 23.445180892944336, 23.979143142700195, 24.147737503051758, 23.806568145751953, 23.29738998413086, 22.319135665893555, 20.89716148376465, 19.13054656982422, 17.02692413330078, 14.606864929199219, 11.873712539672852, 8.982905387878418, 5.937356472015381, 2.89172625541687, -0.15212684869766235, -2.8886873722076416, -5.621269226074219, -7.893444061279297, -10.008731842041016, -11.815056800842285, -13.312338829040527, -14.802647590637207, -16.133678436279297, -17.45500373840332, -18.76470184326172, -20.21040916442871, -21.788482666015625, -23.346031188964844, -25.02818489074707, -26.68242645263672, -28.012056350708008, -29.164573669433594, -29.70525550842285, -29.787616729736328, -29.134523391723633, -27.621501922607422, -25.412471771240234, -22.25177764892578, -18.44794464111328, -14.164474487304688, -9.291211128234863, -4.257670879364014, 0.7883673906326294, 5.758544921875, 10.349836349487305, 14.554865837097168, 18.10743522644043, 21.003238677978516, 23.238370895385742, 24.67835235595703, 25.714908599853516, 26.084728240966797, 25.919748306274414, 25.35284423828125, 24.38681411743164, 23.155601501464844, 21.53321647644043, 19.78384780883789, 17.65332794189453, 15.404842376708984, 12.786293029785156, 10.058995246887207, 7.226256370544434, 4.164880752563477, 1.2562792301177979, -1.62546706199646, -4.230710029602051, -6.438499927520752, -8.376797676086426, -9.680880546569824, -10.359607696533203, -10.54345989227295, -10.119776725769043, -9.099275588989258, -7.73159122467041, -6.024744510650635, -3.9875433444976807, -1.978701114654541, 0.0, 1.8921979665756226, 3.602200984954834, 5.123223304748535, 6.322330951690674, 7.182374477386475, 7.940431118011475, 8.328351974487305, 8.721844673156738, 8.984097480773926, 9.106496810913086, 9.218616485595703, 9.317910194396973, 9.261580467224121, 8.903002738952637, 8.520757675170898, 7.831113815307617, 6.835590362548828, 5.540642738342285, 3.8164584636688232, 1.82323157787323, -0.555045485496521, -3.2854695320129395, -6.194398880004883, -9.113438606262207, -12.142218589782715, -14.9905424118042, -17.763687133789062, -20.199932098388672, -22.416866302490234, -24.077899932861328, -25.28058624267578, -26.108619689941406, -26.385974884033203, -26.22394371032715, -25.521020889282227, -24.285051345825195, -22.526859283447266, -20.363798141479492, -17.709545135498047, -14.687400817871094, -11.221245765686035, -7.3419413566589355, -3.276613473892212, 0.9637627005577087, 5.299471855163574, 9.7018461227417, 14.034221649169922, 18.159788131713867, 21.945947647094727, 25.352712631225586, 28.350387573242188, 30.68329620361328, 32.527957916259766, 33.68800354003906, 34.25083923339844, 34.212318420410156, 33.664794921875, 32.702877044677734, 31.237403869628906, 29.46305274963379, 27.41059112548828, 25.18864631652832, 22.840476989746094, 20.393951416015625, 17.981298446655273, 15.53419017791748, 13.081748962402344, 10.756421089172363, 8.484307289123535, 6.2154130935668945, 4.122919082641602, 1.9053571224212646, -0.21152332425117493, -2.425333261489868, -4.616821765899658, -6.878047943115234, -9.26228141784668, -11.614723205566406, -14.05435562133789, -16.573820114135742, -19.04872703552246, -21.460071563720703, -23.787185668945312, -25.888940811157227, -27.618576049804688, -29.070436477661133, -30.101764678955078, -30.449254989624023, -30.346866607666016, -29.66984748840332, -28.42537498474121, -26.509254455566406, -24.071399688720703, -21.029598236083984, -17.66558837890625, -13.79536247253418, -9.703981399536133, -5.332981109619141, -0.847461998462677, 3.703105926513672, 8.272326469421387, 12.818154335021973, 17.117883682250977, 21.251008987426758, 25.117795944213867, 28.721471786499023, 31.911710739135742, 34.72176742553711, 36.96656036376953, 38.70873260498047, 39.92015838623047, 40.40194320678711, 40.18559265136719, 39.26093292236328, 37.68177032470703, 35.442237854003906, 32.540000915527344, 29.068553924560547, 25.119047164916992, 20.680442810058594, 15.971977233886719, 10.930011749267578, 5.738205909729004, 0.4388842284679413, -4.829118251800537, -10.098794937133789, -15.121315956115723, -20.125669479370117, -24.756908416748047, -29.15955924987793, -33.18832015991211, -36.878910064697266, -40.064327239990234, -42.7888298034668, -44.858863830566406, -46.32109832763672, -47.10417938232422, -47.13747787475586, -46.353057861328125, -44.6876335144043, -42.5302734375, -39.558189392089844, -35.89387893676758, -31.680015563964844, -27.07757568359375, -21.93590545654297, -16.596771240234375, -11.086339950561523, -5.600923538208008, -0.1712253838777542, 5.1746320724487305, 10.0645751953125, 14.646403312683105, 18.901350021362305, 22.6395320892334, 25.673667907714844, 28.34793472290039, 30.130416870117188, 31.371793746948242, 31.896446228027344, 31.882389068603516, 30.979900360107422, 29.54420280456543, 27.578039169311523, 25.259708404541016, 22.591690063476562, 19.57701873779297, 16.393949508666992, 13.393949508666992, 10.404966354370117, 7.430386066436768, 4.81847620010376, 2.569110155105591, 0.5110472440719604, -1.185150146484375, -2.6902823448181152, -3.837575674057007, -4.79747200012207, -5.5718841552734375, -6.336678504943848, -7.244879722595215, -7.971745014190674, -8.836326599121094, -9.676139831542969, -10.643893241882324, -11.427522659301758, -12.33167552947998, -13.05154037475586, -13.737373352050781, -14.243051528930664, -14.573269844055176, -14.73320198059082, -14.864896774291992, -14.69913387298584, -14.381888389587402, -13.920963287353516, -13.449583053588867, -12.72502613067627, -12.003425598144531, -11.05761432647705, -10.029511451721191, -8.812705993652344, -7.337121963500977, -5.731472015380859, -3.902637004852295, -1.8744899034500122, 0.32606759667396545, 2.7231667041778564, 5.135063648223877, 7.442101001739502, 9.741494178771973, 11.800821304321289, 13.498095512390137, 14.823893547058105, 15.772913932800293, 16.238569259643555, 16.229917526245117, 15.866003036499023, 15.062932968139648, 13.849690437316895, 12.454447746276855, 10.90168285369873, 9.30846118927002, 7.564108848571777, 5.984614372253418, 4.342735767364502, 2.8241169452667236, 1.3421932458877563, -0.1951567530632019, -1.885519027709961, -3.629810094833374, -5.525740146636963, -7.571603298187256, -9.763873100280762, -12.09727668762207, -14.350691795349121, -16.618722915649414, -18.673784255981445, -20.39376449584961, -21.876680374145508, -22.786718368530273, -23.338544845581055, -23.204015731811523, -22.607213973999023, -21.338695526123047, -19.628555297851562, -17.489145278930664, -15.040392875671387, -12.336044311523438, -9.417252540588379, -6.478453159332275, -3.528859853744507, -0.5794724225997925, 2.35722017288208, 5.2676005363464355, 8.137325286865234, 10.951729774475098, 13.696208000183105, 16.3565731048584, 18.79238510131836, 20.860258102416992, 22.673263549804688, 23.832305908203125, 24.454208374023438, 24.401212692260742, 23.53806495666504, 21.994773864746094, 19.512910842895508, 16.36113166809082, 12.549013137817383, 8.218710899353027, 3.51285719871521, -1.1670711040496826, -5.812489032745361, -10.029587745666504, -13.699426651000977, -16.558340072631836, -18.664731979370117, -19.833194732666016, -20.15564727783203, -19.604721069335938, -18.30438995361328, -16.256208419799805, -13.612255096435547, -10.535155296325684, -7.058107852935791, -3.3915932178497314, 0.27277249097824097, 4.1115946769714355, 7.84632682800293, 11.469062805175781, 14.832703590393066, 17.927324295043945, 20.882591247558594, 23.447599411010742, 25.695438385009766, 27.54807472229004, 28.97954750061035, 29.96501350402832, 30.329612731933594, 30.20081901550293, 29.406583786010742, 28.085704803466797, 26.229930877685547, 23.994028091430664, 21.223777770996094, 18.244237899780273, 15.06924819946289, 11.55704116821289, 7.886031150817871, 4.234741687774658, 0.6227548718452454, -2.9311776161193848, -6.409660816192627, -9.797184944152832, -12.931965827941895, -15.810352325439453, -18.288515090942383, -20.660823822021484, -22.510284423828125, -24.1356258392334, -25.282331466674805, -26.111709594726562, -26.518091201782227, -26.531517028808594, -26.056209564208984, -25.246185302734375, -24.12327003479004, -22.7111873626709, -21.042430877685547, -18.987897872924805, -16.78097915649414, -14.293609619140625, -11.64525318145752, -8.711992263793945, -5.496026992797852, -2.128755569458008, 1.3790807723999023, 5.01373815536499, 8.633644104003906, 12.221258163452148, 15.510204315185547, 18.61043357849121, 21.277061462402344, 23.44202423095703, 24.950698852539062, 25.927522659301758, 26.378963470458984, 26.075443267822266, 25.275224685668945, 24.11365509033203, 22.584590911865234, 20.902629852294922, 19.2055721282959, 17.574047088623047, 16.13697624206543, 14.90261459350586, 13.876867294311523, 13.102228164672852, 12.396991729736328, 11.66109848022461, 10.897021293640137, 9.742330551147461, 8.440048217773438, 6.625814437866211, 4.425277233123779, 1.844955563545227, -1.2292524576187134, -4.6632771492004395, -8.199790000915527, -11.949853897094727, -15.658783912658691, -19.197980880737305, -22.563121795654297, -25.51312828063965, -28.170194625854492, -30.41961669921875, -32.268070220947266, -33.954349517822266, -35.13751220703125, -36.1698112487793, -36.82917022705078, -37.124515533447266, -37.12535095214844, -36.601409912109375, -35.48724365234375, -33.68697738647461, -31.000551223754883, -27.56068992614746, -23.283554077148438, -18.08879280090332, -12.111459732055664, -5.376780986785889, 1.778268814086914, 9.236512184143066, 16.680356979370117, 23.905763626098633, 30.61456298828125, 36.517887115478516, 41.43474197387695, 45.38642883300781, 48.0969352722168, 49.785133361816406, 50.275047302246094, 49.876712799072266, 48.6055793762207, 46.66736602783203, 44.07591247558594, 41.033355712890625, 37.554447174072266, 33.7482795715332, 29.545120239257812, 25.06080436706543, 20.324230194091797, 15.199331283569336, 9.734943389892578, 4.067846298217773, -1.9047768115997314, -7.954606056213379, -14.09016227722168, -19.943944931030273, -25.53567123413086, -30.54029655456543, -34.88056564331055, -38.37128448486328, -40.86997604370117, -42.463157653808594, -43.02389144897461, -42.74170684814453, -41.66910934448242, -39.94955825805664, -37.8189697265625, -35.28440856933594, -32.51680374145508, -29.74601173400879, -26.918502807617188, -24.102371215820312, -21.451435089111328, -18.761402130126953, -16.165895462036133, -13.614703178405762, -10.977402687072754, -8.198748588562012, -5.4992876052856445, -2.6257848739624023, 0.09765211492776871, 2.8329555988311768, 5.295045852661133, 7.543675899505615, 9.341259956359863, 10.651153564453125, 11.442368507385254, 11.68952465057373, 11.482121467590332, 10.918863296508789, 9.99471378326416, 8.931068420410156, 7.731585502624512, 6.625446319580078, 5.506229400634766, 4.7158942222595215, 4.1451616287231445, 3.7950613498687744, 3.6646761894226074, 3.7511911392211914, 4.049956798553467, 4.554567813873291, 4.935115814208984, 5.511632442474365, 5.960592746734619, 6.284745216369629, 6.589078426361084, 6.773129940032959, 6.841805458068848, 6.896509647369385, 6.843615531921387, 6.689639091491699, 6.531023979187012, 6.193941593170166, 5.692671775817871, 5.105160713195801, 4.255185127258301, 3.397144317626953, 2.2830488681793213, 1.091873288154602, -0.0832313522696495, -1.398898720741272, -2.597487211227417, -3.6751832962036133, -4.551665306091309, -5.273731708526611, -5.759990692138672, -5.995429039001465, -5.900839805603027, -5.450048923492432, -4.879798412322998, -4.006698131561279, -2.9975321292877197, -1.8502628803253174, -0.658428430557251, 0.572808563709259, 1.837783932685852, 3.0326311588287354, 4.148282527923584, 5.214396953582764, 6.022169589996338, 6.767848014831543, 7.329851150512695, 7.571573257446289, 7.459599018096924, 7.082231044769287, 6.4166259765625, 5.310495376586914, 3.863481283187866, 2.053579092025757, 0.0, -2.162731170654297, -4.285050868988037, -6.505378246307373, -8.511605262756348, -10.2802734375, -11.626906394958496, -12.519412994384766, -12.927019119262695, -12.820398330688477], [-2.326479989278596e-05, 1.8049126083496958e-05, -0.0006885741604492068, -0.004222986288368702, -0.01135752908885479, -0.029305240139365196, -0.055534735321998596, -0.09376517683267593, -0.14578570425510406, -0.21288910508155823, -0.29588326811790466, -0.42134568095207214, -0.541854977607727, -0.715243399143219, -0.9142199158668518, -1.186423897743225, -1.4362887144088745, -1.8259069919586182, -2.25138258934021, -2.778073310852051, -3.4133856296539307, -4.161752700805664, -5.108241558074951, -6.2607526779174805, -7.621228218078613, -9.27759838104248, -11.225268363952637, -13.451220512390137, -16.125553131103516, -19.221818923950195, -22.797012329101562, -26.79991340637207, -31.448402404785156, -36.47233963012695, -42.14395523071289, -48.42897415161133, -55.270790100097656, -62.67465591430664, -70.61515808105469, -79.19041442871094, -88.22398376464844, -97.80442810058594, -107.88723754882812, -118.42709350585938, -129.36276245117188, -140.71937561035156, -152.3245849609375, -164.30999755859375, -176.4175567626953, -188.83367919921875, -201.29608154296875, -213.7774658203125, -226.28451538085938, -238.57254028320312, -250.60877990722656, -262.220458984375, -273.205322265625, -283.67193603515625, -293.0571594238281, -301.45465087890625, -308.4156188964844, -314.0596923828125, -318.1283264160156, -320.35003662109375, -320.9071044921875, -319.0902404785156, -315.59539794921875, -309.7301025390625, -302.02142333984375, -292.0348205566406, -280.1039733886719, -266.597900390625, -251.12750244140625, -234.35321044921875, -215.89329528808594, -196.744140625, -176.2320556640625, -155.2812042236328, -133.7613525390625, -112.06719970703125, -90.06096649169922, -68.6484603881836, -47.41073989868164, -26.703344345092773, -7.115237236022949, 11.804734230041504, 29.257139205932617, 45.47343826293945, 60.203975677490234, 72.99027252197266, 84.11669158935547, 93.17583465576172, 100.02676391601562, 104.55267333984375, 107.09170532226562, 107.33158874511719, 105.4095458984375, 101.4599380493164, 95.41299438476562, 87.6009292602539, 78.33379364013672, 67.7126693725586, 56.01797103881836, 43.33218002319336, 30.265661239624023, 16.868850708007812, 3.5636146068573, -9.871746063232422, -22.900833129882812, -35.476497650146484, -47.54833984375, -59.06333541870117, -69.81419372558594, -80.05364990234375, -89.28009796142578, -97.884765625, -105.52728271484375, -112.28759765625, -118.03138732910156, -122.77002716064453, -126.2103271484375, -128.5935821533203, -129.53269958496094, -129.1748809814453, -127.31315612792969, -124.0159912109375, -119.14118957519531, -112.92699432373047, -105.40298461914062, -96.42710876464844, -86.36996459960938, -75.15628051757812, -63.219505310058594, -50.462379455566406, -37.400482177734375, -23.945547103881836, -10.606427192687988, 2.4207470417022705, 15.04813003540039, 26.853891372680664, 37.52635192871094, 46.967132568359375, 54.962738037109375, 61.213706970214844, 65.52279663085938, 67.79320526123047, 68.17842864990234, 66.3099594116211, 62.49262237548828, 56.619667053222656, 48.96835708618164, 39.515052795410156, 28.63233757019043, 16.359058380126953, 3.1370718479156494, -10.757149696350098, -25.178173065185547, -39.86415481567383, -54.50480651855469, -68.78804016113281, -82.61493682861328, -95.89707946777344, -108.12073516845703, -119.43082427978516, -129.3300018310547, -138.21046447753906, -145.59779357910156, -151.24911499023438, -155.59664916992188, -158.2034912109375, -159.0867462158203, -158.27413940429688, -156.0184783935547, -151.9304656982422, -146.4921875, -139.75624084472656, -131.5700225830078, -122.4127197265625, -112.33756256103516, -101.80270385742188, -90.84576416015625, -79.69981384277344, -68.58545684814453, -58.097503662109375, -48.22550964355469, -39.33466339111328, -31.396268844604492, -24.93453025817871, -19.71731185913086, -15.882845878601074, -13.38426399230957, -12.176666259765625, -12.042498588562012, -12.773468971252441, -13.998936653137207, -15.532273292541504, -16.693134307861328, -17.32613182067871, -16.794395446777344, -14.815812110900879, -10.968615531921387, -4.861265659332275, 3.8646035194396973, 15.074714660644531, 29.225051879882812, 45.98687744140625, 65.6135025024414, 87.69776153564453, 112.1706771850586, 138.7665557861328, 167.02224731445312, 196.69464111328125, 227.52561950683594, 258.7979736328125, 290.5334777832031, 322.3081359863281, 353.7046813964844, 384.3172607421875, 414.05181884765625, 442.68426513671875, 469.7224426269531, 495.14483642578125, 518.3765258789062, 539.1680297851562, 557.4447021484375, 572.60546875, 584.3771362304688, 592.3860473632812, 596.477294921875, 596.3840942382812, 591.7334594726562, 582.512451171875, 568.7130126953125, 550.330322265625, 527.4990234375, 500.4917907714844, 469.6998291015625, 435.4230651855469, 398.2132568359375, 358.4273986816406, 316.89788818359375, 273.92022705078125, 230.1107635498047, 186.11770629882812, 142.31344604492188, 99.23857116699219, 56.98843765258789, 16.2895450592041, -22.894132614135742, -60.1201171875, -95.09082794189453, -127.82321166992188, -158.0136260986328, -185.35902404785156, -209.88812255859375, -231.15516662597656, -249.2218780517578, -263.68756103515625, -274.3469543457031, -281.3536682128906, -284.3064270019531, -283.1514892578125, -278.2098693847656, -269.1372375488281, -256.47076416015625, -240.13119506835938, -220.60562133789062, -198.26766967773438, -173.5394287109375, -146.705810546875, -118.43348693847656, -89.2330322265625, -59.27116394042969, -29.417552947998047, 0.17404603958129883, 29.01803207397461, 56.82881164550781, 83.17928314208984, 108.18276977539062, 131.3064727783203, 152.55496215820312, 171.6324920654297, 188.59793090820312, 203.36947631835938, 215.7324676513672, 225.77081298828125, 233.66412353515625, 239.1874237060547, 242.4977569580078, 243.90870666503906, 243.43161010742188, 241.383056640625, 237.9263916015625, 233.3755340576172, 228.0412139892578, 222.23080444335938, 216.0976104736328, 210.095947265625, 204.22337341308594, 198.77841186523438, 193.7549285888672, 189.1460418701172, 184.94491577148438, 181.14515686035156, 177.591064453125, 174.27737426757812, 170.90252685546875, 167.31797790527344, 163.52587890625, 159.3843994140625, 154.90203857421875, 149.9453887939453, 144.53009033203125, 138.67410278320312, 132.39756774902344, 125.5834732055664, 118.39726257324219, 111.00044250488281, 103.14591217041016, 95.26538848876953, 87.2459945678711, 79.31086730957031, 71.66279602050781, 64.64458465576172, 58.5211296081543, 53.68952941894531, 50.67802810668945, 49.75050735473633, 51.42981719970703, 55.83966827392578, 63.62120056152344, 74.62100219726562, 88.94014739990234, 106.41168975830078, 126.86437225341797, 149.60726928710938, 174.2138671875, 199.87782287597656, 225.80593872070312, 251.34754943847656, 275.6119384765625, 297.9783020019531, 317.9642639160156, 334.97125244140625, 348.78472900390625, 359.3178405761719, 366.6080627441406, 370.8144836425781, 372.0927429199219, 370.7177429199219, 367.0828552246094, 361.0975646972656, 353.1553039550781, 343.2923278808594, 331.4352111816406, 317.6397399902344, 301.6659240722656, 283.47491455078125, 262.72052001953125, 239.57168579101562, 213.96751403808594, 185.8596954345703, 155.60684204101562, 123.36371612548828, 89.8614273071289, 55.37958526611328, 20.795433044433594, -13.483945846557617, -46.450477600097656, -77.74114227294922, -106.55339813232422, -132.35577392578125, -155.05606079101562, -174.16514587402344, -189.5183868408203, -201.28285217285156, -209.53138732910156, -214.24755859375, -215.8827362060547, -214.78404235839844, -211.3261260986328, -205.90101623535156, -198.7821502685547, -190.37771606445312, -181.08645629882812, -171.17288208007812, -160.88919067382812, -150.4951171875, -140.32040405273438, -130.32748413085938, -120.82124328613281, -111.68083190917969, -103.21147155761719, -95.2979507446289, -87.93458557128906, -81.11785888671875, -74.6441879272461, -68.41980743408203, -62.3575553894043, -56.28065490722656, -49.922908782958984, -43.070255279541016, -35.637474060058594, -27.400148391723633, -18.06520652770996, -7.564348220825195, 4.1011738777160645, 17.12251091003418, 31.340124130249023, 46.91170883178711, 63.61198043823242, 81.39278411865234, 100.09922790527344, 119.46781921386719, 139.3142547607422, 159.5338897705078, 179.9185791015625, 200.26513671875, 220.4724884033203, 240.56021118164062, 260.3227844238281, 279.67523193359375, 298.7502746582031, 317.4919738769531, 335.7465515136719, 353.5128173828125, 370.7125244140625, 387.34295654296875, 403.0888671875, 417.86431884765625, 431.3929748535156, 443.5296936035156, 453.951171875, 462.3772888183594, 468.6755676269531, 472.4678955078125, 473.69769287109375, 472.1118469238281, 467.4815673828125, 459.8463439941406, 449.0597839355469, 435.022705078125, 417.68988037109375, 397.0740661621094, 373.2489318847656, 346.3474426269531, 316.4375, 283.6437683105469, 248.50914001464844, 211.1337127685547, 172.13552856445312, 131.9108123779297, 91.3230209350586, 50.75070571899414, 10.992470741271973, -27.224716186523438, -63.158531188964844, -96.47724914550781, -126.4467544555664, -152.7584991455078, -175.1190643310547, -193.5192413330078, -207.85711669921875, -218.27609252929688, -225.1932830810547, -228.86866760253906, -229.6340789794922, -228.00685119628906, -224.32826232910156, -218.9557647705078, -212.16250610351562, -204.19277954101562, -195.27976989746094, -185.4648895263672, -174.88784790039062, -163.45069885253906, -151.2859649658203, -138.39796447753906, -124.84502410888672, -110.71361541748047, -96.20342254638672, -81.5483169555664, -66.82193756103516, -52.38804244995117, -38.64128494262695, -25.792762756347656, -14.154091835021973, -3.82102370262146, 4.751270294189453, 11.714715957641602, 16.727643966674805, 20.048654556274414, 21.478498458862305, 21.3503360748291, 19.652067184448242, 16.675796508789062, 12.62280559539795, 7.584070205688477, 1.9779093265533447, -4.1953887939453125, -10.612805366516113, -17.24583625793457, -23.736614227294922, -30.20612144470215, -36.45054244995117, -42.43124008178711, -48.11433410644531, -53.298709869384766, -58.131595611572266, -62.247215270996094, -65.9797134399414, -68.79609680175781, -70.8663558959961, -72.01432037353516, -71.89012145996094, -70.4984130859375, -67.66980743408203, -63.41248321533203, -57.38322448730469, -49.94377136230469, -40.752262115478516, -29.99590301513672, -17.863197326660156, -4.7194600105285645, 9.243396759033203, 23.830793380737305, 38.32495880126953, 52.53110122680664, 66.08195495605469, 78.6147689819336, 89.77397155761719, 99.38330841064453, 107.44315338134766, 113.79246520996094, 118.61335754394531, 122.08981323242188, 124.29638671875, 125.57791900634766, 126.11300659179688, 126.23323059082031, 126.1019515991211, 125.72135162353516, 125.24564361572266, 124.36946105957031, 122.9514389038086, 120.56737518310547, 117.10953521728516, 111.77556610107422, 104.5223388671875, 94.50801849365234, 81.78063201904297, 66.02593994140625, 47.126930236816406, 25.280235290527344, 0.7271443605422974, -26.12510108947754, -54.604095458984375, -84.18028259277344, -113.88728332519531, -143.01744079589844, -170.7079620361328, -196.24688720703125, -218.98452758789062, -238.24671936035156, -253.69021606445312, -265.1659240722656, -272.40277099609375, -275.607666015625, -274.80615234375, -270.3973388671875, -262.8265686035156, -252.4739227294922, -239.8638458251953, -225.648193359375, -210.37908935546875, -194.40281677246094, -178.56207275390625, -163.06637573242188, -148.6763916015625, -135.7027587890625, -124.496337890625, -115.61186218261719, -109.12278747558594, -105.33956146240234, -104.49933624267578, -106.55558776855469, -111.74181365966797, -119.78373718261719, -130.77584838867188, -144.37905883789062, -160.52647399902344, -179.0184783935547, -199.4103546142578, -221.6549072265625, -245.2562713623047, -270.1355895996094, -295.9914855957031, -322.41015625, -349.4207763671875, -376.5179748535156, -403.6534423828125, -430.47552490234375, -456.77056884765625, -482.1390380859375, -506.4314880371094, -529.1626586914062, -550.1427612304688, -568.7634887695312, -584.8800659179688, -598.0155029296875, -607.8092041015625, -613.9149169921875, -616.1290893554688, -614.03515625, -607.4890747070312, -596.5115966796875, -580.7863159179688, -560.5394287109375, -535.6558837890625, -506.4364929199219, -472.95477294921875, -435.69866943359375, -394.91644287109375, -351.130859375, -304.87286376953125, -256.6734313964844, -207.18943786621094, -157.19915771484375, -107.3373031616211, -58.35355758666992, -11.108312606811523, 33.81771469116211, 75.47608184814453, 113.28007507324219, 146.65145874023438, 174.99082946777344, 198.015625, 215.24066162109375, 226.53402709960938, 231.8576202392578, 231.40834045410156, 225.20603942871094, 213.77923583984375, 197.52639770507812, 177.0293426513672, 153.08837890625, 126.09185028076172, 97.0033950805664, 66.4006118774414, 35.02082061767578, 3.341214656829834, -28.250118255615234, -59.2861213684082, -89.64055633544922, -119.1709976196289, -147.87733459472656, -175.9117431640625, -203.2806396484375, -229.9904327392578, -256.51611328125, -282.5607604980469, -308.29168701171875, -333.5617370605469, -358.06298828125, -381.6485290527344, -403.8631591796875, -424.42620849609375, -442.60894775390625, -458.34759521484375, -470.9939880371094, -480.72454833984375, -487.4476013183594, -490.9687805175781, -491.87762451171875, -490.621826171875, -487.51055908203125, -483.4153137207031, -478.8944396972656, -474.6122131347656, -471.1916809082031, -469.0870056152344, -468.59710693359375, -470.1284484863281, -473.45745849609375, -478.5048522949219, -485.1061706542969, -492.56219482421875, -500.6231994628906, -508.6964111328125, -516.048583984375, -522.4258422851562, -527.2000122070312, -530.1167602539062, -530.8114624023438, -529.19091796875, -525.4397583007812, -519.2698974609375, -510.92340087890625, -500.6694030761719, -488.6779479980469, -474.9826965332031, -459.8809509277344, -443.6087341308594, -426.28253173828125, -408.0268859863281, -388.9687194824219, -369.35211181640625, -349.0569763183594, -328.3634033203125, -307.3636474609375, -286.1749572753906, -265.0453186035156, -244.2062225341797, -223.658447265625, -203.88320922851562, -184.84765625, -166.882568359375, -150.0314483642578, -134.6387481689453, -120.56134033203125, -108.00814819335938, -96.93321228027344, -87.15338134765625, -78.71810150146484, -71.54249572753906, -65.40859985351562, -60.09099578857422, -55.48146438598633, -51.34624481201172, -47.57235336303711, -43.806060791015625, -40.0579948425293, -36.33718490600586, -32.4162712097168, -28.656841278076172, -24.830562591552734, -21.40298080444336, -18.481754302978516, -16.28118896484375, -15.338871002197266, -15.625894546508789, -17.692523956298828, -21.711139678955078, -27.761581420898438, -35.9126091003418, -46.22383117675781, -58.53226852416992, -72.56924438476562, -88.07368469238281, -104.37281036376953, -121.23609161376953, -137.8212127685547, -153.72698974609375, -168.36196899414062, -181.15306091308594, -191.54286193847656, -199.38597106933594, -204.13983154296875, -205.76438903808594, -204.02142333984375, -199.06593322753906, -190.8577117919922, -179.4594268798828, -165.1306915283203, -148.04266357421875, -128.3797607421875, -106.43479919433594, -82.42543029785156, -56.59095764160156, -29.281570434570312, -0.8648608922958374, 28.360763549804688, 57.910430908203125, 87.3773422241211, 116.1913833618164, 143.7235107421875, 169.38172912597656, 192.47720336914062, 212.54074096679688, 228.80421447753906, 240.84201049804688, 248.2372283935547, 250.5994415283203, 247.8028564453125, 239.85818481445312, 226.84188842773438, 209.0518035888672, 186.85317993164062, 160.8301544189453, 131.61643981933594, 99.7984848022461, 66.10224914550781, 31.335472106933594, -3.8598103523254395, -38.85874938964844, -72.98095703125, -105.76331329345703, -136.79534912109375, -165.59927368164062, -192.0032501220703, -215.6299591064453, -236.51513671875, -254.48141479492188, -269.4238586425781, -281.3367919921875, -290.3295593261719, -296.3255310058594, -299.497802734375, -299.7472839355469, -297.2170104980469, -292.0832824707031, -284.33160400390625, -274.0772705078125, -261.45703125, -246.62637329101562, -229.7570037841797, -211.03468322753906, -190.54458618164062, -168.49522399902344, -145.21690368652344, -120.93431091308594, -95.76570129394531, -70.05330657958984, -43.91904830932617, -17.8093318939209, 8.161456108093262, 33.985836029052734, 59.344478607177734, 84.23883819580078, 108.56929016113281, 132.53553771972656, 156.1293182373047, 179.52772521972656, 202.8885040283203, 226.4386444091797, 250.3748321533203, 275.03253173828125, 300.3536071777344, 326.62799072265625, 353.7276611328125, 381.5228271484375, 409.9564208984375, 438.5459899902344, 466.90301513671875, 494.41546630859375, 520.5977172851562, 544.7088012695312, 566.0209350585938, 584.0472412109375, 598.24658203125, 608.0358276367188, 613.3008422851562, 613.8960571289062, 609.8193969726562, 601.3231201171875, 588.84619140625, 573.0208740234375, 554.3832397460938, 533.6343994140625, 511.7320251464844, 489.2010498046875, 466.788818359375, 445.12139892578125, 424.4407653808594, 405.3630065917969, 387.7563171386719, 371.677490234375, 357.16424560546875, 343.85565185546875, 331.5821533203125, 320.0028076171875, 308.72137451171875, 297.7081604003906, 286.63397216796875, 275.42535400390625, 263.9973449707031, 252.40777587890625, 240.8747100830078, 229.6313934326172, 218.5955352783203, 208.1753692626953, 198.288818359375], [-0.00023632138618268073, 3.248842403991148e-05, -0.022722946479916573, -0.12427645176649094, -0.3407258689403534, -0.7033257484436035, -1.232871174812317, -1.9434963464736938, -2.8549699783325195, -3.97938871383667, -5.325899124145508, -6.925869464874268, -8.765300750732422, -10.841584205627441, -13.190887451171875, -15.769551277160645, -18.6717529296875, -21.789155960083008, -25.16250991821289, -28.84922218322754, -32.76850128173828, -36.895538330078125, -41.36838150024414, -45.999141693115234, -50.927738189697266, -56.03302001953125, -61.36479949951172, -66.877197265625, -72.61270141601562, -78.41736602783203, -84.51110076904297, -90.62726593017578, -96.96590423583984, -103.33830261230469, -109.73672485351562, -116.31759643554688, -122.86199951171875, -129.40618896484375, -135.96409606933594, -142.52743530273438, -149.06558227539062, -155.59478759765625, -162.0952911376953, -168.5360565185547, -175.00341796875, -181.48153686523438, -187.94004821777344, -194.4877166748047, -200.98309326171875, -207.59747314453125, -214.35804748535156, -221.20260620117188, -228.21444702148438, -235.30799865722656, -242.59266662597656, -250.01365661621094, -257.4558410644531, -265.2494812011719, -273.0514221191406, -280.78887939453125, -288.7548522949219, -296.657958984375, -304.56805419921875, -312.33013916015625, -319.98828125, -327.3507385253906, -334.4441223144531, -341.2949523925781, -347.9266662597656, -354.1049499511719, -359.8397216796875, -365.145751953125, -370.0414733886719, -374.5466613769531, -378.59930419921875, -381.89959716796875, -384.9626770019531, -387.54168701171875, -389.3883056640625, -391.048583984375, -392.0146484375, -392.5751953125, -392.4987487792969, -392.0769958496094, -391.08392333984375, -389.55621337890625, -387.5331115722656, -384.8128662109375, -381.6932067871094, -377.9853515625, -373.7483825683594, -369.0404052734375, -363.9176025390625, -358.4347839355469, -352.4290466308594, -346.3883056640625, -340.1380920410156, -333.7176208496094, -327.5579833984375, -321.4641418457031, -315.8249816894531, -310.4278869628906, -305.6193542480469, -301.5272521972656, -298.0815734863281, -295.20489501953125, -293.06488037109375, -291.6347961425781, -290.62640380859375, -290.1297302246094, -289.9017639160156, -289.8622741699219, -289.92706298828125, -289.71087646484375, -289.29071044921875, -288.3023376464844, -286.8212585449219, -284.6206359863281, -281.5910339355469, -277.9304504394531, -273.3695068359375, -268.1693420410156, -262.33514404296875, -256.00335693359375, -249.18557739257812, -241.8960723876953, -234.49465942382812, -226.96656799316406, -219.29408264160156, -211.66421508789062, -203.92628479003906, -196.25830078125, -188.4427490234375, -180.5543975830078, -172.26280212402344, -163.64447021484375, -154.48065185546875, -144.5670166015625, -133.81407165527344, -122.10567474365234, -109.280029296875, -95.28260040283203, -80.07815551757812, -63.68305206298828, -46.031837463378906, -27.467937469482422, -7.984860897064209, 12.202317237854004, 32.750144958496094, 53.329837799072266, 73.80996704101562, 93.7333755493164, 112.64564514160156, 130.2950897216797, 146.26597595214844, 160.3612060546875, 172.18621826171875, 181.9705810546875, 189.2993927001953, 194.26251220703125, 197.2029266357422, 198.288330078125, 197.71270751953125, 195.6912384033203, 193.11521911621094, 190.0118408203125, 187.0710906982422, 184.5415496826172, 182.88658142089844, 182.33993530273438, 182.9060516357422, 184.58070373535156, 187.5679168701172, 191.41522216796875, 195.89071655273438, 200.55653381347656, 204.78070068359375, 208.3708953857422, 210.5304412841797, 211.31158447265625, 209.76748657226562, 206.18858337402344, 200.26953125, 192.1090850830078, 181.80252075195312, 169.6307373046875, 156.2338104248047, 142.0344696044922, 127.61482238769531, 113.52625274658203, 100.64966583251953, 89.2955551147461, 80.10879516601562, 73.53375244140625, 70.1654052734375, 69.89522552490234, 73.2828598022461, 80.03022766113281, 90.33101654052734, 104.03276824951172, 120.81373596191406, 140.50625610351562, 162.777099609375, 187.13963317871094, 213.2679443359375, 240.6941375732422, 268.8270568847656, 297.33441162109375, 325.30950927734375, 352.4905090332031, 378.1998291015625, 401.9992980957031, 423.1648864746094, 441.4349670410156, 456.2750549316406, 467.4812316894531, 474.73638916015625, 477.9082336425781, 477.1947326660156, 472.3827819824219, 464.0279541015625, 452.1202392578125, 437.38916015625, 420.1272277832031, 400.76898193359375, 379.8802795410156, 358.0067138671875, 335.5311584472656, 313.0592041015625, 290.9919738769531, 269.490234375, 249.1403045654297, 230.25538635253906, 213.00889587402344, 197.5708465576172, 184.3844451904297, 173.551513671875, 165.25262451171875, 159.7980194091797, 157.1544189453125, 157.57354736328125, 161.01669311523438, 167.43467712402344, 176.46493530273438, 188.02439880371094, 201.70816040039062, 216.92872619628906, 233.222412109375, 249.94078063964844, 266.2462463378906, 281.91070556640625, 295.89300537109375, 307.7788391113281, 317.3177795410156, 323.7809143066406, 327.2662048339844, 327.572021484375, 324.6886901855469, 319.12506103515625, 310.92730712890625, 300.60321044921875, 288.5620422363281, 275.21478271484375, 261.0428771972656, 246.5736846923828, 232.3739013671875, 218.51951599121094, 205.61740112304688, 193.9351348876953, 183.73492431640625, 175.26744079589844, 168.94317626953125, 164.7984619140625, 163.19737243652344, 164.29946899414062, 168.40821838378906, 175.2792205810547, 185.33224487304688, 198.11178588867188, 213.8278045654297, 232.01406860351562, 252.3817901611328, 274.3386535644531, 297.328369140625, 320.6792297363281, 343.5906982421875, 365.6227722167969, 385.86468505859375, 404.01068115234375, 419.45599365234375, 431.75238037109375, 441.0643615722656, 447.1007995605469, 450.0270690917969, 450.00537109375, 447.49755859375, 442.6589050292969, 435.9453125, 427.65887451171875, 417.9482116699219, 407.1115417480469, 395.1451721191406, 382.0493469238281, 367.8294372558594, 352.4958801269531, 335.7664794921875, 317.81353759765625, 298.3714599609375, 277.7740173339844, 255.7733154296875, 233.005126953125, 209.66452026367188, 186.23243713378906, 162.89602661132812, 140.54080200195312, 119.18608093261719, 99.39862823486328, 81.30953216552734, 65.17313385009766, 50.95899963378906, 38.36721420288086, 27.483964920043945, 17.817440032958984, 9.047618865966797, 0.9184930324554443, -6.826052665710449, -14.441925048828125, -22.052995681762695, -29.257266998291016, -36.17781448364258, -42.283226013183594, -47.17720031738281, -50.468971252441406, -51.384620666503906, -49.68206024169922, -44.8692512512207, -36.72407531738281, -25.16124153137207, -10.101171493530273, 8.149059295654297, 29.031801223754883, 52.25032424926758, 77.00991821289062, 102.52945709228516, 128.04119873046875, 152.9143829345703, 176.5286865234375, 198.1516876220703, 217.30799865722656, 233.5315704345703, 246.72979736328125, 256.57562255859375, 262.8741149902344, 265.6794128417969, 264.93707275390625, 260.6065673828125, 252.7093048095703, 241.37350463867188, 226.45835876464844, 208.34442138671875, 186.8186798095703, 162.2964630126953, 135.1154022216797, 105.40570831298828, 73.87138366699219, 40.76366424560547, 6.9318108558654785, -27.105484008789062, -60.63595199584961, -93.17710876464844, -123.9354476928711, -152.66357421875, -179.11892700195312, -202.7891845703125, -223.75672912597656, -241.9917449951172, -257.63665771484375, -271.0009460449219, -282.13970947265625, -291.40606689453125, -299.0264587402344, -304.9763488769531, -309.3846435546875, -312.0283508300781, -312.8612976074219, -311.3070373535156, -307.35382080078125, -300.4500427246094, -290.3106689453125, -276.6788330078125, -259.37286376953125, -238.33680725097656, -213.85499572753906, -186.13206481933594, -155.50537109375, -122.54191589355469, -87.92320251464844, -52.2334098815918, -16.054378509521484, 19.948795318603516, 55.512733459472656, 90.1873779296875, 123.7225570678711, 156.0949249267578, 187.27281188964844, 217.31158447265625, 246.44326782226562, 274.7087097167969, 302.23516845703125, 329.0400390625, 354.8532409667969, 379.48797607421875, 402.6526794433594, 423.7637939453125, 442.32977294921875, 457.6837463378906, 469.3769226074219, 476.8883361816406, 479.829345703125, 477.885498046875, 471.2602233886719, 459.8945617675781, 444.21612548828125, 424.7415466308594, 402.1648254394531, 377.3945617675781, 351.0128173828125, 324.1248474121094, 297.341552734375, 271.595947265625, 247.38400268554688, 225.1750030517578, 205.5077362060547, 188.6137237548828, 174.54347229003906, 163.49168395996094, 155.32357788085938, 150.22259521484375, 148.13250732421875, 149.08206176757812, 152.82826232910156, 159.6811981201172, 169.55728149414062, 182.3236846923828, 198.1657257080078, 216.85108947753906, 238.0944061279297, 261.8062438964844, 287.4862060546875, 314.8443298339844, 343.207763671875, 372.13958740234375, 400.86358642578125, 428.9828796386719, 455.8066101074219, 480.8287658691406, 503.8281555175781, 524.445556640625, 542.60302734375, 558.3779296875, 571.8045654296875, 583.147216796875, 592.691650390625, 600.7379150390625, 607.5926513671875, 613.48291015625, 618.5613403320312, 623.1405639648438, 627.1376342773438, 630.513916015625, 633.2903442382812, 635.2872314453125, 636.380859375, 636.3670043945312, 635.2193603515625, 632.8584594726562, 629.2339477539062, 624.5353393554688, 618.8005981445312, 612.30029296875, 605.2213745117188, 597.8084106445312, 590.44921875, 583.2925415039062, 576.6004028320312, 570.4447631835938, 564.7802124023438, 559.8345336914062, 555.4461669921875, 551.4116821289062, 547.6485595703125, 544.0703735351562, 540.4559326171875, 536.694091796875, 532.667236328125, 528.3966064453125, 523.9189453125, 519.2857666015625, 514.5607299804688, 509.8174133300781, 505.1378479003906, 500.93511962890625, 496.8319091796875, 493.4219665527344, 490.4865417480469, 487.7895202636719, 485.76641845703125, 484.1730651855469, 482.7525329589844, 481.7620544433594, 480.9343566894531, 480.5196533203125, 480.2382507324219, 480.3302307128906, 480.67706298828125, 481.680419921875, 483.2047119140625, 485.4577941894531, 488.46148681640625, 492.0516662597656, 496.40472412109375, 501.33502197265625, 506.6493225097656, 512.1488037109375, 517.455810546875, 522.364013671875, 526.6647338867188, 529.9766235351562, 532.26953125, 533.1759643554688, 532.6815795898438, 530.947265625, 527.9678955078125, 523.7456665039062, 518.7886962890625, 513.2688598632812, 507.2592468261719, 500.8627014160156, 494.2481994628906, 487.4180603027344, 480.21746826171875, 472.4963073730469, 463.8050537109375, 453.7154235839844, 441.97259521484375, 428.05072021484375, 411.4659423828125, 392.06341552734375, 369.58099365234375, 344.07464599609375, 315.36322021484375, 283.9769287109375, 250.19419860839844, 214.81973266601562, 178.2715606689453, 141.68748474121094, 105.67430877685547, 70.99542236328125, 38.52734375, 8.804546356201172, -17.53156089782715, -40.14141082763672, -58.881038665771484, -73.58258819580078, -84.41816711425781, -91.55709075927734, -95.43399810791016, -96.42984771728516, -95.06217193603516, -91.87413787841797, -87.3203125, -82.08352661132812, -76.62906646728516, -71.51634216308594, -67.2759780883789, -64.29547119140625, -63.21394348144531, -64.2997055053711, -67.94755554199219, -74.65020751953125, -84.5400390625, -97.9300537109375, -114.94390106201172, -135.65174865722656, -160.0086212158203, -187.7407989501953, -218.6209716796875, -252.1709747314453, -288.0548095703125, -325.6826477050781, -364.4129333496094, -403.5609130859375, -442.72955322265625, -481.40338134765625, -518.9574584960938, -555.2120971679688, -590.0140991210938, -623.01953125, -654.3558349609375, -684.0806274414062, -712.4002685546875, -739.3422241210938, -765.0798950195312, -789.9264526367188, -813.9000854492188, -837.0274047851562, -859.3790893554688, -880.9578857421875, -901.4529418945312, -921.013427734375, -939.3521728515625, -956.4286499023438, -972.2282104492188, -986.7631225585938, -1000.0722045898438, -1012.3460083007812, -1023.6771240234375, -1034.4384765625, -1044.902587890625, -1054.968017578125, -1065.1888427734375, -1075.3497314453125, -1085.6279296875, -1095.9420166015625, -1105.949951171875, -1115.4365234375, -1123.9210205078125, -1131.181640625, -1136.8646240234375, -1140.358154296875, -1141.7020263671875, -1140.544189453125, -1137.0523681640625, -1131.486572265625, -1124.016845703125, -1115.24609375, -1105.8369140625, -1096.630615234375, -1088.0789794921875, -1081.3134765625, -1076.7431640625, -1074.996337890625, -1076.7686767578125, -1082.3253173828125, -1091.7718505859375, -1105.0596923828125, -1122.300048828125, -1143.0372314453125, -1166.9317626953125, -1193.626220703125, -1222.745361328125, -1253.5989990234375, -1285.9202880859375, -1318.955078125, -1352.5760498046875, -1386.1815185546875, -1419.42578125, -1451.9388427734375, -1483.3299560546875, -1513.3514404296875, -1541.4403076171875, -1567.3468017578125, -1590.674560546875, -1611.04541015625, -1628.27197265625, -1642.2080078125, -1652.5966796875, -1659.3914794921875, -1662.599853515625, -1662.4405517578125, -1659.033935546875, -1652.5589599609375, -1643.548828125, -1631.979736328125, -1618.173583984375, -1602.487548828125, -1585.02978515625, -1565.679443359375, -1544.4962158203125, -1521.4334716796875, -1496.3411865234375, -1468.961669921875, -1439.29541015625, -1407.0784912109375, -1372.506103515625, -1335.513916015625, -1296.4072265625, -1255.75732421875, -1214.1099853515625, -1172.19921875, -1130.828369140625, -1090.9903564453125, -1053.363525390625, -1019.0477905273438, -988.675537109375, -962.888427734375, -942.1932983398438, -926.6956176757812, -916.715087890625, -911.7880249023438, -911.7158813476562, -916.0798950195312, -924.276611328125, -935.4601440429688, -949.2796630859375, -964.7914428710938, -981.5609741210938, -998.943603515625, -1016.5430908203125, -1034.0863037109375, -1051.177001953125, -1067.7130126953125, -1083.20947265625, -1097.9053955078125, -1111.33544921875, -1123.3685302734375, -1133.847900390625, -1142.427001953125, -1149.1514892578125, -1153.491943359375, -1155.4302978515625, -1154.48681640625, -1150.695068359375, -1143.8724365234375, -1133.8624267578125, -1120.7818603515625, -1104.646240234375, -1085.4857177734375, -1063.58349609375, -1038.8642578125, -1011.8599853515625, -982.3746948242188, -950.921630859375, -917.4039916992188, -882.1880493164062, -845.278564453125, -806.90380859375, -767.2762451171875, -726.5901489257812, -685.0250854492188, -642.9889526367188, -600.88232421875, -558.9791870117188, -517.923583984375, -478.1070861816406, -440.10296630859375, -404.1205749511719, -370.7667541503906, -340.2895202636719, -312.8021545410156, -288.6025695800781, -267.65130615234375, -249.69053649902344, -234.76686096191406, -222.41175842285156, -212.46771240234375, -204.57778930664062, -198.29310607910156, -193.37130737304688, -189.67160034179688, -186.76356506347656, -184.61111450195312, -182.98570251464844, -181.85157775878906, -181.07620239257812, -180.62086486816406, -180.3529510498047, -180.14163208007812, -179.85926818847656, -179.38259887695312, -178.42079162597656, -176.87266540527344, -174.48013305664062, -171.01226806640625, -166.3505096435547, -160.40501403808594, -153.1930389404297, -144.75677490234375, -135.16415405273438, -124.6412582397461, -113.23546600341797, -101.2943115234375, -88.98745727539062, -76.43368530273438, -63.84437942504883, -51.21233367919922, -38.45172119140625, -25.631004333496094, -12.340927124023438, 1.4401799440383911, 16.137968063354492, 31.841936111450195, 49.00334548950195, 67.67534637451172, 88.00363159179688, 110.05491638183594, 133.80245971679688, 159.0234375, 185.5837860107422, 213.07212829589844, 241.29330444335938, 269.6778259277344, 298.13189697265625, 325.9852600097656, 353.1695861816406, 379.2226257324219, 404.1651916503906, 427.6280212402344, 449.4605407714844, 469.7457275390625, 488.3728942871094, 505.3558654785156, 520.724609375, 534.3011474609375, 546.1412963867188, 556.2006225585938, 564.5570678710938, 571.1846313476562, 576.177490234375, 579.5281982421875, 581.4619750976562, 582.0966186523438, 581.7708129882812, 580.7073974609375, 579.232421875, 577.7675170898438, 576.6089477539062, 576.032958984375, 576.4937133789062, 578.0069580078125, 580.7715454101562, 584.9581298828125, 590.3321533203125, 596.9357299804688, 604.5222778320312, 612.8512573242188, 621.8606567382812, 631.1680297851562, 640.7457275390625, 650.38330078125, 659.97021484375, 669.654296875, 679.2510375976562, 689.163330078125, 699.3734130859375, 710.0294189453125, 721.281982421875, 733.2848510742188, 746.1160278320312, 759.7991333007812, 774.173583984375, 789.1500244140625, 804.5567626953125, 820.1265258789062, 835.5847778320312, 850.5658569335938, 864.98681640625, 878.4019775390625, 890.744873046875, 901.8653564453125, 911.634521484375, 919.93994140625, 926.8949584960938, 932.4590454101562, 936.6661376953125, 939.4486694335938, 940.9751586914062, 941.0819702148438, 939.72119140625, 936.8490600585938, 932.2979736328125, 926.1641235351562, 918.1443481445312, 908.34716796875, 896.7577514648438, 883.5211791992188, 868.95751953125, 853.2626953125, 836.8142700195312, 820.186279296875, 804.1613159179688, 788.8818359375]], "n_steps": 9000}, "decimation": {"span": 32, "substeps": 10, "taps_sample": [[0, 0, -1.1973872194090508e-05], [15, 0, 0.09200010546324107], [15, 9, 0.01798034887405306], [16, 0, 0.007801113922670582], [31, 9, -6.039517271179016e-06], [7, 5, -0.0006442782744057674]], "normal_first3": [[0.0012926858735503896, -0.0010322205251655267, 0.999998631741074], [0.11161846192727448, 0.1307114628028889, 0.985117166863373], [-0.05807951290352242, 0.16849049849651318, 0.983990712403977]]}}
\ No newline at end of file
tests/gpu.check.tsmodified+18−3View file
@@ -25,9 +25,11 @@ async function test(name: string, fn: () => Promise<void>) {
2525 async function runBoth(cfg: any, nSamples: number, chunk: number) {
2626 const setup = await buildSetup(cfg);
2727 const device = await getDevice();
28- const cpu = new CpuSimulator(setup, 7), gpu = new GpuSimulator(device, setup, 4096, 7);
28+ const opts = { movieEvery: 7, dispEvery: 50, recordAcceleration: true };
29+ const cpu = new CpuSimulator(setup, opts), gpu = new GpuSimulator(device, setup, 4096, opts);
2930 const pc: number[] = [], pg: number[] = [];
30- let framesChecked = 0;
31+ let framesChecked = 0, accChecked = 0, dispChecked = 0;
32+ const relErr = (a: ArrayLike<number>, b: ArrayLike<number>) => { let num = 0, den = 0; for (let i = 0; i < a.length; i++) { num += (a[i] - b[i]) ** 2; den += a[i] ** 2; } return den > 0 ? Math.sqrt(num / den) : 0; };
3133 for (let done = 0; done < nSamples; done += chunk) {
3234 const n = Math.min(chunk, nSamples - done);
3335 const rc = await cpu.runChunk(n), rg = await gpu.runChunk(n);
@@ -39,10 +41,23 @@ async function runBoth(cfg: any, nSamples: number, chunk: number) {
3941 if (den > 0) { assert.ok(Math.sqrt(num / den) < 1e-2, `frame ${f} rel error ${Math.sqrt(num / den)}`); framesChecked++; }
4042 }
4143 for (let i = 0; i < rc.pressureFront.length; i++) { pc.push(rc.pressureFront[i] - rc.pressureBack[i]); pg.push(rg.pressureFront[i] - rg.pressureBack[i]); }
44+ // the acceleration record and the file displacement frames, sample by sample
45+ assert.equal(rg.acceleration!.length, rc.acceleration!.length);
46+ if (rc.acceleration!.length) { const err = relErr(rc.acceleration!, rg.acceleration!); assert.ok(err < 1e-2, `acceleration record rel error ${err}`); accChecked += rc.pressureFront.length; }
47+ assert.deepEqual(rg.dispSamples, rc.dispSamples);
48+ for (let f = 0; f < rc.dispFrames.length; f++) { const err = relErr(rc.dispFrames[f], rg.dispFrames[f]); assert.ok(err < 1e-2, `disp frame ${f} rel error ${err}`); dispChecked++; }
4249 }
4350 const dc = await cpu.diagnostics(), dg = await gpu.diagnostics();
44- gpu.dispose();
4551 assert.ok(framesChecked > 10, `only ${framesChecked} movie frames compared`);
52+ assert.ok(accChecked > 100 && dispChecked >= 5, `only ${accChecked} acceleration samples and ${dispChecked} displacement frames compared`);
53+ // the exported state restarts the GPU loop where it was: the next chunk matches a fresh run of the same length
54+ const st = await gpu.exportState();
55+ const gpu2 = new GpuSimulator(device, setup, 4096, opts);
56+ await gpu2.importState(st);
57+ const [a, b] = [await gpu.runChunk(50), await gpu2.runChunk(50)];
58+ assert.equal(a.firstSample, b.firstSample);
59+ assert.ok(relErr(a.pressureFront, b.pressureFront) < 1e-5, "resumed GPU run diverges from the continued one");
60+ gpu2.dispose(); gpu.dispose();
4661 return { setup, pc, pg, dc, dg };
4762 }
4863
tests/radiation.test.tsadded+34−0View file
@@ -0,0 +1,34 @@
1+import test from "node:test";
2+import assert from "node:assert/strict";
3+import { DECIMATION_SPAN, DELAY_TAPS, decimationKernel, decimationTaps, fractionalDelayTaps } from "../src/model/radiation.ts";
4+import { fixture } from "./helpers.ts";
5+
6+test("decimation taps equal the Python kernel", () => {
7+ const m = fixture.decimation.substeps, taps = decimationTaps(m);
8+ assert.equal(fixture.decimation.span, DECIMATION_SPAN);
9+ assert.equal(taps.length, DECIMATION_SPAN * m);
10+ for (const [w, k, v] of fixture.decimation.taps_sample as [number, number, number][]) assert.ok(Math.abs(taps[w * m + k] - v) < 1e-15, `tap ${w},${k}`);
11+ let sum = 0; for (const t of taps) sum += t;
12+ assert.ok(Math.abs(sum - 1) < 1e-12);
13+});
14+
15+test("decimation kernel is a linear-phase low-pass with an 80 dB stopband", () => {
16+ const m = 54, fs = 44100, h = decimationKernel(m), L = h.length;
17+ const H = (f: number) => { let re = 0, im = 0; for (let i = 0; i < L; i++) { const ph = (-2 * Math.PI * f * (i - L / 2)) / (fs * m); re += h[i] * Math.cos(ph); im += h[i] * Math.sin(ph); } return Math.hypot(re, im); };
18+ assert.ok(H(1000) > 0.999 && H(15000) > 0.99 && H(18000) > 0.95);
19+ assert.ok(H(22050) < 0.1 && H(24000) < 1e-3 && H(30000) < 1e-4);
20+ for (let i = 1; i < L; i++) assert.ok(Math.abs(h[i] - h[L - i]) < 1e-15); // symmetric about d = 0
21+});
22+
23+test("fractional-delay taps interpolate a band-limited signal", () => {
24+ const T = DELAY_TAPS, f = 0.2; // cycles per sample, well inside the band
25+ for (const fr of [0, 0.25, 0.5, 0.9]) {
26+ const taps = fractionalDelayTaps(fr);
27+ assert.equal(taps.length, T);
28+ // x(n) = cos(2 pi f n); read x(j - i0 - fr) with i0 = 20 at j = 100 from x(j - i0 - t + T/2 - 1)
29+ const j = 100, i0 = 20;
30+ let s = 0;
31+ for (let t = 0; t < T; t++) s += taps[t] * Math.cos(2 * Math.PI * f * (j - i0 - t + T / 2 - 1));
32+ assert.ok(Math.abs(s - Math.cos(2 * Math.PI * f * (j - i0 - fr))) < 2e-3, `fr ${fr}: ${s}`);
33+ }
34+});
↑↓ move↵openescclose