diff --git a/app/src/components/EducationalManual.tsx b/app/src/components/EducationalManual.tsx index 604e844..44882c6 100644 --- a/app/src/components/EducationalManual.tsx +++ b/app/src/components/EducationalManual.tsx @@ -1,4 +1,5 @@ -import { BookOpen, HelpCircle } from 'lucide-react'; +import React from 'react'; +import { HelpCircle, Info, Settings2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Sheet, @@ -23,6 +24,144 @@ export function EducationalManual({ type, params }: EducationalManualProps) { return null; } + // Gera explicações interpretativas dinâmicas com base nas opções selecionadas no painel + const renderConfigurationExplanation = () => { + const explanations: React.ReactNode[] = []; + + // --- Abóbadas (vault) --- + if (type === 'vault') { + const regime = params.regime || 'laminar-rough'; + const cpi = Number(params.localCpi || 0); + + // Regime de escoamento + if (regime === 'laminar-rough') { + explanations.push( +
+ Escoamento: Baixa Turbulência (Tabelas 15-17) +

Representa vento uniforme sobre terreno desobstruído. O escoamento flui de forma limpa sobre o arco, gerando os valores tradicionais de sucção no topo.

+
+ ); + } else { + explanations.push( +
+ Escoamento: Regime Turbulento (Tabelas 18-20) +

O vento apresenta alta turbulência devido a obstáculos no terreno. As correntes de vento ondulantes (exibidas no simulador) induzem picos de pressões dinâmicas flutuantes.

+
+ ); + } + + // Permeabilidade (Cpi) + if (cpi === 0) { + explanations.push( +
+ Pressão Interna Neutralizada (Cpi = 0.0) +

As aberturas são inexistentes ou estão distribuídas igualmente nas faces. A força resultante no arco depende exclusivamente da sucção externa.

+
+ ); + } else if (cpi > 0) { + explanations.push( +
+ Abóbada Inflada (Cpi = +{cpi}) +

Uma abertura dominante na face de barlavento permite a entrada do ar, "inflando" a abóbada de dentro para fora (indicado pelas setas laranjas). Essa pressão interna empurra a cobertura para cima, somando-se à sucção externa do vento e aumentando de forma crítica a força de arrancamento do telhado!

+
+ ); + } else { + explanations.push( +
+ Abóbada Sugada / Vácuo (Cpi = {cpi}) +

Com aberturas dominantes nas faces protegidas (laterais ou sotavento), o ar interno é sugado para fora, criando um vácuo interno (setas azuis). Esse efeito de vácuo ajuda a compensar e aliviar a sucção externa no topo, mas puxa as paredes para dentro.

+
+ ); + } + } + + // --- Cilindros (cylinder) --- + if (type === 'cylinder') { + const isSmooth = params.surface === 'smooth'; + const cpi = Number(params.cpi || 0); + + explanations.push( +
+ Superfície: {isSmooth ? 'Lisa' : 'Rugosa'} +

{isSmooth + ? 'Superfície de baixo atrito. No regime supercrítico, o descolamento da camada limite é atrasado significativamente, fazendo o coeficiente de arrasto Ca cair para valores muito baixos (~0.4).' + : 'Casca áspera. A rugosidade gera microturbulências na superfície do cilindro que impedem a esteira de estreitar excessivamente, mantendo o arrasto Ca em níveis elevados no regime crítico/supercrítico.' + }

+
+ ); + + if (cpi > 0) { + explanations.push( +
+ Reservatório Inflado (Cpi positivo) +

O ar interno pressiona as paredes do silo/chaminé de dentro para fora, somando-se às sucções externas nas laterais.

+
+ ); + } + } + + // --- Muros e Placas (sign) --- + if (type === 'sign') { + const hasEndPlates = params.hasEndPlates === true; + const alpha = Number(params.alpha || 90); + + explanations.push( +
+ Incidência do Vento: {alpha}º +

{alpha === 90 + ? 'Vento Perpendicular: o arrasto atua uniformemente, concentrando a força resultante exatamente no centro da placa (sem torque de torção nas fundações).' + : 'Vento Oblíquo: o fluxo se concentra na borda esquerda de ataque. Isso gera uma excentricidade horizontal na força (e = 0.25 L), introduzindo um momento torsor crítico que deve ser suportado pelos pilares.' + }

+
+ ); + + explanations.push( +
+ Abas Laterais (End Plates): {hasEndPlates ? 'Com abas' : 'Sem abas'} +

{hasEndPlates + ? 'As abas vermelhas mostradas no simulador impedem o ar de escapar pelas laterais do muro, gerando um escoamento bidimensional plano que eleva a força de arrasto Cf ao máximo.' + : 'O vento escoa tridimensionalmente pelas bordas laterais livres, criando um efeito de alívio aerodinâmico que reduz a força resultante nas pontas do muro.' + }

+
+ ); + } + + // --- Galpões (warehouse) --- + if (type === 'warehouse') { + const cpi = Number(params.cpi || 0); + + if (cpi > 0) { + explanations.push( +
+ Galpão Inflado (Cpi = +{cpi}) +

Ocorre quando há aberturas dominantes na parede de barlavento (frente). O ar "sopra" para dentro e expande o galpão de dentro para fora, somando-se à sucção externa do telhado e aumentando de forma gravíssima o risco de arrancamento da cobertura!

+
+ ); + } else if (cpi < 0) { + explanations.push( +
+ Galpão Desinflado / Vácuo (Cpi = {cpi}) +

Ocorre com aberturas nas paredes laterais ou de trás (sotavento). O ar interno é sugado, puxando as chapas do telhado para dentro e ajudando a contrapor a sucção do vento externo.

+
+ ); + } + } + + if (explanations.length === 0) return null; + + return ( +
+
+ +

Análise das Suas Configurações

+
+
+ {explanations} +
+
+ ); + }; + return ( @@ -32,7 +171,7 @@ export function EducationalManual({ type, params }: EducationalManualProps) { className="size-10 bg-background/80 backdrop-blur-xs border border-border shadow-md hover:bg-accent/80 transition-all rounded-full flex items-center justify-center" title="Manual Didático da Norma NBR 6123" > - + @@ -49,6 +188,9 @@ export function EducationalManual({ type, params }: EducationalManualProps) { {/* Simulador Interativo 2D no topo do manual */} + {/* Quadro Dinâmico explicativo dos seletores */} + {renderConfigurationExplanation()} + {/* Seções de Texto e Fórmulas */}
{manual.sections.map((section, idx) => ( diff --git a/app/src/components/WindFlowGrid2D.tsx b/app/src/components/WindFlowGrid2D.tsx index 07bf1a9..29a8e0d 100644 --- a/app/src/components/WindFlowGrid2D.tsx +++ b/app/src/components/WindFlowGrid2D.tsx @@ -1,12 +1,11 @@ - interface WindFlowGrid2DProps { type: string; params: Record; } export function WindFlowGrid2D({ type, params }: WindFlowGrid2DProps) { - // Estilo global de animação inserido no próprio SVG + // Estilos globais e animações integrados no SVG const styleBlock = ( ); - // Renderizadores específicos de fluxo ativo com base nos sliders da página + const getViewLabel = () => { + switch (type) { + case 'tower': + case 'cylinder': + case 'bar': + return 'Vista Aérea (Superior / Planta Baixa)'; + case 'bridge': + case 'sign': + case 'warehouse': + case 'vault': + case 'dome': + case 'dynamics': + case 'isolated-roof': + return 'Vista Lateral (Corte Transversal)'; + default: + return 'Vista Esquemática'; + } + }; + + // Desenha os vetores de Cpi (pressão interna) dentro do perfil do galpão/cilindro/abóbada + const renderCpiVectors = (cpi: number, shape: 'rect' | 'arch' | 'circle' | 'dome') => { + if (cpi === 0) return null; + const isPositive = cpi > 0; + const marker = isPositive ? 'url(#cpi-pos)' : 'url(#cpi-neg)'; + const strokeClass = isPositive ? 'cpi-arrow-pos' : 'cpi-arrow-neg'; + + if (shape === 'arch') { + // Abóbada: 3 vetores radiais + return ( + + {isPositive ? ( + <> + + + + + ) : ( + <> + + + + + )} + + ); + } + + if (shape === 'rect') { + // Galpão: paredes e telhado + return ( + + {isPositive ? ( + <> + {/* Paredes */} + + + {/* Telhado */} + + + + ) : ( + <> + + + + + + )} + + ); + } + + if (shape === 'circle') { + // Cilindro: 4 direções + return ( + + {isPositive ? ( + <> + + + + + + ) : ( + <> + + + + + + )} + + ); + } + + if (shape === 'dome') { + // Cúpula + return ( + + {isPositive ? ( + <> + + + + + + + ) : ( + <> + + + + + + + )} + + ); + } + + return null; + }; + const renderActiveSimulation = () => { switch (type) { case 'bridge': { const alpha = Number(params.alpha || 0); - // O vento muda de ângulo - const rotationAngle = alpha * 3; // amplifica o ângulo para ficar visível + const rotationAngle = alpha * 3; return ( -
-

Simulação Ativa (com suas variáveis)

-
- - {styleBlock} - {/* Linhas de vento de fundo */} - - - - - - - {/* Linhas aceleradas acima e abaixo */} - - - + + {styleBlock} + + + + + + + + - {/* Tabuleiro da ponte */} - - - {/* Barreiras de proteção */} - - - + + + + + - {/* Vetores de Força baseados no ângulo */} - {alpha !== 0 && ( - - {/* Vetor de sustentação (Fz) */} - 0 ? "M 200,75 L 200,30" : "M 200,125 L 200,170"} - stroke={alpha > 0 ? "#10b981" : "#ef4444"} - strokeWidth="3" - fill="none" - markerEnd="url(#arrow)" - /> - 0 ? 45 : 160} fill={alpha > 0 ? "#10b981" : "#ef4444"} className="text-xs font-bold font-mono"> - {alpha > 0 ? 'Sustentação (+Fz)' : 'Downforce (-Fz)'} - - - )} - - {/* Marcadores SVG de setas */} - - - - - - -
- Ângulo: {alpha}º -
-
-
+ {alpha !== 0 && ( + + 0 ? "M 200,75 L 200,30" : "M 200,125 L 200,170"} + stroke={alpha > 0 ? "#10b981" : "#ef4444"} + strokeWidth="3" + fill="none" + markerEnd="url(#arrow)" + /> + 0 ? 45 : 160} fill={alpha > 0 ? "#10b981" : "#ef4444"} className="text-xs font-bold font-mono"> + {alpha > 0 ? '+Fz (Sustentação)' : '-Fz (Abaixamento)'} + + + )} + + + + + + ); } @@ -134,243 +248,384 @@ export function WindFlowGrid2D({ type, params }: WindFlowGrid2DProps) { const section = params.section || 'square'; const alphaWind = Number(params.alphaWind || 0); return ( -
-

Simulação Ativa (com suas variáveis)

-
- - {styleBlock} - - {/* Linhas de vento fluindo */} - - - - - - - {/* Turbulência traseira (esteira) */} - - - + + {styleBlock} + + + + + + + + - {/* Perfil da Seção da Torre (Centro) */} - - {section === 'square' ? ( - - ) : ( - - )} - {/* Barras internas treliçadas */} - {section === 'square' ? ( - <> - - - - ) : ( - <> - - - - - )} - - -
- {section === 'square' ? 'Quadrada' : 'Triangular'} | {alphaWind}º -
-
-
+ + {section === 'square' ? ( + <> + + + + + ) : ( + <> + + + + + + )} + + ); } case 'cylinder': { - const isSmooth = params.roughness === 'smooth' || params.d_over_k > 1e5; + const isSmooth = params.surface === 'smooth'; + const cpi = Number(params.cpi || 0); return ( -
-

Simulação Ativa (com suas variáveis)

-
- - {styleBlock} - - {/* Fluxo contornando cilindro */} - - - - - - + + {styleBlock} + {/* Marcadores de setas Cpi */} + + + + + + + + - {/* Esteira de Vórtices de Von Kármán */} - - - - - - + + + + + + - {/* Cilindro */} - - -
- Superfície: {isSmooth ? 'Lisa (Menor Arrasto)' : 'Rugosa (Maior Arrasto)'} -
-
-
+ + + + + + + {/* Cilindro */} + + + {/* Pressão Interna */} + {renderCpiVectors(cpi, 'circle')} + + ); + } + + case 'sign': { + const hasEndPlates = params.hasEndPlates === true; + return ( + + {styleBlock} + + + + + {/* O vento passa reto ou desvia mais dependendo das abas laterais */} + + + + {/* Maior turbulência se houver placas de extremidade */} + + + + + {/* Muro */} + + {/* Placas de extremidade (abas de borda) */} + {hasEndPlates && ( + + + + + )} + + ); + } + + case 'warehouse': { + const cpi = Number(params.cpi || 0); + return ( + + {styleBlock} + + + + + + + + + + + + + + + + + + + {/* Galpão */} + + {/* Pressão Interna */} + {renderCpiVectors(cpi, 'rect')} + + ); + } + + case 'vault': { + const regime = params.regime || 'laminar-rough'; + const cpi = Number(params.localCpi || 0); + const isTurbulent = regime.startsWith('turbulent'); + + return ( + + {styleBlock} + + + + + + + + + + + + + + {/* Linha de vento ondulante / caótica se for turbulento */} + + + {isTurbulent && ( + + )} + + + {/* Abóbada */} + + {/* Pressão Interna */} + {renderCpiVectors(cpi, 'arch')} + + ); + } + + case 'dome': { + const cpi = Number(params.cpi || 0); + return ( + + {styleBlock} + + + + + + + + + + + + + + + + + + {/* Cúpula */} + + + + + {/* Pressão Interna */} + {renderCpiVectors(cpi, 'dome')} + + ); + } + + case 'isolated-roof': { + const typeRoof = params.type || 'shed'; + return ( + + {styleBlock} + + + + + + + + + + + + + {typeRoof === 'shed' ? ( + + ) : ( + + )} + + + ); + } + + case 'bar': { + const barType = params.barType || 'flat'; + const section = params.section || 'l'; + const alpha = Number(params.alpha || 0); + return ( + + {styleBlock} + + + + + + + + + {barType === 'circular' ? ( + + ) : ( + + {section === 'l' && ( + + )} + {section === 'u' && ( + + )} + {section === 'i' && ( + + )} + + )} + + ); } case 'dynamics': { - const fn = Number(params.fn || 0.5); - // Frequência regula a velocidade da vibração visual - const vibeDuration = Math.max(0.5, Math.min(2.5, 1 / fn)); return ( -
-

Simulação Ativa (com suas variáveis)

-
- - {styleBlock} - - {/* Linhas de vento */} - - - - - - + + {styleBlock} + + + + + + - {/* Vórtices alternados desalinhados de Von Kármán */} - - - + + + + - {/* Cilindro que VIBRA verticalmente na ressonância */} - - - - - -
- fn: {fn} Hz | Oscilação Ativa -
-
-
+ + + + + ); } default: - // Padrão genérico de fluxo para os demais módulos return ( -
-

Visualização do Escoamento

-
- - {styleBlock} - - - - - - {/* Elemento genérico no centro */} - - -
-
+ + {styleBlock} + + + + + ); } }; - // Comparativos estáticos baseados em grids como sugerido pelo usuário - const renderComparisonGrid = () => { - if (type === 'bridge') { - return ( -
-
- Incidência Descendente (α = -5º) -
- - {styleBlock} - - - - - - - {/* Seta para baixo */} - - -
-

Vento empurra o tabuleiro para baixo, aumentando os esforços de compressão nos pilares.

-
-
- Incidência Ascendente (α = +5º) -
- - {styleBlock} - - - - - - - {/* Seta para cima */} - - -
-

Efeito aerofólio levanta a ponte. Crítico para pontes estaiadas ou suspensas.

-
-
- ); - } - - if (type === 'tower') { - return ( -
-
- Vento Normal (0º) -
- - {styleBlock} - - - - - - - - -
-

Vento incidindo perpendicularmente à face frontal. Menor área exposta efetiva.

-
-
- Vento na Diagonal (45º) -
- - {styleBlock} - - - - - - - -
-

Aumenta a esteira e o coeficiente de arrasto Ca nas torres de seção quadrada.

-
-
- ); - } - - // Grid padrão se não houver um caso comparativo customizado - return null; - }; - return ( -
-
-

Túnel de Vento Virtual (Escoamento 2D)

- SVG Interativo +
+
+
+

Túnel de Vento Virtual 2D

+ {getViewLabel()} +
+ SVG Animado +
+ +
+ {renderActiveSimulation()} +
+ + {/* Caixa de Legenda Didática Expandida */} +
+ Legenda do Escoamento: +
+
+ + Linhas de Corrente de Vento +
+
+ + Fluxo Acelerado (Alta Vel. / Sucção) +
+
+ + Esteira Turbulenta / Recirculação +
+
+ + Vórtices de Desprendimento +
+ {/* Legenda de Pressão Interna */} +
+ + Seta Laranja: Pressão Interna (+Cpi) +
+
+ + Seta Azul Escura: Sucção Interna (-Cpi) +
+
- {renderActiveSimulation()} - {renderComparisonGrid()}
); } diff --git a/app/src/pages/CylinderModule.tsx b/app/src/pages/CylinderModule.tsx index 21823a3..28b4285 100644 --- a/app/src/pages/CylinderModule.tsx +++ b/app/src/pages/CylinderModule.tsx @@ -142,7 +142,7 @@ const CylinderModule: React.FC = () => {
- +
{
- +
{
- +