using System; using System.ComponentModel; using Newtonsoft.Json; namespace CtrEditor.ObjetosSim { /// /// Tipos de fluido en el sistema hidráulico /// public enum FluidType { [Description("Aire (tanque vacío)")] Air, [Description("Agua")] Water, [Description("Jarabe con sacarosa")] Syrup, [Description("Soda cáustica (CIP)")] CausticSoda, [Description("Mezcla")] Mix } /// /// Propiedades de un fluido en el sistema /// [JsonObject(MemberSerialization.OptIn)] public class FluidProperties { [JsonProperty] public FluidType Type { get; set; } = FluidType.Water; [JsonProperty] public double Temperature { get; set; } = 20.0; // °C [JsonProperty] public double Brix { get; set; } = 0.0; // % para jarabes [JsonProperty] public double Concentration { get; set; } = 0.0; // % para soda cáustica [JsonProperty] public double Volume { get; set; } = 0.0; // Litros /// /// Densidad del fluido en kg/L /// [JsonIgnore] public double Density { get { return Type switch { FluidType.Air => 0.0012, // kg/L a 20°C FluidType.Water => 1.0 - (Temperature - 20) * 0.0002, // Aproximación FluidType.Syrup => 1.0 + (Brix * 0.004), // Aproximación: +0.4% densidad por grado Brix FluidType.CausticSoda => 1.0 + (Concentration * 0.01), // Aproximación FluidType.Mix => 1.0, // Se calculará en runtime _ => 1.0 }; } } /// /// Viscosidad dinámica en cP (centipoise) /// [JsonIgnore] public double Viscosity { get { return Type switch { FluidType.Air => 0.018, FluidType.Water => Math.Max(0.3, 1.0 - (Temperature - 20) * 0.025), // Disminuye con temperatura FluidType.Syrup => Math.Max(1.0, 1.0 + Math.Pow(Brix / 10.0, 2.5)), // Aumenta exponencialmente con Brix FluidType.CausticSoda => Math.Max(0.8, 1.0 + Concentration * 0.02), FluidType.Mix => 1.0, // Se calculará en runtime _ => 1.0 }; } } /// /// Color representativo del fluido para UI /// [JsonIgnore] public string Color { get { return Type switch { FluidType.Air => "#E0E0E0", FluidType.Water => "#87CEEB", FluidType.Syrup => $"#{Math.Min(255, 139 + (int)(Brix * 2)):X2}{Math.Min(255, 69 + (int)(Brix)):X2}19", // Marrón más intenso con más Brix FluidType.CausticSoda => "#FF6347", FluidType.Mix => "#DDA0DD", _ => "#CCCCCC" }; } } /// /// Descripción del fluido /// [JsonIgnore] public string Description { get { return Type switch { FluidType.Air => "Aire", FluidType.Water => $"Agua {Temperature:F1}°C", FluidType.Syrup => $"Jarabe {Brix:F1}°Bx {Temperature:F1}°C", FluidType.CausticSoda => $"NaOH {Concentration:F1}% {Temperature:F1}°C", FluidType.Mix => $"Mezcla {Temperature:F1}°C", _ => "Fluido" }; } } public FluidProperties() { } public FluidProperties(FluidType type, double temperature = 20.0, double brix = 0.0, double concentration = 0.0) { Type = type; Temperature = temperature; Brix = brix; Concentration = concentration; } /// /// Crea una copia de las propiedades del fluido /// public FluidProperties Clone() { return new FluidProperties(Type, Temperature, Brix, Concentration) { Volume = Volume }; } /// /// Mezcla este fluido con otro fluido /// public FluidProperties MixWith(FluidProperties other, double mixRatio) { if (other == null || mixRatio <= 0) return this.Clone(); if (mixRatio >= 1) return other.Clone(); var mixed = new FluidProperties { Type = FluidType.Mix, Temperature = Temperature * (1 - mixRatio) + other.Temperature * mixRatio, Brix = Brix * (1 - mixRatio) + other.Brix * mixRatio, Concentration = Concentration * (1 - mixRatio) + other.Concentration * mixRatio, Volume = Volume + other.Volume }; return mixed; } } /// /// Estado de mezcla del tanque /// public enum MixingState { [Description("Solo fluido primario")] PrimaryOnly, [Description("Solo fluido secundario")] SecondaryOnly, [Description("Vaciando secundario")] EmptyingSecondary, [Description("Mezclando")] Mixing, [Description("Vaciando primario")] EmptyingPrimary, [Description("Vacío")] Empty } }