import React, { useState } from 'react'; import { useCalculatorStore } from '../../../store/calculatorStore'; import { MwfrsLongitudinalFramesDiagram } from './MwfrsLongitudinalFramesDiagram'; interface Props { qh: number; GCpi: number; } export const MwfrsOpenLowRiseSection: React.FC = ({ qh, GCpi }) => { const { buildingGeometry, wind } = useCalculatorStore(); // Inputs const [numFrames, setNumFrames] = useState(4); const [solidAreaAs, setSolidAreaAs] = useState(26.0); // Geometry const B = buildingGeometry.leastWidth; const h = buildingGeometry.meanRoofHeight; const slopeStr = buildingGeometry.roofSlope; // e.g. "0.5 / 12" // Parse Slope const parseSlope = (s: string) => { const parts = s.split('/'); if (parts.length > 0) return parseFloat(parts[0]); return 0; }; const slopeVal = parseSlope(slopeStr); // Rise per 12 run const risePerFoot = slopeVal / 12; const totalRise = risePerFoot * (B / 2); // Assuming Gable centered // Calculate Heights // Mean Roof Height (h) = (He + Hr) / 2 // Hr = He + totalRise // h = (He + He + totalRise) / 2 = He + totalRise/2 // He = h - totalRise/2 const eaveHeight = h - (totalRise / 2); const ridgeHeight = h + (totalRise / 2); // Calculate Ae (Total end wall area if solid) // Rectangular part + Triangular part const areaRect = B * eaveHeight; // This assumes B is the full width const areaTri = 0.5 * B * totalRise; const Ae = areaRect + areaTri; // Validations const isEnclosed = wind.enclosure.classification === 'Enclosed'; const isTooHigh = h > 60 || h > B; // Screenshot says "h>B - can't use low-rise method" return (
Wind Loads - h≤60' Longitudinal Direction MWFRS On Open or Partially
Enclosed Buildings with Transverse Frames and Pitched Roofs
{/* Validation Errors */} {isTooHigh && (
(Kd qh) = 0.0 psf h>B - can't use low-rise method
)} {isEnclosed && (
GCpi = {GCpi} Enclosed bldg, procedure doesn't apply
)}
Roof Angle (θ) = {(Math.atan(slopeVal / 12) * 180 / Math.PI).toFixed(1)} deg
{/* Diagram */}
{/* Inputs & Outputs */}
B = {B.toFixed(1)} ft
# of frames (n) = setNumFrames(parseFloat(e.target.value) || 0)} style={{ width: '60px', marginLeft: '10px', color: 'red', fontWeight: 'bold' }} />
Solid area of end wall including fascia (As) = setSolidAreaAs(parseFloat(e.target.value) || 0)} style={{ width: '60px', marginLeft: '10px', color: 'red', fontWeight: 'bold' }} /> sf
Roof ridge height = {ridgeHeight.toFixed(1)} ft
Roof eave height = {eaveHeight.toFixed(1)} ft
Total end wall area if solid (Ae) = {Ae.toFixed(1)} sf
{/* Calculations Section */}
); }; // Sub-component for Calculation Logic to keep main component clean const LongitudinalForceCalc: React.FC<{ qh: number, Ae: number, As: number, n: number }> = ({ qh, Ae, As, n }) => { // Inputs (Defaults from screenshot) const [netGCpf, setNetGCpf] = useState(0.734); const [KB, setKB] = useState(1.562); const [KS, setKS] = useState(0.678); // Areas (Not used in formula directly shown but present in screenshot) const [area56, setArea56] = useState(500); const [area5E6E, setArea5E6E] = useState(72); const phi = Ae > 0 ? As / Ae : 0; // p = qh * [Net GCpf] * KB * KS const p = qh * netGCpf * KB * KS; // F = p * Ae ? // Screenshot: "Longitudinal Directional Force (F) = pAe" // F in kips = (p * Ae) / 1000 const F_kips = (p * Ae) / 1000; return (
Longitudinal Directional Force (F) = pAe
p= qh [(GCpf)windward -(GCpf)leeward] KB KS
Solidarity ratio (Φ) =
{phi.toFixed(3)}
n =
{n}
KB =
setKB(parseFloat(e.target.value) || 0)} className="input-field minimal" style={{ width: '60px', textAlign: 'right' }} />
KS =
setKS(parseFloat(e.target.value) || 0)} className="input-field minimal" style={{ width: '60px', textAlign: 'right' }} />
Zones 5 & 6 area =
setArea56(parseFloat(e.target.value) || 0)} className="input-field minimal" style={{ width: '60px', textAlign: 'right' }} /> sf
5E & 6E area =
setArea5E6E(parseFloat(e.target.value) || 0)} className="input-field minimal" style={{ width: '60px', textAlign: 'right' }} /> sf
(GCpf) windward - (GCpf) leeward] =
setNetGCpf(parseFloat(e.target.value) || 0)} className="input-field minimal" style={{ width: '60px', textAlign: 'right' }} />
p =
{p.toFixed(1)} psf
Total force to be resisted by MWFRS (F) =   {F_kips.toFixed(1)} kips applied at the centroid of the end wall area Ae
Note: The longitudinal force acts in combination with roof loads calculated elsewhere for an open or partially enclosed building.
); };