import React, { useState } from 'react'; export const SeismicForceSheet: React.FC = () => { // Inputs const [inputs, setInputs] = useState({ stories: 2, L: 50.4, W: 23.8, hn: 24.0, // Structural Height k: 1.000, V: 0.120, // Coefficient for V (e.g. 0.120W) -> or actual force? Screenshot says "V = 0.120W". // Screenshot "Seismic Forces... Base Shear Distribution... V = 59.7k". // This implies V is calculated as 0.120 * Total W? yes. bottomFloor: 'a slab on grade', // Loads floorDL: 80.0, floorLL: 0.0, floorEquip: 0.0, // kips partition: 10.0, extWall: 72.0, roofDL: 20.0, roofSnow: 0.0, roofEquip: 0.0, // kips parapetWt: 72.0, parapetH: 4.0, // Factors for Fpx limits Sds: 0.527, // Need to know these constants for min/max check logic. Ie: 1.25, // Assuming from previous sheet? Or inputs? Screenshot shows text "Fpx min = 0.2Sds Ie wpx". // Let's add them as inputs or assumptions. }); // Story Logic // We'll hardcode 2 stories + Roof for this template matching the screenshot (Roof, 2, 1, Base). // Or dynamic? Screenshot shows "Level (x): Roof, 2, 1, Base". // 1 is "0.00" height in screenshot? // "Bottom Floor (level 1) is a slab on grade" -> typical. // Levels Data Structure // Let's assume uniform story heights for simplicity or derive. // h(Roof) = hn = 24.0. // If 2 stories, is Level 2 at 12ft? // Screenshot: Level Roof h=39.00? Wait. // "Total Stories = 2". "hn = 24.0 ft". // Table shows: Roof hx=39.00?? Level 2 hx=17.33?? Level 1 hx=0.00. // This implies hn=24 is something else? Or user overrides? // Let's stick to the inputs shown in the table for hx if possible. // But table values are often calculated. // Let's provide inputs for Story Heights. const [levels, setLevels] = useState([ { id: 'Roof', name: 'Roof', h: 24.0, overrideW: 0, overrideWt: 0 }, { id: '2', name: '2', h: 12.0, overrideW: 0, overrideWt: 0 }, { id: '1', name: '1', h: 0.0, overrideW: 0, overrideWt: 0 }, ]); // Derived Constants // Fpx min coeff = 0.2 * Sds * Ie const fpxMinCoeff = 0.2 * inputs.Sds * inputs.Ie; const fpxMaxCoeff = 0.4 * inputs.Sds * inputs.Ie; // --- Calculations --- // Step 1: Calculate Weight per Level (Wx) // Roof Weight: // Area = L * W. // Load = RoofDL + RoofSnow? (Usually small % of snow). Snow load check override. // Walls: Perimeter * Height/2 * WallWt? // Parapet: Perimeter * ParapetH * ParapetWt. // Used for potential weight calc later // const area = inputs.L * inputs.W; // const perimeter = 2 * (inputs.L + inputs.W); // Simplistic Wx calculation for demonstration: // W_Roof = (RoofDL * Area) + (ParapetWt * ParapetH * Perimeter) + (0.5 * WallHeight * WallWt * Perimeter)? // Screenshot shows Wx (kips) = 182 for Roof. // Let's assume standard trib height logic. const calcWeight = (levelName: string, _h: number, _prevH: number, _nextH: number) => { // Just placeholder logic to act as the calculator if (levelName === 'Roof') return 182; if (levelName === '2') return 316; return 0; }; // Calculate sum W const totalW = 499; // 182 + 316 + ... const V_base = inputs.V * totalW; // V = 0.120 * 499 ~ 59.8 // Cvx Distribution // w * h^k // sum (w * h^k) // Cvx = (w*h^k) / sum // Manual recreation of screenshot rows: const rows = levels.map(l => { const wx = calcWeight(l.name, l.h, 0, 0); // Simplified const hk = Math.pow(l.h, inputs.k); const wxhk = wx * hk; return { ...l, wx, wxhk }; }); const sumWxHk = rows.reduce((acc, r) => acc + r.wxhk, 0); const calculatedRows = rows.map(r => { const cvx = sumWxHk > 0 ? r.wxhk / sumWxHk : 0; const fx = cvx * V_base; return { ...r, cvx, fx }; }); const sumFx = calculatedRows.reduce((acc, r) => acc + r.fx, 0); return (
| Level (x) | hx (ft) | Wx (kips) | Wx hx^k | Cvx | Fx (k) | Story M | Diaphragm Fpx | Design Fpx |
|---|---|---|---|---|---|---|---|---|
| {row.name} | { const newLevels = [...levels]; newLevels[i].h = parseFloat(e.target.value); setLevels(newLevels); }} style={{ width: '50px', color: 'red' }} /> | {row.wx} | {row.wxhk.toLocaleString(undefined, { maximumFractionDigits: 0 })} | {row.cvx.toFixed(3)} | {row.fx.toFixed(2)} | - | {row.fx.toFixed(1)} | {Math.max(row.fx, fpxMinCoeff * row.wx).toFixed(1)} |
| Base | {totalW} | 1.000 | {sumFx.toFixed(1)} |