CtrEditor/HydraulicSimulator/Models/DischargeTank.cs

80 lines
2.7 KiB
C#

using System;
using System.Linq;
using System.Collections.Generic;
namespace HydraulicSimulator.Models
{
/// <summary>
/// Tanque especial para descarga libre con cálculo de nivel dinámico
/// </summary>
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;
}
/// <summary>
/// Altura actual del líquido en el tanque
/// </summary>
public double CurrentHeight => CurrentVolume / Area;
/// <summary>
/// Presión hidrostática en el fondo del tanque
/// </summary>
public double BottomPressure(Fluid fluid) => fluid.Rho * 9.81 * CurrentHeight;
/// <summary>
/// Actualizar volumen basado en flujo neto
/// </summary>
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));
}
/// <summary>
/// Para tanque de descarga, la caída de presión es mínima
/// </summary>
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
}
/// <summary>
/// Verificar si el tanque está desbordando
/// </summary>
public bool IsOverflowing => CurrentVolume >= MaxVolume;
/// <summary>
/// Verificar si el tanque está vacío
/// </summary>
public bool IsEmpty => CurrentVolume <= MinVolume;
/// <summary>
/// Porcentaje de llenado (0.0 - 1.0)
/// </summary>
public double FillPercentage => (CurrentVolume - MinVolume) / (MaxVolume - MinVolume);
}
}