🚀 Auto-deploy: BrainWind atualizado em 13/07/2026 11:37:13

This commit is contained in:
2026-07-13 11:37:13 +00:00
parent 58ac69ba18
commit 314c9b7490
7 changed files with 1824 additions and 30 deletions
+1 -1
View File
@@ -105,7 +105,7 @@ function cylinderScenario(
endType: 'closed' | 'open-top' | 'open-bottom' | 'open-both', endType: 'closed' | 'open-top' | 'open-bottom' | 'open-both',
_windAngle: 0 | 90, _windAngle: 0 | 90,
): AuditScenario { ): AuditScenario {
const { s2, vk, q } = calcWind(v0, s1, s3, cat, d, h); const { s2, vk, q } = calcWind(v0, s1, s3, cat, Math.max(d, h), h);
const re = 70000 * vk * d; const re = 70000 * vk * d;
const hOverD = h / d; const hOverD = h / d;
let cpiVal: number; let cpiVal: number;
+3 -3
View File
@@ -35,9 +35,9 @@ export function evaluateComfort(input: ComfortInput): ComfortResult {
description: 'Fora da faixa 0,061,00 Hz — aplicar critério da ISO 10137.', description: 'Fora da faixa 0,061,00 Hz — aplicar critério da ISO 10137.',
}; };
} }
const ka = use === 'commercial' ? 6.12 : 4.058; const ka = use === 'commercial' ? 6.12 : 4.06;
const aLim = Number((0.01 * ka * Math.pow(freq, 1.124)).toFixed(3)); const aLim = 0.01 * ka * Math.pow(freq, 1.124);
const ratio = Number((aMax / aLim).toFixed(3)); const ratio = aMax / aLim;
return { return {
aLim, aLim,
use, use,
+2 -4
View File
@@ -65,10 +65,8 @@ export function calculateFriction(input: FrictionInput): FrictionResult {
const roofAreaM2 = roofArea(input.length, input.width, input.roofPitch); const roofAreaM2 = roofArea(input.length, input.width, input.roofPitch);
const roofSlant = roofAreaM2; const roofSlant = roofAreaM2;
const theta = (input.roofPitch * Math.PI) / 180; const wallAreaUpwind = input.height * input.length;
const wallHeightFull = input.height + (input.width / 2) * Math.tan(theta); const wallAreaDownwind = input.height * input.length;
const wallAreaUpwind = wallHeightFull * input.length;
const wallAreaDownwind = wallHeightFull * input.length;
const totalArea = roofSlant + wallAreaUpwind + wallAreaDownwind; const totalArea = roofSlant + wallAreaUpwind + wallAreaDownwind;
const forceKN = cf * input.q * totalArea; const forceKN = cf * input.q * totalArea;
+5 -3
View File
@@ -25,6 +25,8 @@ export interface SimplifiedCpiInput {
ratio?: number; ratio?: number;
/** Direção do vento: 0 ou 90 (apenas para two-opposite-permeable) */ /** Direção do vento: 0 ou 90 (apenas para two-opposite-permeable) */
windAngle?: 0 | 90; windAngle?: 0 | 90;
/** Cpe externo da face de sotavento para o caso dominant-leeward */
ce?: number;
} }
/** /**
@@ -57,9 +59,9 @@ export function computeCpiSimplified(input: SimplifiedCpiInput): number {
} }
case 'dominant-leeward': case 'dominant-leeward':
// Caller deve fornecer Ce externo via input.ratio como Ce; // O valor correto deve ser o Ce externo.
// retornamos o próprio Ce como aproximação segura. // Retornamos input.ce ou -0.3 como aproximação segura.
return input.ratio ?? -0.3; return input.ce ?? -0.3;
case 'dominant-lateral': { case 'dominant-lateral': {
const r = input.ratio ?? 1; const r = input.ratio ?? 1;
+2 -2
View File
@@ -52,8 +52,8 @@ export function classifyBridge(input: BridgeClassificationInput): BridgeClassifi
const vit = 0.65 * v0 * s1 * b * Math.pow(deckHeight / 10, p); const vit = 0.65 * v0 * s1 * b * Math.pow(deckHeight / 10, p);
const rho = 1.226; const rho = 1.226;
// Forma simplificada da norma // Forma simplificada da norma: Pse = ρ · V_it² / (m · f_v²)
const pse = (rho * vit * vit * lp * lp) / (massPerLength * fv * fv * width * width); const pse = (rho * vit * vit) / (massPerLength * fv * fv);
let bridgeClass: BridgeClass; let bridgeClass: BridgeClass;
let description: string; let description: string;
+12 -17
View File
@@ -9,12 +9,12 @@
* - Circulares triangular: Figura 18 (vento qq direção) por Re × φ * - Circulares triangular: Figura 18 (vento qq direção) por Re × φ
*/ */
import { bilinearInterp } from '../bilinear-interp'; import { linearInterp1D } from '../log-interp';
/** Figura 15 — Ca para torre faces planas, quadrada e triangular equilátera */ /** Tabela 26 — Ca para torre faces planas, quadrada e triangular equilátera */
const PHI_15 = [0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0] as const; const PHI_26 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6] as const;
const CA_15_QUAD: Readonly<Record<number, number>> = { const CA_26_FLAT: Readonly<Record<number, number>> = {
0.05: 3.6, 0.1: 3.0, 0.2: 2.5, 0.3: 2.2, 0.4: 2.0, 0.5: 1.85, 0.6: 1.75, 0.7: 1.65, 0.8: 1.55, 1.0: 1.4, 0.1: 2.8, 0.2: 2.4, 0.3: 2.0, 0.4: 1.8, 0.5: 1.7, 0.6: 1.6,
}; };
export type TowerSection = 'square' | 'triangular'; export type TowerSection = 'square' | 'triangular';
@@ -49,11 +49,10 @@ export interface TowerResult {
/** Fator Kα para torre quadrada com vento oblíquo */ /** Fator Kα para torre quadrada com vento oblíquo */
function kAlphaQuad(alpha: number): number { function kAlphaQuad(alpha: number): number {
if (alpha <= 12.5) return 1; const a = alpha % 90;
if (alpha <= 20) return 1 + 0.075 * (alpha - 12.5) * 1.333; const aSym = a > 45 ? 90 - a : a;
if (alpha <= 45) return 1.16; if (aSym <= 12.5) return 1.0;
// Extrapolação linear conservadora return 1.08;
return 1.16;
} }
/** Fator Kα para torre triangular equilátera (sempre 1, vento qq direção) */ /** Fator Kα para torre triangular equilátera (sempre 1, vento qq direção) */
@@ -66,13 +65,9 @@ export function calculateTower(input: TowerInput): TowerResult {
let ca = 0; let ca = 0;
if (barType === 'flat') { if (barType === 'flat') {
const grid = { const phiClamped = Math.max(0.1, Math.min(0.6, phi));
xs: PHI_15, const cax = PHI_26.map((p) => CA_26_FLAT[p]);
ys: [1] as readonly number[], ca = Number(linearInterp1D(PHI_26, cax, phiClamped).toFixed(3));
values: [PHI_15.map((p) => CA_15_QUAD[p])],
};
const phiClamped = Math.max(0.05, Math.min(1.0, phi));
ca = bilinearInterp(grid, phiClamped, 1);
} else { } else {
// Circulares — Figuras 16/17/18 (simplificado) // Circulares — Figuras 16/17/18 (simplificado)
const baseCa = re < 4.2e5 ? 1.5 : re < 2.3e6 ? 0.7 : 0.6; const baseCa = re < 4.2e5 ? 1.5 : re < 2.3e6 ? 0.7 : 0.6;
File diff suppressed because it is too large Load Diff