| .mochi | |
| solvers | |
| web | |
| .gitattributes | |
| .gitignore | |
| README.md |
Solutions to the cymbal2 challenges#
This repository holds solutions to the challenges defined in challenges/cymbal2. It is one of possibly several solution repositories registered with that challenge repository, which clones each of them, compares every solution against a common reference, and publishes the comparison at challenges/cymbal2/site. This repository's own site, at challenges/cymbal2-solutions/site, lists its submissions with audio players and animates the exported displacement fields as a 3D surface.
Layout#
solutions/<challenge-id>/<submission-id>.json one submission: metadata and one or more solutions
solutions/<challenge-id>/<submission-id>/*.wav the scored output files, referenced from the JSON
solutions/<challenge-id>/<submission-id>/*.h5 optional displacement fields for visualization (git LFS)
solvers/ source code of the submissions
web/ this repository's site (built by web/build.py)
The submission hermite-fem#
solvers/hermite-fem/fem_shell.py solves the shallow-shell model of MODEL.md directly in the displacements, with no modal reduction. The annulus is approximated by the square cells of a uniform Cartesian grid whose centers lie inside it (a staircase rim and hole). The three fields u, v, w are expanded in bicubic Hermite (Bogner-Fox-Schmit) elements, C1 across cells, four unknowns per node and field. The weak form is integrated with 3 x 3 Gauss points per cell exactly as written: Marguerre membrane strains, bending strains, stress resultants with the Kelvin-Voigt rates, and the assembled virtual work as the internal force, which a test confirms to be the exact gradient of the discrete strain energy; free edges are the natural boundary conditions and need no treatment. The mass is lumped by diagonal scaling of the consistent element mass. The equations are stepped with the explicit leapfrog scheme at 85 percent of the stability limit, which the in-plane block sets; the lumped masses of the in-plane derivative unknowns are scaled by 16, which halves the step count (14 substeps per output sample at 8 mm, about 28 at 4 mm) and moves the in-plane resonances by 0.15 percent while leaving the bending modes unchanged. The rigid constraint of MODEL.md is enforced by applying each stick's reaction as the rigid inertial load that cancels its net force and moments, and by projecting the six mass-orthonormal rigid fields out of the state at every chunk of steps. The sticks are point masses stepped with the same scheme through the Hertz law, each started at the current surface height under it with relative speed v_0. The Rayleigh integral is accumulated at every step from the transverse acceleration at the Gauss points, spread onto the output samples at the retarded times with cubic Lagrange interpolation, so no acceleration history is stored. The step runs on a GPU through PyTorch, the constitutive and output blocks fused by torch.compile and the whole step captured as a CUDA graph: about 5100 steps per second at 8 mm (25488 unknowns, a quarter of an hour for the seven seconds).
Checks: the linearized assembly reproduces the free annulus's lowest frequencies to within 1 percent at 8 mm (21.7, 37.6, 50.6, 85.5 Hz against 21.9, 38.0, 50.9, 85.9), the lumped mass shifts them by under 0.3 percent relative to the consistent mass, the internal force matches the energy gradient to 1e-9, and the retarded accumulation matches a direct integral to 4e-5. On the crash geometry the two tilt modes, exact zero modes of the continuum, come out at 2.95 Hz at 8 mm because the bicubic space cannot represent the in-plane displacement that accompanies a rigid tilt of the cosine bell; the constraint removes them anyway. A run of the flat challenge with the shell left free confirmed what MODEL.md says about the constraint: the shell tilted by about a radian in half a second, the partials glided down, the treble drained away, and the explicit run diverged at 0.66 s.
bash solvers/hermite-fem/run_chain.sh <cymbal2-repo> # on a CUDA GPU: 8 mm then 4 mm for both challenges, hours
python solvers/hermite-fem/check_modes.py <cymbal2-repo>/challenges/cymbal2-flat-v1/challenge.json 0.008 # linear check, CPU
While a run is going, <tag>.progress.json and <tag>.partial.wav beside the outputs are rewritten every minute with the state of the sticks and the samples computed so far.
Validating locally#
pip install git+https://vault1.magland.org/challenges/challenge-tools
challenge-tools validate --challenges <path-to-cymbal2-repo>/challenges --solutions solutions
python web/build.py --out site