Sucção Máxima
diff --git a/app/src/lib/audit/scenarios.ts b/app/src/lib/audit/scenarios.ts
index da9e13e..bca0560 100644
--- a/app/src/lib/audit/scenarios.ts
+++ b/app/src/lib/audit/scenarios.ts
@@ -17,6 +17,13 @@ import { evaluateComfort } from '../comfort';
import { classifyBridge, type BridgeClassificationInput } from '../modules/bridge';
import { calculateTower } from '../modules/tower';
import { calculatePiperack, type PiperackInput } from '../modules/piperack';
+import { calculateVault, type VaultInput } from '../modules/vault';
+import { calculateDome, type DomeInput } from '../modules/dome';
+import { calculateIsolatedGableRoof, calculateIsolatedShedRoof } from '../nbr-tables/table-24-25';
+import { calculateFlatBarForce, type FlatBarForceInput } from '../nbr-tables/table-26';
+import { applyRoughnessChange } from '../wind-direction';
+import { TABLE_1 } from '../nbr-tables/table-1';
+import { getStrouhalNumber, criticalVelocity, scrutonNumber } from '../nbr-tables/table-33';
function calcWind(
v0: number, s1: number, s3: number,
@@ -267,6 +274,209 @@ export function generateAllScenarios(): AuditScenario[] {
));
}
+ // --- NOVOS CENÁRIOS BIBLIOGRÁFICOS EXPANDIDOS (LITERATURA & NBR 6123) ---
+
+ // 1.1 Abóbada Cilíndrica (Blessmann / Tabela 15 NBR 6123)
+ {
+ const vaultIn: VaultInput = { f: 4, l: 20, b: 40, vk: 35, regime: 'laminar-rough', cpi: 0 };
+ const vaultRes = calculateVault(vaultIn);
+ scenarios.push(makeScenario(
+ 'blessmann-abobada-f4-l20', 'vault', 'Blessmann: Abóbada Cilíndrica f=4m l=20m b=40m',
+ { ...vaultIn },
+ { q: vaultRes.q, fOverL: 4 / 20 },
+ { ...vaultRes.windPerpendicular, q: vaultRes.q },
+ { q: { min: 0.5, max: 1.5 } },
+ 'vault',
+ { f: 4, l: 20, b: 40, cpeValues: vaultRes.windPerpendicular },
+ 'Sec. 6.2.3 / Tabela 15',
+ true,
+ 'Blessmann, J. Ação do Vento em Coberturas Curvas e Abóbadas, Exemplo 3.2 / NBR 6123:2023 Tabela 15',
+ 'Abóbada cilíndrica com vão de 20m, flecha de 4m (f/l = 0,20) e comprimento de 40m sob vento perpendicular de 35 m/s. Avaliação da sucção no topo e pressões no bordo de ataque.'
+ ));
+ }
+
+ // 1.2 Cúpula Semiesférica apoiada no solo (Rebello / Tabela 21 NBR 6123)
+ {
+ const domeIn: DomeInput = { d: 30, f: 6, vk: 40, type: 'on-ground', cpi: 0 };
+ const domeRes = calculateDome(domeIn);
+ scenarios.push(makeScenario(
+ 'rebello-cupula-d30-f6', 'dome', 'Rebello: Cúpula no Solo d=30m f=6m',
+ { ...domeIn },
+ { q: domeRes.q, fOverD: domeRes.fOverD },
+ { cpeBarlavento: domeRes.cpeBarlavento, cpeTopo: domeRes.cpeTopo, liftCoefficient: domeRes.liftCoefficient, liftForceKN: domeRes.liftForceKN },
+ { q: { min: 0.5, max: 1.8 }, liftForceKN: { min: 50, max: 1000 } },
+ 'dome',
+ { d: 30, f: 6, cpeTopo: domeRes.cpeTopo, cpeBarlavento: domeRes.cpeBarlavento },
+ 'Sec. 6.2.4 / Tabela 21',
+ true,
+ 'Rebello, Y. A Concepção Estrutural e a Arquitetura / NBR 6123 Tabela 21 (Cúpulas sobre o solo)',
+ 'Cúpula esférica implantada diretamente no terreno com diâmetro d=30m e flecha f=6m (f/d = 0,20). Determinação da força global de sustentação aerodinâmica (empuxo ascendente) para velocidade característica de 40 m/s.'
+ ));
+ }
+
+ // 1.3 Cobertura Isolada a Duas Águas - Hangar Aberto (Pfeil / Tabela 25 NBR 6123)
+ {
+ const isoIn = { theta: 10, height: 5, depth: 15 };
+ const isoRes = calculateIsolatedGableRoof(isoIn);
+ scenarios.push(makeScenario(
+ 'pfeil-cobertura-isolada-2aguas', 'isolated-roof', 'Pfeil: Cobertura Isolada 2 Águas θ=10°',
+ { ...isoIn, q: 0.85 },
+ { cpb1: isoRes.cpb.cpb1, cpa1: isoRes.cpa.cpa1 },
+ { cpb1: isoRes.cpb.cpb1, cpb2: isoRes.cpb.cpb2, cpa1: isoRes.cpa.cpa1, cpa2: isoRes.cpa.cpa2, applies: isoRes.applies ? 1 : 0 },
+ { cpb1: { min: 0.5, max: 2.0 }, cpa1: { min: -2.0, max: -0.5 } },
+ 'isolatedRoof',
+ { theta: 10, height: 5, depth: 15, cpa: isoRes.cpa, cpb: isoRes.cpb },
+ 'Sec. 7.2 / Tabela 25',
+ true,
+ 'Pfeil & Pfeil, Estruturas de Aço, 8ª ed., Cap. 5 (Galpões Abertos e Hangares Isolados) / NBR 6123 Tabela 25',
+ 'Cobertura isolada simétrica de duas águas com inclinação de 10° e pé-direito livre h=5m (b=15m). Análise dos coeficientes de pressão líquida nos carregamentos extremos de sobrepressão e sucção.'
+ ));
+ }
+
+ // 1.4 Cobertura Isolada a Uma Água - Marquise / Abrigo (NBR 6123 Tabela 24)
+ {
+ const shedIn = { theta: 5, height: 3.5, depth: 10 };
+ const shedRes = calculateIsolatedShedRoof(shedIn);
+ scenarios.push(makeScenario(
+ 'nbr-marquise-isolada-1agua', 'isolated-roof', 'NBR 6123: Marquise Isolada a Uma Água θ=5°',
+ { ...shedIn, q: 0.95 },
+ { cph1High: shedRes.cph1.high, cph1Low: shedRes.cph1.low },
+ { cph1High: shedRes.cph1.high, cph1Low: shedRes.cph1.low, applies: shedRes.applies ? 1 : 0 },
+ { cph1High: { min: -1.5, max: 0.0 }, cph1Low: { min: -2.5, max: -0.5 } },
+ 'isolatedRoof',
+ { theta: 5, height: 3.5, depth: 10 },
+ 'Sec. 7.2.1 / Tabela 24',
+ true,
+ 'NBR 6123:2023, Tabela 24 — Coberturas isoladas a uma água plana / Exemplo Didático CBCA',
+ 'Marquise/alpendre isolado a 1 água com inclinação suave de 5° e altura de 3.5m. Verificação dos coeficientes médios e limites de sucção no bordo de ataque.'
+ ));
+ }
+
+ // 1.5 Torre Treliçada Triangular de Telecomunicações (NBR 6123 Tabela 29/30 & Blessmann)
+ {
+ const towerIn = { section: 'triangular' as const, barType: 'flat' as const, phi: 0.25, aFace: 90, alphaWind: 0 as const, q: 1.15 };
+ const towerRes = calculateTower(towerIn);
+ scenarios.push(makeScenario(
+ 'blessmann-torre-triangular-phi025', 'tower', 'Blessmann: Torre Triangular φ=0.25',
+ { ...towerIn },
+ { caEff: towerRes.caEff },
+ { caEff: towerRes.caEff, forceKN: towerRes.forceKN },
+ { caEff: { min: 1.5, max: 3.5 }, forceKN: { min: 100, max: 500 } },
+ 'tower',
+ { section: 'triangular', baseWidth: 3, height: 30, panels: 6, phi: 0.25, alphaWind: 0, forceKN: towerRes.forceKN },
+ 'Sec. 8.5 / Tabelas 29-30',
+ true,
+ 'Blessmann, J. Ação do Vento em Torres e Estruturas Treliçadas, Cap. 7 / NBR 6123:2023 Sec. 8.5',
+ 'Torre treliçada de seção triangular equilátera com índice de plenitude φ=0,25 e área projetada da face de 90 m² submetida a vento frontal (0°). Cálculo do coeficiente de arrasto efetivo e da força global na torre.'
+ ));
+ }
+
+ // 1.6 Barra Isolada Perfil L / Cantoneira de Torre (Pfeil & NBR 6123 Tabela 26)
+ {
+ const barIn: FlatBarForceInput = { section: 'l', alpha: 45, width: 0.15, length: 3.0, q: 1.05 };
+ const barRes = calculateFlatBarForce(barIn);
+ scenarios.push(makeScenario(
+ 'pfeil-cantoneira-l-alpha45', 'bar', 'Pfeil: Cantoneira L150x150 sob Vento a 45°',
+ { ...barIn },
+ { cx: barRes.cx, cy: barRes.cy, kFactor: barRes.kFactor },
+ { fxKN: barRes.fxKN, fyKN: barRes.fyKN, cx: barRes.cx, cy: barRes.cy },
+ { cx: { min: 1.0, max: 2.2 }, cy: { min: 1.0, max: 2.2 }, fxKN: { min: 0.5, max: 2.0 } },
+ 'bar',
+ { section: 'l', width: 0.15, length: 3.0, alpha: 45, fxKN: barRes.fxKN, fyKN: barRes.fyKN },
+ 'Sec. 8.1 / Tabelas 26 e 28',
+ true,
+ 'Pfeil, M. & Pfeil, W. Estruturas de Aço, Cap. Ações em Barras Isoladas / NBR 6123 Tabela 26',
+ 'Barra prismática isolada de seção cantoneira de abas iguais (L 150x150 mm) com 3 metros de comprimento livre, sob incidência oblíqua do vento a 45°. Determinação das componentes de força Cx, Cy e redução por comprimento finito (Fator K).'
+ ));
+ }
+
+ // 1.7 Galpão Extenso — Força de Atrito Superficial (Blessmann Cap. 5 / NBR 6123 Sec. 6.1.5)
+ {
+ const fricIn = { roughness: 'rounded-ribs' as const, length: 80, width: 15, height: 6, roofPitch: 8, q: 1.0, windAngle: 0 as const };
+ const fricRes = calculateFriction(fricIn);
+ scenarios.push(makeScenario(
+ 'blessmann-galpao-extenso-atrito', 'galpao', 'Blessmann: Galpão Extenso 80x15m — Atrito Superficial',
+ { ...fricIn },
+ { applies: fricRes.applies ? 1 : 0, ratioLh: 80 / 6 },
+ { applies: fricRes.applies ? 1 : 0, forceKN: fricRes.forceKN, roofArea: fricRes.roofArea, cf: fricRes.cf },
+ { forceKN: { min: 10, max: 50 }, roofArea: { min: 1000, max: 1500 } },
+ 'warehouse',
+ { width: 15, length: 80, height: 6, roofPitch: 8, windAngle: 0, cpi: 0 },
+ 'Sec. 6.1.5',
+ true,
+ 'Blessmann, J. O Vento na Engenharia Estrutural, Cap. 5 (Forças de Atrito em Edificações Longas) / NBR 6123 Sec. 6.1.5',
+ 'Galpão industrial longo de 80 metros de comprimento por 15m de largura e 6m de altura (l/h = 13,3 > 4). Telhas com nervuras onduladas/arredondadas (Cf = 0,02). Cálculo da força de arrasto por atrito superficial na cobertura.'
+ ));
+ }
+
+ // 1.8 Transição de Rugosidade de Terreno — Litoral para Centro Urbano (NBR 6123 Sec. 5.5)
+ {
+ const transIn = { near: 'IV' as TerrainCategory, far: 'I' as TerrainCategory, distance: 500, height: 30 };
+ const params = new Map
();
+ (['I', 'II', 'III', 'IV', 'V'] as TerrainCategory[]).forEach(cat => {
+ params.set(cat, TABLE_1[cat].B);
+ });
+ const transRes = applyRoughnessChange(transIn, params);
+ scenarios.push(makeScenario(
+ 'nbr-transicao-rugosidade-catI-IV', 'galpao', 'NBR 6123: Transição de Rugosidade Cat I -> Cat IV (x=500m, z=30m)',
+ { ...transIn },
+ { z1: transRes.z1, z2: transRes.z2, s2: transRes.s2 },
+ { s2: transRes.s2, z1: transRes.z1 },
+ { s2: { min: 0.8, max: 1.3 } },
+ 'warehouse',
+ { width: 20, length: 40, height: 30, roofPitch: 0, windAngle: 0, cpi: 0 },
+ 'Sec. 5.5',
+ true,
+ 'NBR 6123:2023, Seção 5.5 (Mudança de Rugosidade do Terreno) / Notas de Aula Prof. Blessmann',
+ 'Edificação de 30m de altura situada a 500 metros da linha de transição costeira (saída de Terreno Aberto Cat. I para Zona Urbana Densa Cat. IV). Determinação da altura da camada limite interna (z1) e do fator S2 interpolado.'
+ ));
+ }
+
+ // 1.9 Desprendimento de Vórtices em Chaminé Esbelta (Strouhal & Scruton — NBR 6123 Sec. 10)
+ {
+ const st = getStrouhalNumber('circle', 0); // 0.20
+ const fn = 1.2; // Hz
+ const d = 1.5; // m
+ const vcr = criticalVelocity(fn, d, st); // 1.2 * 1.5 / 0.20 = 9.0 m/s
+ const sc = scrutonNumber(0.02, 600, 1.225, 1.5); // 0.02 * 600 / (1.225 * 1.5) = 6.53
+ scenarios.push(makeScenario(
+ 'nbr-vortices-chamine-strouhal', 'dynamics', 'NBR 6123: Vórtices de Von Kármán em Chaminé Cilíndrica',
+ { shape: 'circle', diameter: d, naturalFreq: fn, massPerLength: 600, dampingRatio: 0.02 },
+ { st, vcr, sc },
+ { st, vcr, sc, isSusceptible: sc < 20 ? 1 : 0 },
+ { vcr: { min: 5, max: 20 }, sc: { min: 2, max: 20 } },
+ 'dynamics',
+ { height: 45, freq: fn, windSpeed: vcr, scruton: sc, sectionShape: 'circle', sectionSize: d },
+ 'Sec. 10 / Tabela 33',
+ true,
+ 'NBR 6123:2023, Seção 10 (Efeitos Dinâmicos de Desprendimento de Vórtices) & Simiu & Scanlan',
+ 'Chaminé metálica esbelta circular com d=1.5m, frequência natural fundamental fn=1.2 Hz, massa linear de 600 kg/m e amortecimento estrutural ξ=0,02. Cálculo do Número de Strouhal (St=0,20), velocidade crítica de ressonância (Vcr) e Número de Scruton (Sc).'
+ ));
+ }
+
+ // 1.10 Pipe-Rack Industrial com Múltiplos Planos (NBR 6123 Sec. 8.4 / Blessmann)
+ {
+ const pipeIn: PiperackInput = {
+ width: 12, height: 5, elevation: 8, spacing: 6, numFrames: 4, phiStruct: 0.20,
+ pipes: [{ id: 'p1', diameter: 0.6, elevationOffset: 5 }, { id: 'p2', diameter: 0.6, elevationOffset: 5 }],
+ q: 1.10
+ };
+ const pipeRes = calculatePiperack(pipeIn);
+ scenarios.push(makeScenario(
+ 'blessmann-piperack-4quadros', 'piperack', 'Blessmann: Pipe-Rack Industrial 4 Quadros com Tubulações',
+ { ...pipeIn },
+ { phiTotal: pipeRes.phiTotal, effectiveElevation: pipeRes.effectiveElevation },
+ { caFrontal: pipeRes.caFrontal, eta: pipeRes.eta, globalForce: pipeRes.globalForce },
+ { caFrontal: { min: 1.5, max: 3.0 }, eta: { min: 0.4, max: 1.0 }, globalForce: { min: 10, max: 300 } },
+ 'warehouse',
+ { width: 12, height: 5, length: 24 },
+ 'Sec. 8.4',
+ true,
+ 'Blessmann, J. Ação do Vento em Estruturas Industriais e Reticulados / NBR 6123:2023 Sec. 8.4',
+ 'Pipe-rack industrial contendo 4 pórticos transversais espaçados de 6m com bandejas de cabos e 2 linhas de tubulação de 600mm de diâmetro. Cálculo do índice de plenitude total (φ), fator de sombreamento (η) e carga de arrasto global.'
+ ));
+ }
+
// 2. GALPÃO VARREDURA
const galpaoGeos = [
{ w: 10, l: 20, h: 4 }, { w: 15, l: 30, h: 6 }, { w: 20, l: 50, h: 8 },
diff --git a/app/src/pages/Compare.tsx b/app/src/pages/Compare.tsx
deleted file mode 100644
index c6f6f2e..0000000
--- a/app/src/pages/Compare.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import { useGalpaoStore } from '../store/galpaoStore';
-import { getWallCpeOfficial as getWallCpe, getRoofCpeOfficial as getRoofCpe } from '../lib/coefficients';
-import Heatmap2D from '../components/Heatmap2D';
-
-const Compare: React.FC = () => {
- const { length, width, height, roofPitch } = useGalpaoStore();
-
- const wallCpe0 = getWallCpe(length, width, height, 0);
- const roofCpe0 = getRoofCpe(length, width, height, roofPitch, 0);
-
- const wallCpe90 = getWallCpe(length, width, height, 90);
- const roofCpe90 = getRoofCpe(length, width, height, roofPitch, 90);
-
- return (
-
-
Comparação A/B (0° vs 90°)
-
Compare visualmente a distribuição de pressões (Cpe - Cpi) nas duas direções normativas simultaneamente.
-
-
-
-
-
-
- );
-};
-
-export default Compare;
diff --git a/app/src/pages/GalpaoModule.tsx b/app/src/pages/GalpaoModule.tsx
index 5bc1e19..92cf955 100644
--- a/app/src/pages/GalpaoModule.tsx
+++ b/app/src/pages/GalpaoModule.tsx
@@ -1,5 +1,4 @@
import React from 'react';
-import { Link } from 'react-router-dom';
import Warehouse3DViewer from '../components/Warehouse3D';
import Heatmap2D from '../components/Heatmap2D';
import LinearLoadsTable from '../components/LinearLoadsTable';
@@ -8,6 +7,7 @@ import FtoolExportCard from '../components/FtoolExportCard';
import { CpiSettingsCard } from '../components/CpiSettingsCard';
import { useGalpaoStore } from '../store/galpaoStore';
import { useWindStore } from '../store/appStore';
+import { getWallCpeOfficial as getWallCpe, getRoofCpeOfficial as getRoofCpe } from '../lib/coefficients';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Slider } from '@/components/ui/slider';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
@@ -16,7 +16,7 @@ import { Separator } from '@/components/ui/separator';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
-import { AlertCircle, Lightbulb, Box, Wind, Columns } from 'lucide-react';
+import { AlertCircle, Lightbulb, Box, Wind } from 'lucide-react';
import ExportMenu from '../components/ExportMenu';
import { EducationalManual } from '@/components/EducationalManual';
import { PressureLegend } from '@/components/PressureLegend';
@@ -280,25 +280,17 @@ const GalpaoModule: React.FC = () => {
Modelo 3D
Heatmap 2D
+ Modo A/B