using System; using System.Linq; using System.Collections.Generic; namespace HydraulicSimulator.Models { /// /// Tanque especial para descarga libre con cálculo de nivel dinámico /// public class DischargeTank : Element { public double Area { get; set; } // m² - área del tanque public double CurrentVolume { get; set; } // m³ - volumen actual public double MaxVolume { get; set; } // m³ - volumen máximo public double MinVolume { get; set; } // m³ - volumen mínimo public string TankId { get; set; } // ID del tanque public DischargeTank(string tankId, double area, double initialVolume = 0, double maxVolume = double.MaxValue, double minVolume = 0) { TankId = tankId; Area = area; CurrentVolume = initialVolume; MaxVolume = maxVolume; MinVolume = minVolume; } /// /// Altura actual del líquido en el tanque /// public double CurrentHeight => CurrentVolume / Area; /// /// Presión hidrostática en el fondo del tanque /// public double BottomPressure(Fluid fluid) => fluid.Rho * 9.81 * CurrentHeight; /// /// Actualizar volumen basado en flujo neto /// public void UpdateVolume(double netFlowRate, double deltaTime) { double volumeChange = netFlowRate * deltaTime; CurrentVolume += volumeChange; // Limitar entre mínimo y máximo CurrentVolume = Math.Max(MinVolume, Math.Min(MaxVolume, CurrentVolume)); } /// /// Para tanque de descarga, la caída de presión es mínima /// public override double Dp(double q, Fluid fluid) { // Caída de presión mínima para tanque de descarga return Math.Sign(q) * 100.0; // 100 Pa de pérdida nominal } public override double DdpDq(double q, Fluid fluid) { return 1e-6; // Derivada muy pequeña para estabilidad } /// /// Verificar si el tanque está desbordando /// public bool IsOverflowing => CurrentVolume >= MaxVolume; /// /// Verificar si el tanque está vacío /// public bool IsEmpty => CurrentVolume <= MinVolume; /// /// Porcentaje de llenado (0.0 - 1.0) /// public double FillPercentage => (CurrentVolume - MinVolume) / (MaxVolume - MinVolume); } }