518 lines
14 KiB
Markdown
518 lines
14 KiB
Markdown
# 🔬 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**
|
||
```csharp
|
||
// 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**
|
||
```csharp
|
||
// 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)**
|
||
```csharp
|
||
// 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)**
|
||
```csharp
|
||
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**
|
||
```csharp
|
||
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**
|
||
```csharp
|
||
// 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**
|
||
```csharp
|
||
[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**
|
||
```csharp
|
||
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**
|
||
```csharp
|
||
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**
|
||
```csharp
|
||
[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**
|
||
```csharp
|
||
[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**
|
||
```csharp
|
||
[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**
|
||
```csharp
|
||
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**
|
||
```csharp
|
||
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**
|
||
```csharp
|
||
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*
|