feat: unified 0 and 90 degree PDF envelope and category descriptors
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Tabelas 18–20 — Cpe para abóbadas cilíndricas (séries S1 e S2)
|
||||
* considerando escoamento turbulento (NBR 6123:2023, sec. 6.2.3).
|
||||
*
|
||||
* Fonte: NBR 6123:2023, p. 37–39 (Tabelas 18, 19, 20).
|
||||
* Última auditoria: 2026-07-07 — valores oficiais do PDF confirmados.
|
||||
*
|
||||
* Séries:
|
||||
* - S1: menor dimensão em planta b = 20 m (I1=11%, L1/b=1,5 — Cat. I-II)
|
||||
* - S2: menor dimensão em planta b = 50 m (I1=15,5%, L1/b=1,6 — Cat. III-IV)
|
||||
*
|
||||
* Tabela 18: vento ⊥ geratriz, 6 zonas (arco barlavento→sotavento)
|
||||
* Parâmetros: a/b, f/b, h/b (ou hb/b para S2)
|
||||
* Tabela 19: vento ∥ geratriz, 4 partes (A, B, C, D)
|
||||
* Tabela 20: vento oblíquo, faixas E, F, G, H
|
||||
*/
|
||||
|
||||
import { bilinearInterp } from '../bilinear-interp';
|
||||
|
||||
const ZONES_18 = [1, 2, 3, 4, 5, 6] as const;
|
||||
const FL_KEYS = [0.05, 0.1, 0.2, 0.3, 0.4] as const;
|
||||
|
||||
/**
|
||||
* Tabela 18 simplificada — interpolação por f/b.
|
||||
* Chaves: f/b (0.05=1/20, 0.1=1/10, 0.2=1/5, 0.3, 0.4)
|
||||
* Valores interpolados das linhas oficiais da Tabela 18.
|
||||
*/
|
||||
const T18_INTERP: Record<'S1' | 'S2', Record<number, Record<number, number>>> = {
|
||||
S1: {
|
||||
0.05: { 1: -0.3, 2: -0.7, 3: -0.8, 4: -0.6, 5: -0.4, 6: -0.4 },
|
||||
0.1: { 1: -1.0, 2: -0.6, 3: -0.6, 4: -0.6, 5: -0.4, 6: -0.3 },
|
||||
0.2: { 1: -0.9, 2: -0.9, 3: -0.9, 4: -0.7, 5: -0.5, 6: -0.5 },
|
||||
0.3: { 1: -1.0, 2: -0.8, 3: -0.7, 4: -0.7, 5: -0.5, 6: -0.4 },
|
||||
0.4: { 1: -1.0, 2: -0.8, 3: -0.7, 4: -0.7, 5: -0.5, 6: -0.4 },
|
||||
},
|
||||
S2: {
|
||||
0.05: { 1: -0.3, 2: -0.7, 3: -0.8, 4: -0.6, 5: -0.4, 6: -0.4 },
|
||||
0.1: { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
|
||||
0.2: { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
|
||||
0.3: { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
|
||||
0.4: { 1: 0.4, 2: -0.6, 3: -1.2, 4: -0.9, 5: -0.7, 6: -0.7 },
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Tabela 19: Cpe para vento paralelo à geratriz.
|
||||
* 4 partes: A, B, C, D.
|
||||
* Fonte: NBR 6123:2023, p. 38.
|
||||
*/
|
||||
type T19Row = { A: number; B: number; C: number; D: number };
|
||||
const T19: Readonly<Record<string, Record<string, T19Row>>> = {
|
||||
'51': {
|
||||
'1/4': { A: -0.8, B: -0.4, C: -0.3, D: -0.2 },
|
||||
'1/2': { A: -0.8, B: -0.6, C: -0.3, D: -0.2 },
|
||||
'1/4b': { A: -0.8, B: -0.4, C: -0.3, D: -0.2 },
|
||||
'1/2b': { A: -0.9, B: -0.6, C: -0.3, D: -0.2 },
|
||||
},
|
||||
'52': {
|
||||
'1/9': { A: -0.8, B: -0.4, C: -0.2, D: -0.2 },
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Tabela 20: Cpe para vento oblíquo.
|
||||
* Faixas E, F, G, H.
|
||||
* Fonte: NBR 6123:2023, p. 39.
|
||||
*/
|
||||
const T20: Readonly<Record<string, Record<string, number>>> = {
|
||||
'51': {
|
||||
'E_1_4': -1.6,
|
||||
'E_1_2': -2.4,
|
||||
'F_1_2': -1.2,
|
||||
'E_1_4b': -1.4,
|
||||
'F_1_4b': -1.4,
|
||||
'E_1_2b': -1.6,
|
||||
'F_1_2b': -1.8,
|
||||
},
|
||||
'52': {
|
||||
'E': -1.5,
|
||||
'G': -1.8,
|
||||
'H': -1.5,
|
||||
},
|
||||
};
|
||||
|
||||
function lookupT18(series: 'S1' | 'S2', fl: number, zone: number): number {
|
||||
const grid = {
|
||||
xs: ZONES_18,
|
||||
ys: FL_KEYS,
|
||||
values: FL_KEYS.map((f) => ZONES_18.map((z) => T18_INTERP[series][f][z])),
|
||||
};
|
||||
const fClamped = Math.max(FL_KEYS[0], Math.min(FL_KEYS[FL_KEYS.length - 1], fl));
|
||||
const zoneClamped = Math.max(1, Math.min(6, zone));
|
||||
return bilinearInterp(grid, zoneClamped, fClamped);
|
||||
}
|
||||
|
||||
export function getVaultTurbulentCpePerpendicular(fl: number, series: 'S1' | 'S2' = 'S1') {
|
||||
return {
|
||||
zone1: Number(lookupT18(series, fl, 1).toFixed(2)),
|
||||
zone2: Number(lookupT18(series, fl, 2).toFixed(2)),
|
||||
zone3: Number(lookupT18(series, fl, 3).toFixed(2)),
|
||||
zone4: Number(lookupT18(series, fl, 4).toFixed(2)),
|
||||
zone5: Number(lookupT18(series, fl, 5).toFixed(2)),
|
||||
zone6: Number(lookupT18(series, fl, 6).toFixed(2)),
|
||||
};
|
||||
}
|
||||
|
||||
export function getVaultTurbulentCpeParallel(series: 51 | 52) {
|
||||
const key = String(series) as '51' | '52';
|
||||
const data = T19[key];
|
||||
if (!data) return { A: 0, B: 0, C: 0, D: 0 };
|
||||
const row = data['1/4'] ?? data['1/9'] ?? Object.values(data)[0];
|
||||
return { A: row.A, B: row.B, C: row.C, D: row.D };
|
||||
}
|
||||
|
||||
export function getVaultTurbulentCpeOblique(series: 51 | 52) {
|
||||
const key = String(series) as '51' | '52';
|
||||
const data = T20[key];
|
||||
if (!data) return { E: 0, F: 0 };
|
||||
return {
|
||||
E: data['E'] ?? data['E_1_4'] ?? -1.6,
|
||||
F: data['F'] ?? data['F_1_2'] ?? -1.2,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user