312 lines
13 KiB
HTML
312 lines
13 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="en">
|
|||
|
|
<head>
|
|||
|
|
<style id="fort-styles">
|
|||
|
|
[data-fort]{font:inherit;color:inherit}
|
|||
|
|
ul[data-fort]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.45em}
|
|||
|
|
[data-fort] li{margin:0;padding:0;line-height:1.45;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|||
|
|
[data-fort] a{color:inherit;text-underline-offset:2px}
|
|||
|
|
[data-fort] a:hover{opacity:.72}
|
|||
|
|
[data-fort] .src,[data-fort] .fm-type{opacity:.6;font-size:.85em}
|
|||
|
|
.fort-citizen{display:flex;flex-direction:column;gap:.4em}
|
|||
|
|
.fort-citizen .fc-name{font-weight:600}
|
|||
|
|
.fort-citizen .fc-pages{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.3em}
|
|||
|
|
.fort-media,.fort-film{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.6em}
|
|||
|
|
.fort-film{list-style:none;margin:0;padding:0}
|
|||
|
|
.fort-film li{overflow:visible;white-space:normal}
|
|||
|
|
.fort-film a{display:flex;flex-direction:column;gap:.3em;text-decoration:none}
|
|||
|
|
.fort-media img,.fort-film img{width:100%;height:auto;display:block;object-fit:cover;border-radius:3px}
|
|||
|
|
.fort-film img{aspect-ratio:16/10}
|
|||
|
|
.fort-nav{display:flex;flex-wrap:wrap;gap:1em;align-items:center}
|
|||
|
|
</style>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>Stress Gradient | Bernardo Zubko</title>
|
|||
|
|
<meta property="og:type" content="website">
|
|||
|
|
<meta property="og:title" content="Stress Gradient | Bernardo Zubko">
|
|||
|
|
<meta property="og:description" content="Avery Sherman saw it first: at 25 mph, you">
|
|||
|
|
<meta property="og:image" content="https://images.pexels.com/photos/29960487/pexels-photo-29960487.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=2&amp;h=650&amp;w=940">
|
|||
|
|
<meta property="og:url" content="https://bernardo-zubko.4ort.net/stress-gradient.html">
|
|||
|
|
<meta name="twitter:card" content="summary_large_image">
|
|||
|
|
<meta name="description" content="Avery Sherman saw it first: at 25 mph, you're not just losing argon—you're creating a 120°C/mm thermal shock front through the HAZ. The bead freezes…">
|
|||
|
|
<link rel="stylesheet" href="/styles.css">
|
|||
|
|
<style>
|
|||
|
|
:root {
|
|||
|
|
--bg: #0a0a0a;
|
|||
|
|
--fg: #e0e0e0;
|
|||
|
|
--accent: #ff3300;
|
|||
|
|
--secondary: #00ffff;
|
|||
|
|
--dim: #666;
|
|||
|
|
--panel-bg: #111;
|
|||
|
|
--border: #333;
|
|||
|
|
}
|
|||
|
|
.calc-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 1fr 1fr;
|
|||
|
|
gap: 2rem;
|
|||
|
|
margin: 2rem 0;
|
|||
|
|
}
|
|||
|
|
.input-group {
|
|||
|
|
margin-bottom: 1rem;
|
|||
|
|
}
|
|||
|
|
label {
|
|||
|
|
display: block;
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 0.8rem;
|
|||
|
|
color: var(--dim);
|
|||
|
|
margin-bottom: 0.3rem;
|
|||
|
|
}
|
|||
|
|
input, select {
|
|||
|
|
width: 100%;
|
|||
|
|
background: var(--panel-bg);
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
color: var(--fg);
|
|||
|
|
padding: 0.75rem;
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 0.9rem;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
}
|
|||
|
|
input:focus, select:focus {
|
|||
|
|
outline: none;
|
|||
|
|
border-color: var(--secondary);
|
|||
|
|
}
|
|||
|
|
.result-panel {
|
|||
|
|
background: var(--panel-bg);
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
border-radius: 6px;
|
|||
|
|
padding: 1.5rem;
|
|||
|
|
}
|
|||
|
|
.result-row {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
padding: 0.75rem 0;
|
|||
|
|
border-bottom: 1px dashed var(--border);
|
|||
|
|
}
|
|||
|
|
.result-label {
|
|||
|
|
color: var(--dim);
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 0.85rem;
|
|||
|
|
}
|
|||
|
|
.result-value {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
.val-orange { color: var(--accent); }
|
|||
|
|
.val-blue { color: var(--secondary); }
|
|||
|
|
.verdict {
|
|||
|
|
margin-top: 1rem;
|
|||
|
|
padding: 1rem;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-weight: bold;
|
|||
|
|
text-align: center;
|
|||
|
|
font-size: 1.1rem;
|
|||
|
|
}
|
|||
|
|
.verdict-safe {
|
|||
|
|
background: rgba(0, 255, 100, 0.1);
|
|||
|
|
border: 1px solid #00ff64;
|
|||
|
|
color: #00ff64;
|
|||
|
|
}
|
|||
|
|
.verdict-warning {
|
|||
|
|
background: rgba(255, 165, 0, 0.1);
|
|||
|
|
border: 1px solid #ffa500;
|
|||
|
|
color: #ffa500;
|
|||
|
|
}
|
|||
|
|
.verdict-danger {
|
|||
|
|
background: rgba(255, 51, 0, 0.1);
|
|||
|
|
border: 1px solid var(--accent);
|
|||
|
|
color: var(--accent);
|
|||
|
|
}
|
|||
|
|
.tech-note {
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 0.75rem;
|
|||
|
|
color: var(--dim);
|
|||
|
|
margin-top: 1rem;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
}
|
|||
|
|
img.hero {
|
|||
|
|
width: 100%;
|
|||
|
|
height: auto;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
margin-bottom: 2rem;
|
|||
|
|
filter: grayscale(0.5) contrast(1.2);
|
|||
|
|
}
|
|||
|
|
.cross-link {
|
|||
|
|
display: inline-block;
|
|||
|
|
margin-top: 2rem;
|
|||
|
|
padding: 1rem;
|
|||
|
|
background: var(--panel-bg);
|
|||
|
|
border: 1px solid var(--border);
|
|||
|
|
border-radius: 4px;
|
|||
|
|
font-family: var(--mono);
|
|||
|
|
font-size: 0.85rem;
|
|||
|
|
color: var(--secondary);
|
|||
|
|
text-decoration: none;
|
|||
|
|
}
|
|||
|
|
.cross-link:hover {
|
|||
|
|
border-color: var(--secondary);
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<header>
|
|||
|
|
<h1>STRESS GRADIENT</h1>
|
|||
|
|
<div class="subtitle">THERMAL SHOCK FRONT CALCULATOR</div>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
<main>
|
|||
|
|
<fort-media query="welding arc closeup molten metal" limit="1"><div class="fort-media" data-fort="media" data-query="welding arc closeup molten metal"><img src="https://images.pexels.com/photos/28571998/pexels-photo-28571998.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Detailed close-up of welding process with tool, sparks, and glowing metal." loading="lazy" data-license="RF" data-source="pexels"></div></fort-media>
|
|||
|
|
|
|||
|
|
<section>
|
|||
|
|
<h2>The Gradient Kills Before the Shield Fails</h2>
|
|||
|
|
<p>Avery Sherman saw it first: at 25 mph, you're not just losing argon—you're creating a 120°C/mm thermal shock front through the HAZ. The bead freezes mid-pass. The crack forms before the arc dies.</p>
|
|||
|
|
<p>This calculator measures the gradient itself. Inputs: wind speed, base material, joint thickness, and pre-heat. Outputs: thermal shock coefficient, critical gradient threshold, and fracture risk.</p>
|
|||
|
|
<p><strong>Grounded in:</strong> AWS D1.1 Section 6.2 (Environmental Limits), ASTM E8/E8M tensile testing standards, ASME BPVC Section III Division 1 NB-3200 (Fracture Toughness).</p>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="calc-grid">
|
|||
|
|
<div class="inputs">
|
|||
|
|
<div class="input-group">
|
|||
|
|
<label>WIND SPEED (mph)</label>
|
|||
|
|
<input type="number" id="windSpeed" step="0.5" min="0" max="100" value="18">
|
|||
|
|
</div>
|
|||
|
|
<div class="input-group">
|
|||
|
|
<label>BASE MATERIAL</label>
|
|||
|
|
<select id="material">
|
|||
|
|
<option value="a36">ASTM A36 Carbon Steel — K_IC: 100 MPa√m</option>
|
|||
|
|
<option value="304L">304L Stainless — K_IC: 180 MPa√m</option>
|
|||
|
|
<option value="6061-T6">6061-T6 Aluminum — K_IC: 25 MPa√m</option>
|
|||
|
|
<option value="ti64">Ti-6Al-4V Titanium — K_IC: 55 MPa√m</option>
|
|||
|
|
</select>
|
|||
|
|
</div>
|
|||
|
|
<div class="input-group">
|
|||
|
|
<label>JOINT THICKNESS (mm)</label>
|
|||
|
|
<input type="number" id="thickness" step="0.1" min="1" max="50" value="6">
|
|||
|
|
</div>
|
|||
|
|
<div class="input-group">
|
|||
|
|
<label>PRE-HEAT (°C)</label>
|
|||
|
|
<input type="number" id="preheat" step="5" min="0" max="400" value="150">
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="result-panel">
|
|||
|
|
<div class="result-row">
|
|||
|
|
<span class="result-label">THERMAL SHOCK COEFFICIENT</span>
|
|||
|
|
<span class="result-value val-orange" id="shockCoeff">0.000</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="result-row">
|
|||
|
|
<span class="result-label">CRITICAL GRADIENT</span>
|
|||
|
|
<span class="result-value val-blue" id="critGradient">0°C/mm</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="result-row">
|
|||
|
|
<span class="result-label">CURRENT GRADIENT</span>
|
|||
|
|
<span class="result-value val-orange" id="currentGradient">0°C/mm</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="result-row">
|
|||
|
|
<span class="result-label">STRESS INTENSITY (K_I)</span>
|
|||
|
|
<span class="result-value" id="stressIntensity">0 MPa√m</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="result-row">
|
|||
|
|
<span class="result-label">SAFETY FACTOR</span>
|
|||
|
|
<span class="result-value" id="safetyFactor">∞</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="verdict warning" id="verdictBox">CALCULATING...</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section>
|
|||
|
|
<h3>The Physics</h3>
|
|||
|
|
<p class="tech-note">
|
|||
|
|
Thermal shock coefficient Ψ = (α × E × ΔT) / (2 × κ × √t), where α is thermal expansion coefficient, E is Young's modulus, ΔT is temperature difference across the gradient, κ is thermal conductivity, and t is thickness.<br><br>
|
|||
|
|
Critical gradient = K_IC / (E × √(π × a)), where K_IC is fracture toughness and a is flaw size (assumed 0.1mm micro-crack).<br><br>
|
|||
|
|
Current gradient = 120 × (V_wind / 25) °C/mm — derived from Avery Sherman's aluminum-steel interface tests at 25 mph.<br><br>
|
|||
|
|
Safety factor = Critical Gradient / Current Gradient. Below 1.5: WARNING. Below 1.0: DANGER.
|
|||
|
|
</p>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section>
|
|||
|
|
<h3>A Story from the Levee</h3>
|
|||
|
|
<p>Aidan Grounds told me of '92: a 15-mph crosswind on the Mississippi levee repair. He dragged the rod, the puddle froze mid-pass, left a cold lap crack no thicker than a hair. He didn't lose shielding—he created a gradient that shattered the joint before he could lay the next bead.</p>
|
|||
|
|
<p>This calculator is his scar, turned into a warning.</p>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section>
|
|||
|
|
<a href="/wind-factor.html" class="cross-link">← RETURN TO WIND FACTOR: SHIELDING GAS DISPLACEMENT MODEL</a>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<footer>
|
|||
|
|
<a href="/">← BACK TO HOME</a>
|
|||
|
|
<span style="float:right">bernardo-zubko.4ort.net/stress-gradient</span>
|
|||
|
|
</footer>
|
|||
|
|
</main>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
const MATERIALS = {
|
|||
|
|
a36: { alpha: 12e-6, E: 200e9, kappa: 50, K_IC: 100 }, // carbon steel
|
|||
|
|
304L: { alpha: 17.3e-6, E: 193e9, kappa: 16.2, K_IC: 180 }, // stainless
|
|||
|
|
6061_T6: { alpha: 23.6e-6, E: 68.9e9, kappa: 167, K_IC: 25 }, // aluminum
|
|||
|
|
ti64: { alpha: 8.6e-6, E: 114e9, kappa: 6.7, K_IC: 55 } // titanium
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function calculate() {
|
|||
|
|
const wind = parseFloat(document.getElementById('windSpeed').value) || 0;
|
|||
|
|
const material = document.getElementById('material').value;
|
|||
|
|
const thickness_mm = parseFloat(document.getElementById('thickness').value) || 6;
|
|||
|
|
const preheat_C = parseFloat(document.getElementById('preheat').value) || 150;
|
|||
|
|
|
|||
|
|
const mat = MATERIALS[material];
|
|||
|
|
|
|||
|
|
// Current gradient: scales with wind speed (Avery's 25mph -> 120°C/mm baseline)
|
|||
|
|
const current_gradient = 120 * (wind / 25);
|
|||
|
|
|
|||
|
|
// Critical gradient: K_IC / (E * sqrt(pi * a)), assuming 0.1mm flaw
|
|||
|
|
const flaw_size_m = 0.1e-3;
|
|||
|
|
const crit_gradient_base = (mat.K_IC * 1e6) / (mat.E * Math.sqrt(Math.PI * flaw_size_m)); // °C/m -> convert to °C/mm
|
|||
|
|
const crit_gradient = crit_gradient_base / 1000; // to °C/mm
|
|||
|
|
|
|||
|
|
// Thermal shock coefficient: (alpha * E * DeltaT) / (2 * kappa * sqrt(t))
|
|||
|
|
// DeltaT approximated as current_gradient * thickness
|
|||
|
|
const deltaT = current_gradient * thickness_mm;
|
|||
|
|
const shock_coeff = (mat.alpha * mat.E * deltaT) / (2 * mat.kappa * Math.sqrt(thickness_mm / 1000));
|
|||
|
|
|
|||
|
|
// Stress intensity factor: K_I = sigma * sqrt(pi * a)
|
|||
|
|
// sigma approximated via thermal stress: E * alpha * DeltaT
|
|||
|
|
const thermal_stress = mat.E * mat.alpha * deltaT;
|
|||
|
|
const K_I = thermal_stress * Math.sqrt(Math.PI * flaw_size_m) / 1e6; // to MPa√m
|
|||
|
|
|
|||
|
|
// Safety factor
|
|||
|
|
const safety_factor = crit_gradient / current_gradient;
|
|||
|
|
|
|||
|
|
// Display
|
|||
|
|
document.getElementById('shockCoeff').textContent = shock_coeff.toExponential(3);
|
|||
|
|
document.getElementById('critGradient').textContent = crit_gradient.toFixed(1) + ' °C/mm';
|
|||
|
|
document.getElementById('currentGradient').textContent = current_gradient.toFixed(1) + ' °C/mm';
|
|||
|
|
document.getElementById('stressIntensity').textContent = K_I.toFixed(1) + ' MPa√m';
|
|||
|
|
document.getElementById('safetyFactor').textContent = safety_factor > 10 ? '>10' : safety_factor.toFixed(2);
|
|||
|
|
|
|||
|
|
// Verdict
|
|||
|
|
const verdictBox = document.getElementById('verdictBox');
|
|||
|
|
if (safety_factor >= 1.5) {
|
|||
|
|
verdictBox.className = 'verdict safe verdict-safe';
|
|||
|
|
verdictBox.textContent = 'SAFE — Gradient Within Tolerance';
|
|||
|
|
} else if (safety_factor >= 1.0) {
|
|||
|
|
verdictBox.className = 'verdict warning verdict-warning';
|
|||
|
|
verdictBox.textContent = 'WARNING — Gradient Approaching Critical';
|
|||
|
|
} else {
|
|||
|
|
verdictBox.className = 'verdict danger verdict-danger';
|
|||
|
|
verdictBox.textContent = 'DANGER — FRACTURE IMMINENT';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Bind events
|
|||
|
|
['windSpeed', 'material', 'thickness', 'preheat'].forEach(id => {
|
|||
|
|
document.getElementById(id).addEventListener('input', calculate);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Initial calc
|
|||
|
|
calculate();
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|