410 lines
13 KiB
Markdown
410 lines
13 KiB
Markdown
# 🔧 Mejoras Necesarias al Sistema de Fluidos - CtrEditor
|
|
|
|
## 🎯 Problemas Identificados
|
|
|
|
### 1. **Tuberías (osHydPipe)** - Falta Información de Fluidos
|
|
**Problema**: Las tuberías no muestran:
|
|
- Tipo de fluido que las atraviesa
|
|
- Propiedades del fluido (temperatura, Brix, viscosidad)
|
|
- Flujo en unidades apropiadas (L/min)
|
|
- Color visual basado en el tipo de fluido
|
|
|
|
**Estado Actual**:
|
|
```csharp
|
|
[Category("📊 Estado")]
|
|
[Description("Flujo actual a través de la tubería en m³/s")]
|
|
public double CurrentFlow { get; set; }
|
|
|
|
[Category("📊 Estado")]
|
|
[Description("Pérdida de presión en la tubería en Pa")]
|
|
public double PressureDrop { get; set; }
|
|
```
|
|
|
|
**Propiedades Faltantes**:
|
|
```csharp
|
|
// Propiedades de fluido que deben agregarse
|
|
public FluidProperties CurrentFluid { get; set; }
|
|
public string CurrentFluidDescription { get; }
|
|
public double CurrentFlowLMin { get; } // Flujo en L/min
|
|
public SolidColorBrush FluidColor { get; } // Color basado en el fluido
|
|
```
|
|
|
|
### 2. **Bomba (osHydPump)** - Sin Información del Fluido Bombeado
|
|
**Problema**: La bomba no muestra:
|
|
- Tipo de fluido que está bombeando
|
|
- Propiedades del fluido actual
|
|
- Efecto de la viscosidad en el rendimiento
|
|
- Color visual según el fluido
|
|
|
|
**Propiedades Faltantes**:
|
|
```csharp
|
|
public FluidProperties CurrentFluid { get; set; }
|
|
public string CurrentFluidDescription { get; }
|
|
public double ViscosityEffect { get; } // Factor de eficiencia por viscosidad
|
|
public double EffectiveFlow { get; } // Flujo ajustado por viscosidad
|
|
```
|
|
|
|
### 3. **Tanques (osHydTank)** - Gestión Inadecuada de Fluidos Duales
|
|
**Problema**:
|
|
- Los niveles de fluidos primario/secundario no disminuyen proporcionalmente
|
|
- Falta selector de tipo de flujo de salida (Primario/Secundario/Mix)
|
|
- El volumen total no se gestiona correctamente
|
|
|
|
**Funcionalidades Faltantes**:
|
|
```csharp
|
|
// Enum para tipo de salida
|
|
public enum TankOutputMode
|
|
{
|
|
Primary, // Solo fluido primario
|
|
Secondary, // Solo fluido secundario
|
|
Mixed // Mezcla según configuración
|
|
}
|
|
|
|
public TankOutputMode OutputMode { get; set; }
|
|
public double PrimaryLevelM { get; } // Nivel específico del primario
|
|
public double SecondaryLevelM { get; } // Nivel específico del secundario
|
|
```
|
|
|
|
## 🛠️ Implementación Propuesta
|
|
|
|
### Fase 1: Mejoras en osHydPipe
|
|
|
|
```csharp
|
|
public partial class osHydPipe : osBase, IHydraulicComponent
|
|
{
|
|
// Propiedades de fluido actuales
|
|
private FluidProperties _currentFluid = new FluidProperties(FluidType.Air);
|
|
|
|
[Category("🧪 Fluido Actual")]
|
|
[DisplayName("Tipo de fluido")]
|
|
[Description("Tipo de fluido que atraviesa la tubería")]
|
|
[ReadOnly(true)]
|
|
public FluidType CurrentFluidType
|
|
{
|
|
get => _currentFluid.Type;
|
|
private set
|
|
{
|
|
if (_currentFluid.Type != value)
|
|
{
|
|
_currentFluid.Type = value;
|
|
OnPropertyChanged();
|
|
OnPropertyChanged(nameof(CurrentFluidDescription));
|
|
OnPropertyChanged(nameof(FluidColor));
|
|
}
|
|
}
|
|
}
|
|
|
|
[Category("🧪 Fluido Actual")]
|
|
[DisplayName("Descripción")]
|
|
[Description("Descripción completa del fluido actual")]
|
|
[ReadOnly(true)]
|
|
public string CurrentFluidDescription => _currentFluid.Description;
|
|
|
|
[Category("📊 Estado")]
|
|
[DisplayName("Flujo (L/min)")]
|
|
[Description("Flujo actual en litros por minuto")]
|
|
[ReadOnly(true)]
|
|
public double CurrentFlowLMin => CurrentFlow * 60000.0; // Conversión de m³/s a L/min
|
|
|
|
[JsonIgnore]
|
|
public SolidColorBrush FluidColor
|
|
{
|
|
get
|
|
{
|
|
var colorHex = _currentFluid.Color;
|
|
return new SolidColorBrush((Color)ColorConverter.ConvertFromString(colorHex));
|
|
}
|
|
}
|
|
|
|
// Método para actualizar fluido desde componente fuente
|
|
public void UpdateFluidFromSource(FluidProperties sourceFluid)
|
|
{
|
|
if (sourceFluid != null)
|
|
{
|
|
_currentFluid = sourceFluid.Clone();
|
|
OnPropertyChanged(nameof(CurrentFluidType));
|
|
OnPropertyChanged(nameof(CurrentFluidDescription));
|
|
OnPropertyChanged(nameof(FluidColor));
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Fase 2: Mejoras en osHydPump
|
|
|
|
```csharp
|
|
public partial class osHydPump : osBase, IHydraulicComponent
|
|
{
|
|
private FluidProperties _currentFluid = new FluidProperties(FluidType.Air);
|
|
|
|
[Category("🧪 Fluido Actual")]
|
|
[DisplayName("Tipo de fluido")]
|
|
[Description("Tipo de fluido que está bombeando")]
|
|
[ReadOnly(true)]
|
|
public FluidType CurrentFluidType => _currentFluid.Type;
|
|
|
|
[Category("🧪 Fluido Actual")]
|
|
[DisplayName("Descripción")]
|
|
[Description("Descripción del fluido que se está bombeando")]
|
|
[ReadOnly(true)]
|
|
public string CurrentFluidDescription => _currentFluid.Description;
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Factor Viscosidad")]
|
|
[Description("Factor de eficiencia debido a la viscosidad del fluido")]
|
|
[ReadOnly(true)]
|
|
public double ViscosityEffect
|
|
{
|
|
get
|
|
{
|
|
// Factor basado en viscosidad del fluido vs agua
|
|
var waterViscosity = 0.001; // Pa·s
|
|
var currentViscosity = _currentFluid.Viscosity;
|
|
return Math.Max(0.1, Math.Min(1.0, waterViscosity / currentViscosity));
|
|
}
|
|
}
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Flujo Efectivo (L/min)")]
|
|
[Description("Flujo real ajustado por viscosidad")]
|
|
[ReadOnly(true)]
|
|
public double EffectiveFlowLMin => CurrentFlow * 60000.0 * ViscosityEffect;
|
|
|
|
// Método para actualizar fluido desde tanque de succión
|
|
public void UpdateFluidFromSuction()
|
|
{
|
|
// Buscar tanque o componente conectado en la succión
|
|
var suctionComponent = FindSuctionComponent();
|
|
if (suctionComponent is osHydTank tank)
|
|
{
|
|
_currentFluid = tank.CurrentOutputFluid.Clone();
|
|
OnPropertyChanged(nameof(CurrentFluidType));
|
|
OnPropertyChanged(nameof(CurrentFluidDescription));
|
|
OnPropertyChanged(nameof(ViscosityEffect));
|
|
OnPropertyChanged(nameof(EffectiveFlowLMin));
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Fase 3: Mejoras en osHydTank
|
|
|
|
```csharp
|
|
public partial class osHydTank : osBase, IHydraulicComponent
|
|
{
|
|
private TankOutputMode _outputMode = TankOutputMode.Primary;
|
|
|
|
[Category("🔄 Control de Salida")]
|
|
[DisplayName("Modo de salida")]
|
|
[Description("Selecciona qué fluido sale del tanque")]
|
|
public TankOutputMode OutputMode
|
|
{
|
|
get => _outputMode;
|
|
set
|
|
{
|
|
if (SetProperty(ref _outputMode, value))
|
|
{
|
|
OnPropertyChanged(nameof(CurrentOutputFluid));
|
|
OnPropertyChanged(nameof(CurrentFluidDescription));
|
|
InvalidateHydraulicNetwork();
|
|
}
|
|
}
|
|
}
|
|
|
|
[Category("📊 Niveles Específicos")]
|
|
[DisplayName("Nivel Primario (m)")]
|
|
[Description("Nivel específico del fluido primario")]
|
|
[ReadOnly(true)]
|
|
public double PrimaryLevelM
|
|
{
|
|
get
|
|
{
|
|
if (CrossSectionalArea <= 0) return 0;
|
|
return PrimaryVolumeL / 1000.0 / CrossSectionalArea;
|
|
}
|
|
}
|
|
|
|
[Category("📊 Niveles Específicos")]
|
|
[DisplayName("Nivel Secundario (m)")]
|
|
[Description("Nivel específico del fluido secundario")]
|
|
[ReadOnly(true)]
|
|
public double SecondaryLevelM
|
|
{
|
|
get
|
|
{
|
|
if (CrossSectionalArea <= 0) return 0;
|
|
return SecondaryVolumeL / 1000.0 / CrossSectionalArea;
|
|
}
|
|
}
|
|
|
|
// Modificación del CurrentOutputFluid para considerar OutputMode
|
|
[JsonIgnore]
|
|
public override FluidProperties CurrentOutputFluid
|
|
{
|
|
get
|
|
{
|
|
return OutputMode switch
|
|
{
|
|
TankOutputMode.Primary => PrimaryVolumeL > 0 ? _primaryFluid.Clone() : new FluidProperties(FluidType.Air),
|
|
TankOutputMode.Secondary => SecondaryVolumeL > 0 ? _secondaryFluid.Clone() : new FluidProperties(FluidType.Air),
|
|
TankOutputMode.Mixed => CalculateMixedOutput(),
|
|
_ => new FluidProperties(FluidType.Air)
|
|
};
|
|
}
|
|
}
|
|
|
|
private FluidProperties CalculateMixedOutput()
|
|
{
|
|
if (PrimaryVolumeL <= 0 && SecondaryVolumeL <= 0)
|
|
return new FluidProperties(FluidType.Air);
|
|
|
|
if (PrimaryVolumeL <= 0)
|
|
return _secondaryFluid.Clone();
|
|
|
|
if (SecondaryVolumeL <= 0)
|
|
return _primaryFluid.Clone();
|
|
|
|
// Calcular ratio de mezcla basado en volúmenes
|
|
var totalVolume = PrimaryVolumeL + SecondaryVolumeL;
|
|
var mixRatio = SecondaryVolumeL / totalVolume;
|
|
|
|
return _primaryFluid.MixWith(_secondaryFluid, mixRatio);
|
|
}
|
|
|
|
// Método para actualizar volúmenes proporcionalmente durante el flujo
|
|
protected override void UpdateVolumeFromFlow(double deltaTimeSec)
|
|
{
|
|
var flowOutLMin = OutletFlow;
|
|
var flowInLMin = InletFlow;
|
|
var netFlowLMin = flowInLMin - flowOutLMin;
|
|
var deltaVolumeL = netFlowLMin * deltaTimeSec / 60.0;
|
|
|
|
if (deltaVolumeL < 0) // Salida neta
|
|
{
|
|
var outVolumeL = Math.Abs(deltaVolumeL);
|
|
|
|
// Reducir volúmenes según el modo de salida
|
|
switch (OutputMode)
|
|
{
|
|
case TankOutputMode.Primary:
|
|
PrimaryVolumeL = Math.Max(0, PrimaryVolumeL - outVolumeL);
|
|
break;
|
|
|
|
case TankOutputMode.Secondary:
|
|
SecondaryVolumeL = Math.Max(0, SecondaryVolumeL - outVolumeL);
|
|
break;
|
|
|
|
case TankOutputMode.Mixed:
|
|
// Reducir proporcionalmente
|
|
var totalVol = PrimaryVolumeL + SecondaryVolumeL;
|
|
if (totalVol > 0)
|
|
{
|
|
var primaryRatio = PrimaryVolumeL / totalVol;
|
|
var secondaryRatio = SecondaryVolumeL / totalVol;
|
|
|
|
PrimaryVolumeL = Math.Max(0, PrimaryVolumeL - (outVolumeL * primaryRatio));
|
|
SecondaryVolumeL = Math.Max(0, SecondaryVolumeL - (outVolumeL * secondaryRatio));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if (deltaVolumeL > 0) // Entrada neta
|
|
{
|
|
// El fluido que entra se añade al primario por defecto
|
|
// TODO: Implementar lógica para determinar tipo de fluido entrante
|
|
PrimaryVolumeL += deltaVolumeL;
|
|
}
|
|
|
|
// Actualizar nivel total
|
|
CurrentVolumeL = PrimaryVolumeL + SecondaryVolumeL;
|
|
CurrentLevelM = CurrentVolumeL / 1000.0 / Math.Max(0.1, CrossSectionalArea);
|
|
}
|
|
}
|
|
|
|
public enum TankOutputMode
|
|
{
|
|
[Description("Solo fluido primario")]
|
|
Primary,
|
|
|
|
[Description("Solo fluido secundario")]
|
|
Secondary,
|
|
|
|
[Description("Mezcla proporcional")]
|
|
Mixed
|
|
}
|
|
```
|
|
|
|
## 🔄 Lógica de Propagación de Fluidos
|
|
|
|
### Algoritmo de Propagación:
|
|
1. **Tanques** determinan el tipo de fluido que sale según `OutputMode`
|
|
2. **Bombas** toman el fluido del componente de succión
|
|
3. **Tuberías** transportan el fluido desde el componente fuente
|
|
4. **Actualización en tiempo real** durante la simulación
|
|
|
|
### Implementación en UpdateControl():
|
|
```csharp
|
|
public override void UpdateControl(int elapsedMilliseconds)
|
|
{
|
|
base.UpdateControl(elapsedMilliseconds);
|
|
|
|
// Actualizar propiedades del fluido
|
|
UpdateFluidProperties();
|
|
|
|
// Actualizar volúmenes (solo tanques)
|
|
if (this is osHydTank tank)
|
|
{
|
|
tank.UpdateVolumeFromFlow(elapsedMilliseconds / 1000.0);
|
|
}
|
|
}
|
|
|
|
private void UpdateFluidProperties()
|
|
{
|
|
// Lógica específica para cada tipo de componente
|
|
if (this is osHydPump pump)
|
|
{
|
|
pump.UpdateFluidFromSuction();
|
|
}
|
|
else if (this is osHydPipe pipe)
|
|
{
|
|
pipe.UpdateFluidFromSource();
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📋 Plan de Implementación
|
|
|
|
### Prioridad 1: Básico
|
|
- [ ] Agregar propiedades de fluido a osHydPipe
|
|
- [ ] Agregar propiedades de fluido a osHydPump
|
|
- [ ] Implementar TankOutputMode en osHydTank
|
|
|
|
### Prioridad 2: Funcional
|
|
- [ ] Implementar propagación de fluidos
|
|
- [ ] Actualización de volúmenes proporcional
|
|
- [ ] Colores visuales según tipo de fluido
|
|
|
|
### Prioridad 3: Avanzado
|
|
- [ ] Efectos de viscosidad en bombas
|
|
- [ ] Transitorios de mezcla
|
|
- [ ] Optimización de rendimiento
|
|
|
|
## 🧪 Tests de Validación
|
|
|
|
### Test 1: Propagación Básica
|
|
- Tanque con agua → Bomba → Tubería → Tanque
|
|
- Verificar que todas las propiedades se propaguen
|
|
|
|
### Test 2: Cambio de Modo de Salida
|
|
- Tanque con fluidos duales
|
|
- Cambiar OutputMode y verificar propagación
|
|
|
|
### Test 3: Efectos de Viscosidad
|
|
- Comparar bombeo de agua vs jarabe
|
|
- Verificar factor de eficiencia
|
|
|
|
---
|
|
|
|
*Documento Técnico - Mejoras Sistema de Fluidos*
|
|
*Fecha: Septiembre 2025*
|