[{"data":1,"prerenderedAt":174},["ShallowReactive",2],{"palette-posts":3,"work-elementarium":7,"work-all":163},[4],{"title":5,"path":6},"Threaded WebAssembly doesn't crash. It hangs.","\u002Fblog\u002Fthreads-that-hang",{"id":8,"title":9,"body":10,"cover":117,"coverCaption":118,"coverType":119,"description":120,"extension":121,"facts":122,"kicker":138,"links":139,"meta":146,"navigation":147,"order":148,"path":149,"role":150,"seo":151,"stack":152,"stem":161,"__hash__":162},"work\u002Fwork\u002Felementarium.md","Elementarium",{"type":11,"value":12,"toc":107},"minimark",[13,18,22,25,29,37,49,52,59,63,74,78,81,87,91,94,100,104],[14,15,17],"h2",{"id":16},"the-problem","The problem",[19,20,21],"p",{},"Structural analysis has traditionally meant installed desktop software, licence servers and a machine set aside for it. Elementarium's premise is that none of that is necessary any more: open a tab, model a structure, solve it, check it, print the report.",[19,23,24],{},"I built it on my own, end to end: the solver architecture, the numerics, the editor, the infrastructure, and taking it to production.",[14,26,28],{"id":27},"the-engine","The engine",[19,30,31,32,36],{},"At the core is ",[33,34,35],"strong",{},"tinyfem",", the finite element library I wrote in C++ on top of Eigen and compile with Emscripten. JavaScript reaches it through embind.",[19,38,39,40,44,45],{},"It ships as two builds of the same sources. The default one is single-threaded. The ",[41,42,43],"code",{},"-pthread"," build is the only way Eigen's OpenMP paths get real threads, and it only runs on a cross-origin-isolated page. The app tries the threaded build behind a deadline and falls back to the serial one on any failure, because a threaded init that the browser refuses doesn't throw, it hangs. ",[46,47,48],"a",{"href":6},"The full story is in this write-up.",[19,50,51],{},"Solves run in Web Workers, so the editor never blocks while a model is being factorised.",[19,53,54],{},[55,56],"img",{"alt":57,"src":58},"Steel hall in Elementarium: properties panel, 3D view, bending moment diagram and the loads table","\u002Fmedia\u002Fel-steelhall-moment.webp",[14,60,62],{"id":61},"dynamics-done-carefully","Dynamics, done carefully",[19,64,65,66,69,70,73],{},"Modal analysis asks for a ",[33,67,68],{},"mass participation target"," rather than a guessed number of modes, as EN 1998-1 §4.3.3.3 does. Iterative eigensolvers can step over a mode while passing every residual test, so a ",[33,71,72],{},"Sturm-sequence check"," confirms the returned modes really are the lowest ones. Consistent and lumped mass are both available.",[14,75,77],{"id":76},"the-editor","The editor",[19,79,80],{},"The front end is a Nuxt app with dockable panels and a TresJS viewport: instanced members, result shaders and cool–warm fringe plots. Models sync live between collaborators over Yjs and WebRTC, persist offline to IndexedDB, and the app installs as a PWA. Calculation reports are paginated for print with Paged.js.",[19,82,83],{},[55,84],{"alt":85,"src":86},"Concrete floor example: model with loads on the left, total displacement on the right","\u002Fmedia\u002Fel-concrete-floor.webp",[14,88,90],{"id":89},"design-checks","Design checks",[19,92,93],{},"Every steel member gets a utilisation per clause of EN 1993-1-1 §6.2, the governing combination, and a calculation sheet that shows the working.",[19,95,96],{},[55,97],{"alt":98,"src":99},"Design checks table: utilisation per clause, governing combination and status","\u002Fmedia\u002Fel-design-checks.webp",[14,101,103],{"id":102},"in-numbers","In numbers",[19,105,106],{},"The bundled examples solve in the browser in tens to hundreds of milliseconds: a 3D steel hall in 74 ms, a concrete floor with three load cases in 175 ms, a 318-member lattice tower with two load cases in 195 ms.",{"title":108,"searchDepth":109,"depth":109,"links":110},"",2,[111,112,113,114,115,116],{"id":16,"depth":109,"text":17},{"id":27,"depth":109,"text":28},{"id":61,"depth":109,"text":62},{"id":76,"depth":109,"text":77},{"id":89,"depth":109,"text":90},{"id":102,"depth":109,"text":103},"\u002Fmedia\u002Fel-steelhall-results.webp","Steel hall example · loads on the left, total displacement on the right · solved in 75 ms","image","3D structural analysis that opens like a web page. A C++ finite element engine in WebAssembly, under a full engineering editor.","md",[123,126,129,132,135],{"k":124,"v":125},"Elements","3D beams, trusses, MITC4 shells with drilling DOFs",{"k":127,"v":128},"Analyses","Static, modal, linear buckling, second-order",{"k":130,"v":131},"Eigen","Direct, Krylov, subspace · Sturm-sequence check",{"k":133,"v":134},"Design","EN 1993-1-1 §6.2 · AISC 360 · EN 1990 \u002F ASCE 7 combinations",{"k":136,"v":137},"Runtime","Single- & multi-threaded WASM, in workers","Product · built end to end",[140,143],{"label":141,"href":142},"Open the live demo","https:\u002F\u002Fstudio.elementarium.app\u002Fexample\u002Fdemo-hall",{"label":144,"href":145},"elementarium.app","https:\u002F\u002Felementarium.app",{},true,1,"\u002Fwork\u002Felementarium","Founder. Built it end to end, from architecture to production.",{"title":9,"description":120},[153,130,154,155,156,157,158,159,160],"C++","OpenMP","Emscripten","WebAssembly","Nuxt","TresJS","Yjs","Paged.js","work\u002Felementarium","Mq3NPgYQ-ZVwLvJ9Wt0kMzqh_c5XtDE2LmDAjK-7Pb4",[164,165,169],{"title":9,"path":149,"order":148,"kicker":138},{"title":166,"path":167,"order":109,"kicker":168},"Interior designer","\u002Fwork\u002Finterior-designer","Client work · confidential",{"title":170,"path":171,"order":172,"kicker":173},"Edubeam","\u002Fwork\u002Fedubeam",3,"Open source · structural mechanics education",1791464838305]