main
John Lauer Add readable heat-flow section toggle and refine thermal viewer framing 9f3135b
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Electronic load — 3D thermal comparison</title><style>
html,body{margin:0;height:100%;background:#14212c;color:#e4edf4;font:15px system-ui}body{display:flex;flex-direction:column}header{padding:12px 18px;background:#20303e}select,button{font:inherit;background:#30495b;color:white;border:1px solid #76929f;border-radius:5px;padding:5px}small{display:block;color:#c9d5de;margin-top:6px}#host{flex:1;min-height:0}a{color:#7bd7ce}label{margin-left:12px}.legend{display:inline-block;width:150px;height:10px;background:linear-gradient(90deg,cyan,#ffff80,red)}#numbers{font-size:17px;margin-top:8px;color:#9be5d9}#warning{color:#ffd18a}</style><script>window.process={env:{NODE_ENV:'production'}};window.global=window;</script></head><body><header><b>Q1 → interface → heatsink fins</b> <select id="choice"><option value="preferred50">50 mm low-profile</option><option value="chipset40">40 mm tall-fin</option><option value="pi5">Pi 5 blower concept</option></select> <select id="air"><option value="100">Fan-on assumption · h=100</option><option value="5">Fan-off assumption · h=5</option></select><label><input id="sink" type="checkbox" checked>Heatsink</label><label><input id="layers" type="checkbox" checked>Interface layers</label> <button id="home">Home</button> <button id="section">Heat-flow section</button>
<small>Steady 3D solid-conduction simulation • 5.5 W Q1 heat input • 40°C ambient • approximate geometry • h in W/m²K, not measured fan performance</small>
<div id="numbers">Loading…</div><small><span class="legend"></span> <span id="legendText">40–150°C</span> <button id="scale">Magnify 40–60°C</button> · <a href="https://wiki.adom.inc/adom/adom-custom-electronic-load/files/docs/cooling-volume/README.md">Results, heat-flow sections and limitations</a></small><small id="warning">Calculated limits are conditional, not board power ratings. Fan-off views assume shutdown failed; they are not an authorized operating state.</small><small id="status">Loading canonical Adom viewer…</small></header><main id="host"></main><img id="sectionImage" style="display:none;flex:1;min-height:0;object-fit:contain;max-width:100%" alt="Solved h=100 heat-flow cross-section">
<script type="module">
const $=id=>document.getElementById(id),status=$('status');
try {
await import('/static/vendor/adom-3d-viewer-babylon9/adom-3d-viewer-babylon9.esm.js?v=20261012b');
const v=window.Adom3DViewerBabylon9.init($('host'),{zUp:true,showViewCube:true});window.thermalViewer=v;
const data=await(await fetch('./summary.json')).json();let loading=false,magnify=false;
function recolor(){for(const m of v.getScene().meshes){const a=m.getVerticesData?.('color');if(!a)continue;if(!m.thermalOriginal)m.thermalOriginal=Array.from(a);const src=m.thermalOriginal,out=src.slice(),stride=src.length/m.getTotalVertices();for(let i=0;i<src.length;i+=stride){const temp=40+110*(1-src[i+2]),t=Math.max(0,Math.min(1,(temp-40)/(magnify?20:110)));out[i]=Math.min(1,2*t);out[i+1]=Math.min(1,2*(1-t));out[i+2]=1-t;}m.setVerticesData('color',out,false,stride);} $('legendText').textContent=magnify?'40–60°C (above 60°C saturated)':'40–150°C';$('scale').textContent=magnify?'Show 40–150°C':'Magnify 40–60°C';}
function visibility(){for(const m of v.getScene().meshes){if(m.name==='heatsink')m.setEnabled($('sink').checked);if(['AlN','spreader'].includes(m.name))m.setEnabled($('layers').checked);}}
window.selectThermal=async function(id,h){if(loading)return {busy:true};loading=true;$('choice').disabled=$('air').disabled=true;$('choice').value=id;$('air').value=String(h);status.textContent='Loading solved surfaces…';$('host').style.display='block';$('sectionImage').style.display='none';$('section').textContent='Heat-flow section';$('section').disabled=Number(h)!==100;try{v.clearScene();await v.loadModel(new URL(id+'-h'+h+'.glb',location.href).href);v.frameModel();const camera=v.getCamera();camera.alpha=0.8;camera.beta=0.55;camera.radius*=1.15;recolor();visibility();const r=data.results.find(r=>r.id===id&&r.h===Number(h)&&r.pitchMm===1);$('numbers').textContent=`Case ${r.caseC.toFixed(1)}°C · estimated junction ${r.junctionC.toFixed(1)}°C · sink ${r.sinkMinC.toFixed(1)}–${r.sinkMaxC.toFixed(1)}°C · conditional ceiling ${r.conditionalLoadW.toFixed(2)} W`;status.textContent='Ready · drag to orbit; hide heatsink and interface layers to inspect Q1. Cell colours come from the solve.';window.thermalState={id,h:Number(h),...r};return window.thermalState;}finally{loading=false;$('choice').disabled=$('air').disabled=false;}};
$('section').onclick=()=>{const show=$('sectionImage').style.display==='none';$('sectionImage').src='./'+$('choice').value+'-section.png';$('sectionImage').style.display=show?'block':'none';$('host').style.display=show?'none':'block';$('section').textContent=show?'Return to 3D':'Heat-flow section';};
$('choice').onchange=()=>selectThermal($('choice').value,$('air').value);$('air').onchange=()=>selectThermal($('choice').value,$('air').value);$('sink').onchange=visibility;$('layers').onchange=visibility;$('home').onclick=()=>v.goHome();$('scale').onclick=()=>{magnify=!magnify;recolor();};await selectThermal('chipset40',100);
}catch(e){status.textContent='Viewer error: '+e.message;window.viewerError=e.message;}
</script></body></html>