import React, { useState } from 'react'; import { useCalculatorStore } from '../../../store/calculatorStore'; import { TornadoMwfrsDiagrams } from '../diagrams/TornadoMwfrsDiagrams'; export const TornadoMwfrsSheet: React.FC = () => { const { tornado, buildingGeometry } = useCalculatorStore(); // Local Inputs for this tab (some might be better in global if shared, but specific to this detail tab) const [inputs, setInputs] = useState({ kdt: 0.80, kvtRoofUplift: 1.10, kvtWalls: 1.00, gcpiT_pos: 0.55, gcpiT_neg: -0.18, }); // Gust Factor from logic const gVal = tornado.userG === '0.85' ? 0.85 : parseFloat(tornado.userG); // Tornado qhT (Recalculated or could be stored) const qhT = 0.00256 * tornado.KhTor * tornado.Ke * Math.pow(tornado.Vt, 2); // qi = qhT const qi = qhT; // Define rows for the table // Surface | L/B | h/L | Cp (Normal) | ... | Cp (Parallel) // Values from ASCE 7-22 Figures/Tables or Screenshot hardcoded for now as placeholders or calc // Screenshot shows: // Wind Normal: L/B=0.47, h/L=1.01 // Wind Parallel: L/B=2.12, h/L=0.48 const rows = [ { label: 'Windward Wall (WW) @ h', cpNorm: 0.80, cpPar: 0.80, kvt: inputs.kvtWalls }, { label: 'Leeward Wall (LW) @ h', cpNorm: -0.50, cpPar: -0.29, kvt: inputs.kvtWalls }, { label: 'Side Wall (SW) @ h', cpNorm: -0.70, cpPar: -0.70, kvt: inputs.kvtWalls }, { label: 'Leeward Roof (LR)', cpNorm: 'Included', cpPar: 'Included', kvt: inputs.kvtRoofUplift }, // Special { label: 'Neg Windward Roof: 0 to h/2*', cpNorm: -1.10, cpPar: -0.90, kvt: inputs.kvtRoofUplift }, { label: 'Neg Windward Roof: > h/2*', cpNorm: -0.70, cpPar: -0.90, kvt: inputs.kvtRoofUplift }, { label: 'Neg Windward Roof: h to 2h*', cpNorm: null, cpPar: -0.50, kvt: inputs.kvtRoofUplift }, { label: 'Neg Windward Roof: > 2h*', cpNorm: null, cpPar: -0.30, kvt: inputs.kvtRoofUplift }, { label: 'Postmin windward roof press.', cpNorm: -0.18, cpPar: -0.18, kvt: inputs.kvtRoofUplift } ]; // GCpiT to use: Both + and - usually checked. Screenshot shows columns for +GCpiT and -GCpiT? // Actually screenshot columns: "+++", "w/+GCpiT", "w/-GCpiT" // "+++" is likely qhT * KdT * KvT * G * Cp (External Pressure only?) // Let's deduce headers. return (

Tornado Loads - MWFRS all h (Except for Open Buildings)

setInputs({ ...inputs, kdt: parseFloat(e.target.value) })} style={{ width: '60px' }} />
{qhT.toFixed(1)} psf
0.4 deg
{/* Derived from slope in geometry? */}
605 sf
286 sf
{buildingGeometry.buildingLength} ft
{buildingGeometry.leastWidth} ft
{tornado.h} ft
{gVal}
setInputs({ ...inputs, kvtRoofUplift: parseFloat(e.target.value) })} style={{ width: '60px' }} /> setInputs({ ...inputs, kvtWalls: parseFloat(e.target.value) })} style={{ width: '60px' }} />
Enclosed Building
GCpiT = +{inputs.gcpiT_pos} / {inputs.gcpiT_neg}
qi = qhT
Ultimate Tornado Surface Pressures (psf)
{rows.map((row, idx) => { const calcSet = (cp: number | string | null, kvt: number) => { if (typeof cp !== 'number') return { ext: '', pos: '', neg: '' }; const ext = qhT * inputs.kdt * kvt * gVal * cp; const pos = ext - (qi * inputs.gcpiT_pos); const neg = ext - (qi * inputs.gcpiT_neg); return { ext: ext.toFixed(1), plusGCpi: pos.toFixed(1), minusGCpi: neg.toFixed(1) }; }; const norm = calcSet(row.cpNorm, row.kvt); const par = calcSet(row.cpPar, row.kvt); return ( ); })}
Surface Wind Normal to Ridge Dist.* Wind Parallel to Ridge
+++ w/+qGCpT w/-qhGCpT +++ w/+qGCpT w/-qhGCpT
{row.label} {typeof row.cpNorm === 'number' ? row.cpNorm : ''} {norm.ext} {norm.plusGCpi} {norm.minusGCpi} {typeof row.cpPar === 'number' ? row.cpPar : ''} {par.ext} {par.plusGCpi} {par.minusGCpi}
+++ is qhTKdTKvTGCp
*Horizontal distance from windward edge
**Roof angle < 10 degrees. Therefore, leeward roof is included in windward roof pressure zones.
{/* Parapet Section Mockup */}
Windward roof overhangs : 20.1 psf (upward : add to +++ windward roof pressure)
); };