CtrEditor/Documentation/Hidraulic/TechnicalSpecifications.md

14 KiB
Raw Blame History

🔬 Especificaciones Técnicas - Sistema de Fluidos CtrEditor

📋 Resumen Técnico

Este documento proporciona las especificaciones técnicas detalladas del sistema de gestión de fluidos de CtrEditor, incluyendo algoritmos de cálculo, especificaciones de rendimiento, límites del sistema y detalles de implementación para desarrolladores.


🧮 Algoritmos de Cálculo

Cálculo de Densidad por Tipo de Fluido

Agua

// Densidad del agua en función de la temperatura (kg/m³)
public static double WaterDensity(double temperatureC)
{
    // Ecuación polinomial para agua pura (0-100°C)
    var t = temperatureC;
    return 1000.0 - 0.0178 * t - 0.0000676 * t * t + 0.0000001 * t * t * t;
}

Jarabe de Sacarosa

// Densidad del jarabe basada en concentración Brix y temperatura
public static double SyrupDensity(double brix, double temperatureC)
{
    // Correlación estándar para jarabes de sacarosa
    var densityAt20C = 1000.0 + (brix * 3.86) + (brix * brix * 0.0166);
    
    // Corrección por temperatura (kg/m³/°C)
    var tempCorrection = (temperatureC - 20.0) * (-0.3);
    
    return densityAt20C + tempCorrection;
}

Soda Cáustica (NaOH)

// Densidad de solución de NaOH en función de concentración y temperatura
public static double CausticSodaDensity(double concentrationPercent, double temperatureC)
{
    // Para NaOH al 50% (concentración típica industrial)
    var baseDesity = 1530.0; // kg/m³ a 20°C
    
    // Corrección por temperatura
    var tempCorrection = (temperatureC - 20.0) * (-0.8);
    
    return baseDensity + tempCorrection;
}

Cálculo de Viscosidad

Viscosidad de Jarabes (Ecuación de Arrhenius)

public static double SyrupViscosity(double brix, double temperatureC)
{
    // Parámetros de la ecuación de Arrhenius para sacarosa
    var A = 1.68e-6;  // Factor pre-exponencial
    var B = 0.0295;   // Dependencia de concentración
    var Ea = 16500.0; // Energía de activación (J/mol)
    var R = 8.314;    // Constante de gas (J/mol·K)
    var T = temperatureC + 273.15; // Temperatura absoluta (K)
    
    // Viscosidad base del agua
    var waterVisc = 0.001 * Math.Exp(1301.0 / T - 1.5);
    
    // Factor de concentración
    var concFactor = Math.Exp(B * brix);
    
    // Factor de temperatura
    var tempFactor = Math.Exp(Ea / (R * T));
    
    return waterVisc * concFactor * tempFactor;
}

Algoritmo de Mezcla Gradual

Interpolación Ponderada para Propiedades

public class GradualMixingAlgorithm
{
    public static FluidProperties CalculateMixture(
        FluidProperties primary, 
        FluidProperties secondary, 
        double mixingProgress) // 0.0 a 1.0
    {
        return new FluidProperties
        {
            FluidType = FluidType.Mix,
            
            // Interpolación lineal de concentración
            ConcentrationBrix = Lerp(
                primary.ConcentrationBrix, 
                secondary.ConcentrationBrix, 
                mixingProgress),
            
            // Mezcla térmica (conservación de energía)
            Temperature = ThermalMixing(
                primary.Temperature, primary.Density,
                secondary.Temperature, secondary.Density,
                mixingProgress)
        };
    }
    
    private static double ThermalMixing(
        double temp1, double density1,
        double temp2, double density2,
        double ratio)
    {
        // Capacidad calorífica específica (J/kg·K)
        var cp1 = 4186.0; // Agua/jarabe
        var cp2 = 4186.0;
        
        // Balance de energía térmica
        var energy1 = (1.0 - ratio) * density1 * cp1 * temp1;
        var energy2 = ratio * density2 * cp2 * temp2;
        var totalMass = (1.0 - ratio) * density1 + ratio * density2;
        
        return (energy1 + energy2) / (totalMass * cp1);
    }
}

⚙️ Especificaciones de Rendimiento

Límites del Sistema

Rangos Operativos

Parámetro Mínimo Máximo Unidad Notas
Temperatura -5.0 120.0 °C Rango industrial estándar
Presión 0.1 10.0 bar Sistemas de baja-media presión
Concentración Brix 0.0 100.0 % Sacarosa en solución acuosa
Nivel de Tanque 0.0 10.0 m Tanques industriales típicos
Volumen 0.0 100,000 L Desde laboratorio hasta planta
RPM de Mezcla 0.0 100.0 RPM Mezcladores industriales

Precisión de Cálculos

Cálculo Precisión Tolerancia
Densidad ±0.1% ±1.0 kg/m³
Viscosidad ±2.0% Dependiente de fluido
Temperatura de Mezcla ±0.1°C Conservación energética
Concentración Final ±0.5% Balance de masa

Rendimiento Computacional

Tiempos de Respuesta Objetivo

// Benchmarks de rendimiento
public class PerformanceSpecs
{
    public static readonly TimeSpan FluidCalculation = TimeSpan.FromMilliseconds(1);
    public static readonly TimeSpan MixingUpdate = TimeSpan.FromMilliseconds(5);
    public static readonly TimeSpan TankSimulation = TimeSpan.FromMilliseconds(10);
    public static readonly TimeSpan NetworkUpdate = TimeSpan.FromMilliseconds(50);
}

Uso de Memoria

  • FluidProperties: ~200 bytes por instancia
  • osHydTank: ~8 KB por tanque (incluyendo UI)
  • Simulación Completa: <100 MB para 1000 componentes

🔧 Detalles de Implementación

Estructura de Datos Optimizada

FluidProperties - Implementación Interna

[Serializable]
public sealed class FluidProperties : INotifyPropertyChanged, ICloneable
{
    // Campos privados para rendimiento
    private FluidType _fluidType = FluidType.Water;
    private double _concentrationBrix = 0.0;
    private double _temperature = 20.0;
    
    // Cache para propiedades calculadas
    private double? _cachedDensity;
    private double? _cachedViscosity;
    private SolidColorBrush? _cachedColor;
    
    // Invalidación de cache
    private void InvalidateCache()
    {
        _cachedDensity = null;
        _cachedViscosity = null;
        _cachedColor = null;
    }
    
    // Propiedades con lazy evaluation
    public double Density
    {
        get
        {
            if (!_cachedDensity.HasValue)
                _cachedDensity = CalculateDensity();
            return _cachedDensity.Value;
        }
    }
}

Optimizaciones de Cálculo

Lookup Tables para Funciones Costosas

public static class FluidLookupTables
{
    // Tabla pre-calculada para viscosidad de jarabes
    private static readonly double[,] SyrupViscosityTable = 
        PrecomputeSyrupViscosity();
    
    private static double[,] PrecomputeSyrupViscosity()
    {
        var table = new double[101, 121]; // Brix × Temperatura
        
        for (int brix = 0; brix <= 100; brix++)
        {
            for (int temp = 0; temp <= 120; temp++)
            {
                table[brix, temp] = CalculateExactSyrupViscosity(brix, temp);
            }
        }
        
        return table;
    }
    
    public static double GetSyrupViscosity(double brix, double temperature)
    {
        // Interpolación bilineal en la tabla
        return BilinearInterpolation(SyrupViscosityTable, brix, temperature);
    }
}

Gestión de Estados de Mezcla

Máquina de Estados para Mezcla

public class MixingStateMachine
{
    private MixingState _currentState = MixingState.Idle;
    private DateTime _stateStartTime = DateTime.Now;
    private double _mixingProgress = 0.0;
    
    public void Update(TimeSpan deltaTime)
    {
        switch (_currentState)
        {
            case MixingState.Idle:
                // No action required
                break;
                
            case MixingState.Active:
                UpdateActiveMixing(deltaTime);
                break;
                
            case MixingState.Gradual:
                UpdateGradualMixing(deltaTime);
                break;
        }
    }
    
    private void UpdateGradualMixing(TimeSpan deltaTime)
    {
        var mixingRate = CalculateMixingRate();
        _mixingProgress += mixingRate * deltaTime.TotalSeconds;
        
        if (_mixingProgress >= 1.0)
        {
            CompleteMixing();
            TransitionTo(MixingState.Idle);
        }
    }
}

📊 Validación y Testing

Test Cases Críticos

Conservación de Masa

[Test]
public void TestMassConservation()
{
    var tank = new osHydTank()
    {
        CrossSectionalArea = 1.0,
        PrimaryFluid = new FluidProperties 
        { 
            FluidType = FluidType.Water,
            Temperature = 20.0
        }
    };
    
    var initialMass = tank.CurrentVolumeL * tank.PrimaryFluid.Density / 1000.0;
    
    // Agregar fluido secundario
    tank.SecondaryFluid = new FluidProperties 
    { 
        FluidType = FluidType.Syrup,
        ConcentrationBrix = 65.0,
        Temperature = 85.0
    };
    
    // Simular mezcla completa
    tank.MixingState = MixingState.Active;
    SimulateMixing(tank, TimeSpan.FromMinutes(10));
    
    var finalMass = tank.CurrentVolumeL * tank.PrimaryFluid.Density / 1000.0;
    
    // Verificar conservación de masa (±0.1%)
    Assert.AreEqual(initialMass, finalMass, initialMass * 0.001);
}

Conservación de Energía Térmica

[Test]
public void TestThermalEnergyConservation()
{
    // Mezcla de agua caliente y fría
    var hotWater = new FluidProperties 
    { 
        FluidType = FluidType.Water,
        Temperature = 80.0
    };
    
    var coldWater = new FluidProperties 
    { 
        FluidType = FluidType.Water,
        Temperature = 20.0
    };
    
    // Mezcla 50/50
    var mixture = hotWater.MixWith(coldWater, 0.5);
    
    // Temperatura esperada: ~50°C
    Assert.AreEqual(50.0, mixture.Temperature, 0.1);
}

Benchmarks de Rendimiento

Stress Test de Simulación

[Test]
[Category("Performance")]
public void StressTest_1000Tanks()
{
    var tanks = new List<osHydTank>();
    var stopwatch = Stopwatch.StartNew();
    
    // Crear 1000 tanques
    for (int i = 0; i < 1000; i++)
    {
        tanks.Add(CreateRandomTank());
    }
    
    stopwatch.Stop();
    Assert.Less(stopwatch.ElapsedMilliseconds, 5000); // <5 segundos
    
    // Simular un ciclo completo
    stopwatch.Restart();
    
    foreach (var tank in tanks)
    {
        tank.UpdateFluidProperties();
        tank.CalculateFlowRates();
    }
    
    stopwatch.Stop();
    Assert.Less(stopwatch.ElapsedMilliseconds, 100); // <100ms por ciclo
}

🔒 Consideraciones de Seguridad y Robustez

Validación de Entrada

Sanitización de Parámetros

public static class InputValidation
{
    public static double ValidateTemperature(double temp, string paramName)
    {
        if (double.IsNaN(temp) || double.IsInfinity(temp))
            throw new ArgumentException($"Invalid temperature: {temp}", paramName);
        
        if (temp < -273.15)
            throw new ArgumentOutOfRangeException(paramName, "Temperature below absolute zero");
        
        if (temp > 1000.0)
            throw new ArgumentOutOfRangeException(paramName, "Temperature too high for system");
        
        return temp;
    }
    
    public static double ValidateBrix(double brix, string paramName)
    {
        if (double.IsNaN(brix) || double.IsInfinity(brix))
            throw new ArgumentException($"Invalid Brix value: {brix}", paramName);
        
        return Math.Clamp(brix, 0.0, 100.0);
    }
}

Manejo de Errores de Cálculo

Recuperación de Errores Numéricos

public static class SafeCalculations
{
    public static double SafeDivision(double numerator, double denominator, double fallback = 0.0)
    {
        if (Math.Abs(denominator) < 1e-10)
            return fallback;
        
        var result = numerator / denominator;
        
        if (double.IsNaN(result) || double.IsInfinity(result))
            return fallback;
        
        return result;
    }
    
    public static double SafeExponential(double exponent, double maxResult = 1e6)
    {
        if (exponent > Math.Log(maxResult))
            return maxResult;
        
        if (exponent < -50.0) // Underflow protection
            return 0.0;
        
        return Math.Exp(exponent);
    }
}

📈 Métricas de Calidad del Código

Cobertura de Tests

  • Objetivo: >95% cobertura de líneas
  • Crítico: 100% para algoritmos de cálculo
  • Tests de Integración: Escenarios completos de proceso

Complejidad Ciclomática

  • Máximo: 10 por método
  • Promedio: <5 por clase
  • Refactoring: Automático cuando se exceden límites

Documentación

  • XML Documentation: 100% de métodos públicos
  • Ejemplos de Uso: Para cada funcionalidad principal
  • Diagramas de Flujo: Para algoritmos complejos

🔄 Versionado y Compatibilidad

Evolución del API

Versionado Semántico

  • Major: Cambios incompatibles (ej: 1.x → 2.x)
  • Minor: Nuevas funcionalidades compatibles (ej: 2.1 → 2.2)
  • Patch: Correcciones de bugs (ej: 2.1.0 → 2.1.1)

Migración de Datos

public class FluidDataMigration
{
    public static FluidProperties MigrateFromV1(LegacyFluidData legacy)
    {
        return new FluidProperties
        {
            FluidType = MapLegacyType(legacy.Type),
            Temperature = legacy.TempCelsius,
            ConcentrationBrix = legacy.Concentration ?? 0.0
        };
    }
    
    private static FluidType MapLegacyType(string legacyType)
    {
        return legacyType.ToLower() switch
        {
            "water" => FluidType.Water,
            "syrup" => FluidType.Syrup,
            "cleaning" => FluidType.CausticSoda,
            _ => FluidType.Water
        };
    }
}

Especificaciones Técnicas Detalladas
Versión: 2.0 - Septiembre 2025
Documento de Referencia para Desarrolladores