HaomingLuo's picture
Pipe Assembly Lab: task-led thermal and damper comparison, automatic baselines and matched views
8122f59 verified
Raw History Blame Contribute Delete
8.74 kB
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="theme-color" content="#091315"><title>AgentFEM · Pipe Assembly Lab</title><meta name="description" content="Build a pipe. Add a support. See how it moves. A solid-FE component reduced-order model, running in your browser."><link rel="stylesheet" href="style.css"><script type="importmap">{"imports":{"three":"./vendor/three.module.js"}}</script></head>
<link rel="stylesheet" href="journey.css"><body>
<header><a class="brand" href="https://haoming-luo.github.io/agentfem/" target="_blank" rel="noopener">AgentFEM<span>RESEARCH LAB</span></a><div class="heading"><h1 data-t="title">Pipe Assembly Lab</h1><p data-t="subtitle">Thermal movement · support loads · vibration</p></div><nav><button id="method" data-t="method">How it works</button><button id="language" aria-label="Change language">中文</button></nav></header>
<div class="projectbar"><div><button id="undo" data-t="undo">Undo</button><button id="redo" data-t="redo">Redo</button><span id="project-state" role="status"></span></div><div><button id="baseline" data-t="baseline">Keep baseline</button><button id="review" data-t="review">Compare & export</button><button id="save-project" data-t="save">Save</button><button id="open-project" data-t="open">Open</button><input type="file" id="project-file" accept=".json,application/json" hidden></div></div>
<main><aside id="tools">
<div class="section-top"><span class="eyebrow" data-t="route">01 / ROUTE</span><button id="reset" class="quiet" data-t="reset">Reset</button></div>
<div class="presets"><button data-preset="L" class="active">L</button><button data-preset="U">U</button><button data-preset="spatial" data-t="spatial">3D</button></div>
<label class="field"><span data-t="diameter">Outer diameter</span><select id="diameter"><option value="0.12">120 mm</option><option value="0.16">160 mm</option><option value="0.2" selected>200 mm</option><option value="0.24">240 mm</option></select></label>
<label class="field"><span data-t="wall">Wall thickness</span><select id="wall"><option value="0.04">8 mm</option><option value="0.06" selected>12 mm</option></select></label>
<div id="segments" class="segments" aria-label="Pipe components"></div>
<div class="add"><button id="add-straight" data-t="addStraight">+ Straight</button><button id="add-elbow" data-t="addElbow">+ Elbow</button></div>
<div class="segment-editor"><div class="field"><span id="selected-label">Component 1</span><button id="remove" class="quiet" data-t="remove">Remove</button></div><label class="field"><span id="dimension-label">Length</span><select id="dimension"></select></label><label class="field" id="roll-field"><span data-t="bendPlane">Bend direction</span><select id="roll"><option value="0" data-t="left">Left</option><option value="90" data-t="up">Up</option><option value="180" data-t="right">Right</option><option value="270" data-t="down">Down</option></select></label></div>
<div class="section-top"><span class="eyebrow" data-t="supports">02 / SUPPORTS</span></div>
<label class="field"><span data-t="station">Connection</span><select id="station"></select></label><label class="field"><span data-t="constraint">Support</span><select id="support"><option value="none" data-t="free">Free</option><option value="spring" data-t="spring">Vertical spring</option><option value="guide" data-t="guide">Vertical restraint</option><option value="fixed" data-t="fixed">Fixed</option></select></label>
<label id="spring-field" class="slider"><span data-t="stiffness">Spring stiffness</span><output id="spring-value">100 kN/m</output><input id="spring" type="range" min="1" max="3" step=".05" value="2"></label>
<p class="hint" data-t="rootFixed">The inlet is fixed. Select a joint to add a support.</p>
<div class="section-top"><span class="eyebrow" data-t="loading">03 / LOADING</span><label class="gravity"><input id="gravity" type="checkbox" checked><span data-t="gravity">Gravity</span></label></div>
<label class="slider"><span data-t="temperature">Uniform temperature rise</span><output id="temperature-value">100 K</output><input id="temperature" type="range" min="0" max="200" step="5" value="100"></label>
<p class="hint" data-t="material">Steel · E 200 GPa · α 12 × 10⁻⁶/K</p>
<details id="dynamic-tools"><summary data-t="damperTitle">04 / VIBRATION & DAMPER</summary><p class="hint" data-t="releaseHint">Release the first mode from a 1 mm peak displacement.</p><label class="field"><span data-t="station">Connection</span><select id="damper-node"></select></label><label class="field"><span data-t="axis">Global direction</span><select id="damper-axis"><option value="0">X</option><option value="1">Y</option><option value="2" selected>Z ↑</option></select></label><label class="slider"><span data-t="damping">Damping coefficient</span><output id="damper-value">10 kN·s/m</output><input id="damper" type="range" min="0" max="100" step="1" value="10"></label><button id="release" data-t="release">Release & compare</button></details>
</aside>
<section id="viewport"><canvas id="scene" aria-label="Interactive three-dimensional pipe model"></canvas><div class="scene-heading"><div class="eyebrow" data-t="live">COMPONENT ROM / LIVE SOLVE</div><h2 id="scene-title">Thermal displacement</h2><p id="scene-caption">Displacement and support reactions under heating and gravity.</p></div><div class="view-controls"><button id="fit" title="Fit view" aria-label="Fit view">⌖</button><button id="toggle-tools" aria-label="Toggle controls">☷</button></div>
<div id="status" role="status">Loading component library…</div><div id="joint-labels"></div><div id="end-actions" hidden><span data-t="extend">Extend this end</span><button id="preview-straight" data-t="addStraight">+ Straight</button><button id="preview-elbow" data-t="addElbow">+ Elbow</button><button id="confirm-part" data-t="confirm" hidden>Connect</button><button id="cancel-part" data-t="cancel" hidden>Cancel</button></div><div id="trace-panel" hidden><div><span id="trace-caption"></span><strong id="trace-clock"></strong></div><canvas id="trace" aria-label="Displacement versus time, without and with damper"></canvas><p id="trace-info"></p></div><div class="legend"><span class="swatch cold"></span><span id="reference-label" data-t="reference">Original shape</span><span class="swatch hot"></span><span id="result-label">Deformed shape</span></div>
<div class="playbar"><div class="tabs" id="views"><button data-view="static" class="active" data-t="thermalView">Expansion</button><button data-view="0">f₁</button><button data-view="1">f₂</button><button data-view="2">f₃</button></div><button id="play" aria-label="Play or pause">Ⅱ</button><label class="scale"><span data-t="scale">Display</span><select id="scale"><option value="1">×1</option><option value="10">×10</option><option value="30" selected>×30</option><option value="100">×100</option></select></label></div>
<div class="metrics"><article><span data-t="displacement">Max. centreline displacement</span><strong id="displacement">—</strong><small>mm</small></article><article><span data-t="reaction">Largest support force</span><strong id="reaction">—</strong><small>kN</small></article><article><span data-t="frequency">First natural frequency</span><strong id="frequency">—</strong><small>Hz</small></article><article><span data-t="mass">Pipe mass</span><strong id="mass">—</strong><small>kg</small></article></div>
<div class="scene-footer"><span data-t="gesture">Drag to orbit · Scroll to zoom</span><span id="solve-time"></span></div></section></main>
<footer><span data-t="footer">AgentFEM · Component reduced-order models</span><div><a href="https://huggingface.co/datasets/HaomingLuo/AgentFEM-Pipe-Components" target="_blank" rel="noopener">Dataset ↗</a><a href="https://huggingface.co/HaomingLuo/AgentFEM-Pipe-ROM" target="_blank" rel="noopener">Model ↗</a><a href="https://lab.haoming-luo.com/" target="_blank" rel="noopener">Haoming Lab ↗</a></div></footer>
<dialog id="about"><button class="close" id="close-about" aria-label="Close">×</button><span class="eyebrow">AgentFEM / PIPE ASSEMBLY LAB</span><h2 data-t="aboutTitle">Model and assumptions</h2><div id="about-copy"></div></dialog>
<dialog id="review-dialog"><button class="close" id="close-review" aria-label="Close">×</button><span class="eyebrow">AgentFEM / PIPE ASSEMBLY LAB</span><h2 data-t="review">Compare & export</h2><div id="review-copy"></div><div class="report-actions"><button id="export-csv">CSV</button><button id="export-report" data-t="report">Print / PDF</button></div></dialog>
<script type="module" src="app.js"></script></body></html>