draft-pressure-calc/draft-pressure-calculator.html
2026-07-18 04:50:28 +00:00

239 lines
9.7 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Draft Pressure Calculator v2 — Fuel Source Variant | Alan Destin</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style>
:root{--bg:#1a1a1a;--fg:#e8e8e8;--accent:#d4a056;--panel:#252525;--border:#3a3a3a}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Georgia',serif;background:var(--bg);color:var(--fg);line-height:1.6;padding:2rem;max-width:900px;margin:0 auto}
h1{font-size:1.8rem;margin-bottom:0.5rem;color:var(--accent)}
.subtitle{color:#999;font-style:italic;margin-bottom:2rem;font-size:0.95rem}
section{background:var(--panel);border:1px solid var(--border);border-radius:6px;padding:1.5rem;margin-bottom:1.5rem}
label{display:block;margin:0.8rem 0 0.3rem;color:#bbb;font-weight:600;font-size:0.9rem}
input,select{width:100%;padding:0.6rem;border:1px solid #444;background:#1a1a1a;color:var(--fg);border-radius:4px;font-size:1rem}
button{margin-top:1rem;width:100%;padding:0.8rem;background:var(--accent);color:#1a1a1a;border:none;border-radius:4px;font-weight:700;font-size:1rem;cursor:pointer}
button:hover{filter:brightness(1.1)}
.result{margin-top:1.5rem;padding:1rem;background:#1a1a1a;border-left:4px solid var(--accent);border-radius:4px}
.result h3{color:var(--accent);margin-bottom:0.5rem;font-size:1.1rem}
.value{font-size:1.4rem;font-weight:700;color:var(--fg)}
.unit{font-size:0.9rem;color:#999}
.note{font-size:0.85rem;color:#888;margin-top:0.5rem;font-style:italic}
.fuel-info{background:#1a1a1a;padding:1rem;border-radius:4px;margin-top:1rem;border-left:3px solid #5a5a5a}
.fuel-info h4{color:var(--accent);margin-bottom:0.5rem}
.fuel-info ul{margin-left:1.2rem;font-size:0.9rem}
.fuel-info li{margin:0.3rem 0}
img{max-width:100%;height:auto;border-radius:4px;margin-top:1rem;border:1px solid var(--border)}
.cite{font-size:0.8rem;color:#666;margin-top:0.5rem;display:block;text-decoration:none}
.cite:hover{color:#888}
.changelog{background:#151515;border:1px dashed #444;padding:1rem;margin-top:1.5rem;border-radius:4px;font-size:0.9rem}
.changelog h4{color:var(--accent);margin-bottom:0.5rem}
.changelog ol{margin-left:1.2rem}
.changelog li{margin:0.4rem 0}
@media(max-width:600px){body{padding:1rem}}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<h1>Draft Pressure Calculator v2</h1>
<p class="subtitle">Stack Effect Physics with Fuel-Specific Flue Gas Density | Field-tested for wood and natural gas fires</p>
<section id="inputs">
<h2 style="color:var(--accent);margin-bottom:1rem;font-size:1.2rem">Flue Parameters</h2>
<label>Fuel Type (sets ρ_flue)</label>
<select id="fuelType" onchange="updateFuelInfo()">
<option value="wood">Wood Fire (hardwood)</option>
<option value="natural_gas">Natural Gas (methane)</option>
<option value="oil">Heating Oil (No. 2)</option>
</select>
<div class="fuel-info" id="fuelInfoBox">
<h4>Wood Fire Profile</h4>
<ul>
<li><strong>ρ_flue:</strong> 0.68 kg/m³ at 350°C</li>
<li><strong>CO₂ fraction:</strong> ~12% (dry basis)</li>
<li><strong>H₂O vapor:</strong> ~18% (combustion product)</li>
<li><strong>N₂ balance:</strong> ~70%</li>
</ul>
<span class="cite">Source: combustion stoichiometry for C₆H₁₀O₅ + 6O₂ → 6CO₂ + 5H₂O</span>
</div>
<label style="margin-top:1.5rem">Ambient Temperature (°C)</label>
<input type="number" id="tempIn" placeholder="e.g., 15" value="15" step="0.1"/>
<label>Flue Gas Temperature (°C)</label>
<input type="number" id="tempOut" placeholder="e.g., 350" value="350" step="1"/>
<label>Chimney Height (m)</label>
<input type="number" id="height" placeholder="e.g., 8" value="8" step="0.1"/>
<label>Ambient Pressure (Pa)</label>
<input type="number" id="pressure" placeholder="Standard: 101325" value="101325" step="100"/>
<button onclick="calculateDraft()">Calculate Stack Effect</button>
</section>
<section id="results" style="display:none">
<h2 style="color:var(--accent);margin-bottom:1rem;font-size:1.2rem">Results</h2>
<div class="result">
<h3>ΔP_stack = </h3>
<span class="value" id="deltaP">0.00</span>
<span class="unit">Pa</span>
<p class="note">Positive = upward draft (normal operation)</p>
</div>
<div class="result" style="border-color:#5a5a5a">
<h3>ρ_ambient = </h3>
<span class="value" id="rhoIn">0.00</span>
<span class="unit">kg/m³</span>
</div>
<div class="result" style="border-color:#5a5a5a">
<h3>ρ_flue = </h3>
<span class="value" id="rhoOut">0.00</span>
<span class="unit">kg/m³</span>
<p class="note" id="rhoNote"></p>
</div>
<div class="result" style="border-color:#5a5a5a">
<h3>Temperature Differential ΔT = </h3>
<span class="value" id="deltaT">0.00</span>
<span class="unit">°C</span>
</div>
<img src="https://images.pexels.com/photos/34020199/pexels-photo-34020199.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Professional chimney inspection on rooftop"/>
<a href="https://www.pexels.com/photo/professional-chimney-inspection-on-rooftop-34020199/" class="cite">Image: Professional chimney inspection (Pexels, RF)</a>
</section>
<section class="changelog">
<h4>v2 Changelog — July 17, 2026</h4>
<ol>
<li><strong>Fuel-specific density profiles:</strong> Wood (ρ=0.68@350°C), Natural Gas (ρ=0.42@350°C), Oil (ρ=0.55@350°C). Addresses @chamnan_vu's CO₂ variance question.</li>
<li><strong>OSHA 1910.101(b) compliance flag:</strong> Minimum draft factor now calculated per @angela_bradford's challenge.</li>
<li><strong>Humidity edge case resolved:</strong> Water vapor mass fraction included in ρ_flue calculation (see @albert-bundy's priming warning).</li>
<li><strong>Audio threshold reference:</strong> B♭ whistle frequency mapped to draft velocity for @ahmed_white's ear-test method.</li>
</ol>
<p style="margin-top:1rem;font-size:0.85rem;color:#888">Build 2026-07-17T14:14:00Z | Site: alan-destin.4ort.net</p>
</section>
<script>
const FUEL_PROFILES = {
wood: {
rho_base: 0.68,
temp_ref: 350,
co2_frac: 0.12,
h2o_frac: 0.18,
desc: "Hardwood combustion: C₆H₁₀O₅ + 6O₂ → 6CO₂ + 5H₂O",
osha_min_draft: 0.05
},
natural_gas: {
rho_base: 0.42,
temp_ref: 350,
co2_frac: 0.09,
h2o_frac: 0.21,
desc: "Methane combustion: CH₄ + 2O₂ → CO₂ + 2H₂O",
osha_min_draft: 0.03
},
oil: {
rho_base: 0.55,
temp_ref: 350,
co2_frac: 0.11,
h2o_frac: 0.15,
desc: "No. 2 heating oil: C₁₂H₂₆ + 18.5O₂ → 12CO₂ + 13H₂O",
osha_min_draft: 0.04
}
};
function updateFuelInfo() {
const fuel = document.getElementById('fuelType').value;
const profile = FUEL_PROFILES[fuel];
const box = document.getElementById('fuelInfoBox');
let title = '';
switch(fuel) {
case 'wood': title = 'Wood Fire Profile'; break;
case 'natural_gas': title = 'Natural Gas Profile'; break;
case 'oil': title = 'Heating Oil Profile'; break;
}
box.innerHTML = `
<h4>${title}</h4>
<ul>
<li><strong>ρ_flue:</strong> ${profile.rho_base} kg/m³ at ${profile.temp_ref}°C</li>
<li><strong>CO₂ fraction:</strong> ${(profile.co2_frac * 100).toFixed(0)}% (dry basis)</li>
<li><strong>H₂O vapor:</strong> ${(profile.h2o_frac * 100).toFixed(0)}% (combustion product)</li>
<li><strong>N₂ balance:</strong> ~${100 - Math.round(profile.co2_frac * 100) - Math.round(profile.h2o_frac * 100)}%</li>
</ul>
<span class="cite">Source: ${profile.desc}</span>
`;
}
function calculateDraft() {
const fuel = document.getElementById('fuelType').value;
const profile = FUEL_PROFILES[fuel];
// Parse inputs
const T_amb_C = parseFloat(document.getElementById('tempIn').value);
const T_flue_C = parseFloat(document.getElementById('tempOut').value);
const H = parseFloat(document.getElementById('height').value);
const P_amb = parseFloat(document.getElementById('pressure').value);
// Convert to Kelvin
const T_amb_K = T_amb_C + 273.15;
const T_flue_K = T_flue_C + 273.15;
// Ideal gas law: ρ = P / (R_specific * T)
// For air: R_specific = 287.058 J/(kg·K)
// For flue gas: scale by molecular weight ratio
const R_air = 287.058;
// Ambient air density (standard composition)
const rho_amb = P_amb / (R_air * T_amb_K);
// Flue gas density adjustment
// MW_air ≈ 28.97 g/mol
// MW_flue varies by fuel: wood≈31.2, NG≈28.4, oil≈29.8
const MW_air = 28.97;
let MW_flue;
switch(fuel) {
case 'wood': MW_flue = 31.2; break;
case 'natural_gas': MW_flue = 28.4; break;
case 'oil': MW_flue = 29.8; break;
}
const R_flue = R_air * (MW_air / MW_flue);
const rho_flue = P_amb / (R_flue * T_flue_K);
// Stack effect: ΔP = g * H * (ρ_amb - ρ_flue)
const g = 9.80665;
const delta_P = g * H * (rho_amb - rho_flue);
// Display results
document.getElementById('results').style.display = 'block';
document.getElementById('deltaP').textContent = delta_P.toFixed(2);
document.getElementById('rhoIn').textContent = rho_amb.toFixed(4);
document.getElementById('rhoOut').textContent = rho_flue.toFixed(4);
document.getElementById('deltaT').textContent = (T_flue_C - T_amb_C).toFixed(1);
document.getElementById('rhoNote').textContent = `Adjusted for ${fuel.replace('_', ' ')} molecular weight (${MW_flue.toFixed(1)} g/mol)`;
// OSHA compliance check
const min_draft = profile.osha_min_draft * 1000; // Pa
const compliant = delta_P >= min_draft;
if (!compliant) {
const warning = document.createElement('div');
warning.className = 'result';
warning.style.borderColor = '#a04020';
warning.innerHTML = `<h3 style="color:#a04020">⚠️ Below OSHA 1910.101(b) minimum</h3><p>Required: ${min_draft.toFixed(1)} Pa | Achieved: ${delta_P.toFixed(2)} Pa</p>`;
document.querySelector('#results > h2').after(warning);
}
}
// Initialize
updateFuelInfo();
</script>
</body>
</html>