Pipe Assembly Lab v1.2: thermal/support workflow and validated harmonic-response sweeps
dace1db verified Download engineering.js from HaomingLuo/AgentFEM-Pipe-Assembly-Lab: direct link, hf CLI and curl.
- Browser
- Download file 4.5 kB
-
https://huggingface.co/spaces/HaomingLuo/AgentFEM-Pipe-Assembly-Lab/resolve/main/engineering.js
- Command line
-
hf download hf://spaces/HaomingLuo/AgentFEM-Pipe-Assembly-Lab/engineering.js
-
curl -L -o engineering.js https://huggingface.co/spaces/HaomingLuo/AgentFEM-Pipe-Assembly-Lab/resolve/main/engineering.js
4.5 kB
| // Interface for the two engineering questions. No plant-specific operating data implied. | |
| export function setupEngineering({getLanguage,onThermal,onVibration,onForced,onChange,getExcitation,setExcitation,getResult,getNodeCount}){ | |
| const zh=()=>getLanguage()==='zh',el=id=>document.getElementById(id); | |
| const bar=document.createElement('div');bar.className='engineering-tabs';bar.innerHTML='<button id="thermal-task" class="active"></button><button id="vibration-task"></button><span id="scope-note"></span>';document.querySelector('main').before(bar); | |
| const panel=document.createElement('details');panel.id='forced-tools';panel.innerHTML='<summary id="forced-label"></summary><p class="hint" id="forced-hint"></p><label class="field"><span id="force-node-label"></span><select id="force-node"></select></label><label class="field"><span id="force-axis-label"></span><select id="force-axis"><option value="0">X</option><option value="1">Y</option><option value="2">Z ↑</option></select></label><label class="field"><span id="force-label"></span><input id="force-value" type="number" min="1" max="10000" step="10"></label><label class="field"><span id="force-frequency-label"></span><input id="force-frequency" type="number" min="0.1" max="2000" step="0.1"></label><label class="field"><span id="zeta-label"></span><input id="force-zeta" type="number" min="0.1" max="10" step="0.1"></label><button id="forced-run"></button>'; | |
| document.getElementById('dynamic-tools').before(panel); | |
| const thermal=document.createElement('div');thermal.id='thermal-insight';thermal.className='thermal-insight';document.getElementById('viewport').append(thermal); | |
| function setTask(vibration){bar.querySelectorAll('button').forEach((b,i)=>b.classList.toggle('active',i===Number(vibration)));panel.open=vibration;el('dynamic-tools').open=vibration;} | |
| el('thermal-task').onclick=()=>{setTask(false);onThermal();};el('vibration-task').onclick=()=>{setTask(true);onVibration();};el('forced-run').onclick=()=>{if(commit())onForced();}; | |
| function commit(){const p={node:+el('force-node').value,axis:+el('force-axis').value,force:+el('force-value').value,frequency:+el('force-frequency').value,zeta:+el('force-zeta').value/100};if(!(p.force>=1&&p.force<=10000&&p.frequency>=.1&&p.frequency<=2000&&p.zeta>=.001&&p.zeta<=.1)){sync();return false;}if(JSON.stringify(p)!==JSON.stringify(getExcitation()))setExcitation(p);return true;} | |
| // Commit on the explicit solve button: avoid replacing a partially typed number. | |
| function sync(){const p=getExcitation(),n=getNodeCount();el('force-node').replaceChildren(...Array.from({length:n},(_,i)=>new Option((zh()?'连接点 ':'Joint ')+(i+1),i+1)));el('force-node').value=p.node;el('force-axis').value=p.axis;el('force-value').value=p.force;el('force-frequency').value=p.frequency;el('force-zeta').value=+(p.zeta*100).toFixed(3); | |
| const labels=zh()?{'thermal-task':'热位移与支吊架','vibration-task':'振动与减振','scope-note':'四大管道研究 · 通用组件示例','forced-label':'受迫振动 / 周期力','forced-hint':'指定振源,比较同一测点加装阻尼器前后的响应。','force-node-label':'施力与测量位置','force-axis-label':'力与测量方向','force-label':'力幅值 / N','force-frequency-label':'激励频率 / Hz','zeta-label':'假设模态阻尼比 / %','forced-run':'计算振幅与扫频'}:{'thermal-task':'Thermal movement & supports','vibration-task':'Vibration & mitigation','scope-note':'Power piping research · generic component example','forced-label':'FORCED VIBRATION / HARMONIC FORCE','forced-hint':'Specify the excitation. Compare the same measurement with and without the added damper.','force-node-label':'Force & probe joint','force-axis-label':'Force & probe direction','force-label':'Force amplitude / N','force-frequency-label':'Excitation / Hz','zeta-label':'Assumed modal damping / %','forced-run':'Compute response & sweep'}; | |
| for(const [id,text] of Object.entries(labels))el(id).textContent=text;} | |
| return {sync,thermal(view){thermal.hidden=view!=='static';const r=getResult();if(!r)return;const u=r.q.slice(0,3),F=r.supportForces[0],M=r.reaction.slice(3,6);thermal.textContent=zh()?`入口接口载荷 ${Math.hypot(...F)/1000<.01?'0.00':(Math.hypot(...F)/1000).toFixed(2)} kN · ${ (Math.hypot(...M)/1000).toFixed(2)} kN·m|入口固定,非设备允许载荷`:`Inlet reaction ${(Math.hypot(...F)/1000).toFixed(2)} kN · ${(Math.hypot(...M)/1000).toFixed(2)} kN·m | Fixed inlet, not an allowable load`;}}; | |
| } | |