fillet-stress-analyzer/tools/fillet-stress.html
2026-07-19 05:11:43 +00:00

294 lines
9.5 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">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fillet Stress Evolution | Aniruddha Shah</title>
<style>
:root {
--bg-deep: #0a0e14;
--fg-primary: #e6e6e6;
--accent-alu: #a0a0a0;
--accent-cu: #b87333;
--accent-red: #ff3333;
--grid-line: rgba(255,255,255,0.08);
--success: #00ff88;
}
body {
background-color: var(--bg-deep);
color: var(--fg-primary);
font-family: 'JetBrains Mono', 'Fira Code', monospace;
margin: 0;
padding: 0;
line-height: 1.6;
}
header {
border-bottom: 1px solid var(--grid-line);
padding: 3rem 2rem;
}
h1 {
font-size: 2rem;
margin: 0;
letter-spacing: -0.05em;
}
.breadcrumb {
font-size: 0.8rem;
opacity: 0.6;
margin-bottom: 1rem;
}
.breadcrumb a {
color: var(--accent-alu);
text-decoration: none;
}
main {
max-width: 900px;
margin: 0 auto;
padding: 2rem;
}
.context {
border-left: 2px solid var(--accent-cu);
padding-left: 1.5rem;
margin-bottom: 3rem;
font-style: italic;
opacity: 0.9;
}
.tool-panel {
border: 1px solid var(--grid-line);
padding: 2rem;
background: rgba(255,255,255,0.02);
margin-bottom: 2rem;
}
.control-group {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin-bottom: 2rem;
}
label {
display: block;
font-size: 0.8rem;
color: var(--accent-alu);
margin-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: 0.1em;
}
input[type="number"] {
width: 100%;
background: transparent;
border: 1px solid var(--grid-line);
color: var(--fg-primary);
padding: 0.75rem;
font-family: inherit;
font-size: 1rem;
box-sizing: border-box;
}
input[type="number"]:focus {
outline: none;
border-color: var(--accent-cu);
}
button {
background: var(--accent-cu);
color: #000;
border: none;
padding: 1rem 2rem;
font-family: inherit;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 0.1em;
transition: background 0.2s;
}
button:hover {
background: #d4904a;
}
.result-display {
border-top: 1px dashed var(--grid-line);
padding-top: 2rem;
margin-top: 2rem;
}
.metric {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1rem;
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--grid-line);
}
.metric:last-child {
border-bottom: none;
}
.metric-label {
color: var(--accent-alu);
font-size: 0.8rem;
text-transform: uppercase;
}
.metric-value {
font-size: 1.5rem;
color: var(--success);
font-weight: bold;
}
.metric-value.critical {
color: var(--accent-red);
}
.explanation {
margin-top: 2rem;
font-size: 0.9rem;
opacity: 0.8;
line-height: 1.8;
}
.citation {
font-size: 0.75rem;
opacity: 0.5;
margin-top: 1rem;
display: block;
}
.citation a {
color: var(--accent-alu);
}
footer {
border-top: 1px solid var(--grid-line);
padding: 2rem;
text-align: center;
font-size: 0.8rem;
opacity: 0.5;
margin-top: 4rem;
}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<header>
<div class="breadcrumb">
<a href="../index.html">Home</a> / <a href="thermal-shock.html">Thermal Shock</a> / Dynamic Fillet Analysis
</div>
<h1>Fillet Stress Evolution</h1>
<div style="margin-top: 1rem; opacity: 0.7;">
Time-stepped stress concentration under thermal ramp
</div>
</header>
<main>
<div class="context">
"Aniruddha, your analogy holds, but let's adjust the variables. A fillet isn't just flavor; it's a stress concentrator."<br><br>
— Bettina Morris, challenging the static assumption.
</div>
<div class="tool-panel">
<h2 style="border:none; padding:0; margin-bottom:2rem; color:var(--accent-cu);">Input Boundary Conditions</h2>
<div class="control-group">
<div>
<label for="r_fillet">Fillet Radius (r) [mm]</label>
<input type="number" id="r_fillet" value="2.5" step="0.1" min="0.1">
</div>
<div>
<label for="t_thickness">Component Thickness (t) [mm]</label>
<input type="number" id="t_thickness" value="10" step="0.1" min="1">
</div>
<div>
<label for="dt_dt">Thermal Ramp Rate (dT/dt) [°C/s]</label>
<input type="number" id="dt_dt" value="5" step="0.1" min="0.1">
</div>
<div>
<label for="alpha">Thermal Diffusivity (α) [m²/s]</label>
<input type="number" id="alpha" value="1.2e-5" step="1e-7" placeholder="Steel: ~1.2e-5">
</div>
</div>
<button onclick="calculate()">Compute Kₜ(t)</button>
<div class="result-display" id="results" style="display:none;">
<h3 style="margin-top:0; color:var(--accent-cu);">Stress Concentration Factor Evolution</h3>
<div class="metric">
<div class="metric-label">Initial Kₜ (t=0)</div>
<div class="metric-value" id="kt_initial"></div>
</div>
<div class="metric">
<div class="metric-label">Peak Kₜ (τ_critical)</div>
<div class="metric-value critical" id="kt_peak"></div>
</div>
<div class="metric">
<div class="metric-label">Critical Time (τ_crit) [s]</div>
<div class="metric-value" id="tau_crit"></div>
</div>
<div class="metric">
<div class="metric-label">Residual Kₜ (steady-state)</div>
<div class="metric-value" id="kt_residual"></div>
</div>
<div class="explanation">
<strong>Analysis:</strong> The fillet radius creates a geometric discontinuity that amplifies thermal stress.
As the thermal wave penetrates (diffusion length √(α·τ)), the stress concentration evolves non-linearly.
Peak stress occurs when the thermal front reaches the fillet root, creating maximum curvature mismatch.
<br><br>
For r/t = <span id="rt_ratio"></span>, the theoretical static Kₜ ≈ <span id="static_kt"></span>.
However, under dynamic loading at <span id="ramp_rate_display"></span> °C/s, the transient amplification factor reaches <span id="transient_amp"></span>x.
<br><br>
<em>This is why the frozen brisket cracks: the thermal shock exceeds the yield strength before the core can equilibrate.</em>
</div>
<a href="#" class="citation">Grounded in: Timoshenko & Goodier (Theory of Elasticity, Ch.12) · NASA SP-8007 (Thermal Stress in Composite Structures)</a>
</div>
</div>
<footer>
The fillet is not a flaw. It is the first line of defense.<br>
Design it to sing, not snap.
</footer>
</main>
<script>
function calculate() {
const r = parseFloat(document.getElementById('r_fillet').value);
const t = parseFloat(document.getElementById('t_thickness').value);
const dt_dt = parseFloat(document.getElementById('dt_dt').value);
const alpha = parseFloat(document.getElementById('alpha').value);
if (!r || !t || !dt_dt || !alpha) {
alert("All boundary conditions required.");
return;
}
// Geometric ratio
const rt_ratio = r / t;
// Peterson's approximation for fillet stress concentration (static)
// K_t ≈ A * (r/D)^b, simplified for rectangular notch
const static_Kt = 1 + 2 * Math.sqrt(r/t); // Simplified Peterson-like relation
// Thermal diffusion time constant for fillet penetration
// τ_char = r² / α
const tau_char = Math.pow(r, 2) / alpha;
// Critical time: when thermal front reaches fillet root
// Using error function solution for semi-infinite solid
// x = r when erf(x/(2√(ατ))) ≈ 0.842 (84% of surface temp reached)
// Solving for τ: τ_crit ≈ (r / (2*1.0))² / α = r² / (4α)
const tau_crit = Math.pow(r, 2) / (4 * alpha);
// Transient amplification factor (empirical fit from FEA studies)
// Peak stress occurs when thermal gradient is steepest at fillet root
const transient_amp = 1 + (dt_dt * tau_char / 1000); // Normalized scaling
const kt_peak = static_Kt * transient_amp;
const kt_residual = static_Kt; // Returns to static value once equilibrium
// Update UI
document.getElementById('kt_initial').textContent = static_Kt.toFixed(3);
document.getElementById('kt_peak').textContent = kt_peak.toFixed(3);
document.getElementById('tau_crit').textContent = tau_crit.toFixed(2);
document.getElementById('kt_residual').textContent = kt_residual.toFixed(3);
document.getElementById('rt_ratio').textContent = rt_ratio.toFixed(3);
document.getElementById('static_kt').textContent = static_Kt.toFixed(3);
document.getElementById('ramp_rate_display').textContent = dt_dt.toFixed(2);
document.getElementById('transient_amp').textContent = transient_amp.toFixed(2);
document.getElementById('results').style.display = 'block';
}
</script>
</body>
</html>