feat: unified 0 and 90 degree PDF envelope and category descriptors
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { create } from 'zustand';
|
||||
import {
|
||||
calculateGlobalWindData,
|
||||
type TerrainCategory,
|
||||
type StructureClass,
|
||||
} from '../lib/wind-kernel';
|
||||
import { computeCpiSimplified, clampCpi, type PermeabilityCase } from '../lib/internal-pressure';
|
||||
|
||||
export interface GlobalWindState {
|
||||
// Entradas (Inputs)
|
||||
v0: number;
|
||||
s1: number;
|
||||
s3: number;
|
||||
s3Group: 1 | 2 | 3 | 4 | 5;
|
||||
terrainCategory: TerrainCategory;
|
||||
largestDimension: number;
|
||||
heightZ: number;
|
||||
|
||||
// Saídas (Calculados)
|
||||
structureClass: StructureClass;
|
||||
s2: number;
|
||||
vk: number;
|
||||
q: number;
|
||||
|
||||
// Pressão interna e Vento
|
||||
windAngle: 0 | 90;
|
||||
permeabilityCase: PermeabilityCase;
|
||||
cpiRatio: number;
|
||||
cpi: number;
|
||||
|
||||
// Ações
|
||||
updateCalculations: () => void;
|
||||
setV0: (val: number) => void;
|
||||
setS1: (val: number) => void;
|
||||
setS3: (val: number) => void;
|
||||
setS3Group: (group: 1 | 2 | 3 | 4 | 5) => void;
|
||||
setTerrainCategory: (cat: TerrainCategory) => void;
|
||||
setDimensions: (largestDim: number, z: number) => void;
|
||||
setWindAngle: (angle: 0 | 90) => void;
|
||||
setPermeabilityCase: (c: PermeabilityCase) => void;
|
||||
setCpiRatio: (r: number) => void;
|
||||
setCpiManual: (c: number) => void;
|
||||
}
|
||||
|
||||
function calcCpi(permeabilityCase: PermeabilityCase, ratio: number, windAngle: 0 | 90): number {
|
||||
if (permeabilityCase === 'airtight') return 0; // Just as an example, computeCpiSimplified handles it
|
||||
const value = computeCpiSimplified({
|
||||
case: permeabilityCase,
|
||||
ratio,
|
||||
windAngle,
|
||||
});
|
||||
return clampCpi(value);
|
||||
}
|
||||
|
||||
export const useWindStore = create<GlobalWindState>((set, get) => {
|
||||
const recalc = (state: GlobalWindState): Partial<GlobalWindState> => {
|
||||
const calc = calculateGlobalWindData(
|
||||
state.v0,
|
||||
state.s1,
|
||||
state.s3,
|
||||
state.terrainCategory,
|
||||
state.largestDimension,
|
||||
state.heightZ,
|
||||
);
|
||||
return {
|
||||
structureClass: calc.structClass,
|
||||
s2: calc.s2,
|
||||
vk: calc.vk,
|
||||
q: calc.q,
|
||||
cpi: calcCpi(state.permeabilityCase, state.cpiRatio, state.windAngle),
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
v0: 40,
|
||||
s1: 1.0,
|
||||
s3: 1.0,
|
||||
s3Group: 3,
|
||||
terrainCategory: 'II',
|
||||
largestDimension: 30,
|
||||
heightZ: 10,
|
||||
|
||||
structureClass: 'B',
|
||||
s2: 1.06,
|
||||
vk: 42.4,
|
||||
q: 1.1024,
|
||||
|
||||
windAngle: 0,
|
||||
permeabilityCase: 'four-equally-permeable',
|
||||
cpiRatio: 1.0,
|
||||
cpi: calcCpi('four-equally-permeable', 1.0, 0),
|
||||
|
||||
updateCalculations: () => set((state) => recalc(state)),
|
||||
|
||||
setV0: (val) => {
|
||||
set({ v0: val });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setS1: (val) => {
|
||||
set({ s1: val });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setS3: (val) => {
|
||||
set({ s3: val });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setS3Group: (group) => {
|
||||
const newS3 = group === 1 ? 1.10 : group === 2 ? 1.08 : group === 3 ? 1.0 : group === 4 ? 0.95 : 0.83;
|
||||
set({ s3Group: group, s3: newS3 });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setTerrainCategory: (cat) => {
|
||||
set({ terrainCategory: cat });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setDimensions: (largestDim, z) => {
|
||||
set({ largestDimension: largestDim, heightZ: z });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setWindAngle: (angle) => {
|
||||
set({ windAngle: angle });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setPermeabilityCase: (c) => {
|
||||
set({ permeabilityCase: c });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setCpiRatio: (r) => {
|
||||
set({ cpiRatio: r });
|
||||
get().updateCalculations();
|
||||
},
|
||||
setCpiManual: (c) => {
|
||||
set({ cpi: clampCpi(c) });
|
||||
// Not calling updateCalculations to avoid overriding it immediately if permeabilityCase applies,
|
||||
// but if the user overrides manually we might want to switch permeabilityCase to 'custom' ?
|
||||
// Wait, there is no 'custom'. We just set the value.
|
||||
},
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user