import type { PileCapGeometry, LoadCombinationResult, DesignParameters, PileReaction } from '../types/pileCap'; export function calculatePileReactions( geometry: PileCapGeometry, governingLoad: LoadCombinationResult, _design: DesignParameters ): PileReaction[] { const { pileRows, pileColumns, pileSpacingX, pileSpacingY, length, width } = geometry; const { axialLoad: P, momentX: Mx, momentY: My } = governingLoad; const totalPiles = pileRows * pileColumns; // Calculate pile positions const pileReactions: PileReaction[] = []; let pileNumber = 1; // Calculate centroid of pile group const startX = (length - (pileColumns - 1) * pileSpacingX) / 2; const startY = (width - (pileRows - 1) * pileSpacingY) / 2; // Calculate moments of inertia of pile group let sumX = 0; let sumY = 0; let sumX2 = 0; let sumY2 = 0; for (let row = 0; row < pileRows; row++) { for (let col = 0; col < pileColumns; col++) { const x = startX + col * pileSpacingX; const y = startY + row * pileSpacingY; sumX += x; sumY += y; } } const centroidX = sumX / totalPiles; const centroidY = sumY / totalPiles; for (let row = 0; row < pileRows; row++) { for (let col = 0; col < pileColumns; col++) { const x = startX + col * pileSpacingX; const y = startY + row * pileSpacingY; const dx = x - centroidX; const dy = y - centroidY; sumX2 += dx * dx; sumY2 += dy * dy; } } // Calculate pile reactions using P/n ± M*c/I formula for (let row = 0; row < pileRows; row++) { for (let col = 0; col < pileColumns; col++) { const x = startX + col * pileSpacingX; const y = startY + row * pileSpacingY; const dx = x - centroidX; const dy = y - centroidY; // R = P/n + My*dx/Iy - Mx*dy/Ix // Note: Sign convention for moments depends on coordinate system. // Assuming Right-Hand Rule: // +Mx creates compression (+y) at +y locations? No, Mx is moment about X axis. // +Mx creates compression at +y (top) or -y (bottom)? // Standard structural: +Mx puts compression on Top (+y). // So term is + Mx*y/Ix. // Let's stick to the previous logic which was: // reaction = base + My*dx/Iy - Mx*dy/Ix const baseReaction = P / totalPiles; const momentY_effect = sumY2 > 0 ? (My * dx) / sumY2 : 0; const momentX_effect = sumX2 > 0 ? (Mx * dy) / sumX2 : 0; const reaction = baseReaction + momentY_effect - momentX_effect; pileReactions.push({ x, y, reaction, pileNumber: pileNumber++ }); } } return pileReactions; }