660 lines
26 KiB
C#
660 lines
26 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using CtrEditor.HydraulicSimulator;
|
|
using CtrEditor.HydraulicSimulator.TSNet.Components;
|
|
using CtrEditor.ObjetosSim;
|
|
using CtrEditor.FuncionesBase;
|
|
using Newtonsoft.Json;
|
|
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using HydraulicSimulator.Models;
|
|
|
|
namespace CtrEditor.ObjetosSim
|
|
{
|
|
/// <summary>
|
|
/// Tubería hidráulica simplificada para integración con TSNet
|
|
/// </summary>
|
|
public partial class osHydPipe : osBase, IHydraulicComponent, IHydraulicFlowReceiver, IHydraulicPressureReceiver, IosBase
|
|
{
|
|
public static string NombreCategoria() => "Componentes Hidráulicos";
|
|
|
|
public static string NombreClase() => "Tubería Hidráulica";
|
|
|
|
// Private fields para TSNet
|
|
private double _length = 1.0; // m - longitud de la tubería
|
|
private double _diameter = 0.05; // m - diámetro interno
|
|
private double _roughness = 4.5e-5; // m - rugosidad del material
|
|
|
|
// Estado actual (desde TSNet)
|
|
private double _currentFlow = 0.0; // m³/s - flujo actual
|
|
private double _pressureDrop = 0.0; // Pa - caída de presión
|
|
private double _velocity = 0.0; // m/s - velocidad del fluido
|
|
|
|
// TSNet Integration
|
|
[JsonIgnore]
|
|
public TSNetPipeAdapter? TSNetAdapter { get; private set; }
|
|
|
|
// Propiedades visuales
|
|
[ObservableProperty]
|
|
[property: Category("🎨 Apariencia")]
|
|
[property: Description("Ancho visual de la tubería en metros")]
|
|
[property: Name("Ancho")]
|
|
private float ancho = 1.0f;
|
|
|
|
[ObservableProperty]
|
|
[property: Category("🎨 Apariencia")]
|
|
[property: Description("Alto visual de la tubería en metros")]
|
|
[property: Name("Alto")]
|
|
private float alto = 0.05f;
|
|
|
|
[ObservableProperty]
|
|
[property: Category("🎨 Apariencia")]
|
|
[property: Description("Color visual de la tubería")]
|
|
[property: Name("Color")]
|
|
private Brush colorButton_oculto = Brushes.Gray;
|
|
|
|
[ObservableProperty]
|
|
[property: Category("🎨 Apariencia")]
|
|
[property: Description("Ángulo de rotación de la tubería en grados")]
|
|
[property: Name("Ángulo")]
|
|
private float angulo = 0f;
|
|
|
|
// Propiedades de conexión
|
|
[ObservableProperty]
|
|
[property: Category("🔗 Conexiones")]
|
|
[property: Description("Primer componente hidráulico conectado")]
|
|
[property: Name("Componente A")]
|
|
[property: ItemsSource(typeof(osBaseItemsSource<IHydraulicComponent>))]
|
|
private string id_ComponenteA = "";
|
|
|
|
[ObservableProperty]
|
|
[property: Category("🔗 Conexiones")]
|
|
[property: Description("Segundo componente hidráulico conectado")]
|
|
[property: Name("Componente B")]
|
|
[property: ItemsSource(typeof(osBaseItemsSource<IHydraulicComponent>))]
|
|
private string id_ComponenteB = "";
|
|
|
|
// Constructor
|
|
public osHydPipe()
|
|
{
|
|
try
|
|
{
|
|
Nombre = "Tubería Hidráulica";
|
|
Ancho = 1.0f;
|
|
Alto = 0.05f;
|
|
Angulo = 0f;
|
|
Lock_movement = false;
|
|
|
|
Debug.WriteLine($"osHydPipe Constructor completado correctamente");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"Error en constructor osHydPipe: {ex.Message}");
|
|
Nombre = "Tubería Hidráulica";
|
|
Ancho = 1.0f;
|
|
Alto = 0.05f;
|
|
}
|
|
}
|
|
|
|
// Propiedades de configuración de la tubería
|
|
[Category("🔧 Tubería Hidráulica")]
|
|
[DisplayName("Longitud")]
|
|
[Description("Longitud de la tubería en metros")]
|
|
public double Length
|
|
{
|
|
get => _length;
|
|
set
|
|
{
|
|
if (SetProperty(ref _length, Math.Max(0.1, value)))
|
|
{
|
|
InvalidateHydraulicNetwork();
|
|
}
|
|
}
|
|
}
|
|
|
|
[Category("🔧 Tubería Hidráulica")]
|
|
[DisplayName("Diámetro")]
|
|
[Description("Diámetro interno de la tubería en metros")]
|
|
public double Diameter
|
|
{
|
|
get => _diameter;
|
|
set
|
|
{
|
|
if (SetProperty(ref _diameter, Math.Max(0.001, value)))
|
|
{
|
|
InvalidateHydraulicNetwork();
|
|
}
|
|
}
|
|
}
|
|
|
|
[Category("🔧 Tubería Hidráulica")]
|
|
[DisplayName("Rugosidad")]
|
|
[Description("Rugosidad del material en metros")]
|
|
public double Roughness
|
|
{
|
|
get => _roughness;
|
|
set
|
|
{
|
|
if (SetProperty(ref _roughness, Math.Max(1e-6, value)))
|
|
{
|
|
InvalidateHydraulicNetwork();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Estado actual (desde TSNet)
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Flujo actual")]
|
|
[Description("Flujo actual a través de la tubería (m³/s)")]
|
|
[ReadOnly(true)]
|
|
public double CurrentFlow
|
|
{
|
|
get => _currentFlow;
|
|
private set => SetProperty(ref _currentFlow, value);
|
|
}
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Caída de presión")]
|
|
[Description("Caída de presión en la tubería (Pa)")]
|
|
[ReadOnly(true)]
|
|
public double PressureDrop
|
|
{
|
|
get => _pressureDrop;
|
|
private set => SetProperty(ref _pressureDrop, value);
|
|
}
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Velocidad")]
|
|
[Description("Velocidad del fluido en la tubería (m/s)")]
|
|
[ReadOnly(true)]
|
|
public double FluidVelocity
|
|
{
|
|
get => _velocity;
|
|
private set => SetProperty(ref _velocity, value);
|
|
}
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Flujo (L/min)")]
|
|
[Description("Flujo actual en L/min")]
|
|
[ReadOnly(true)]
|
|
public double CurrentFlowLMin => Math.Abs(CurrentFlow) * 60000.0; // m³/s a L/min
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Caída presión (bar)")]
|
|
[Description("Caída de presión en bar")]
|
|
[ReadOnly(true)]
|
|
public double PressureDropBar => PressureDrop / 100000.0; // Pa a bar
|
|
|
|
[Category("📊 Estado Actual")]
|
|
[DisplayName("Tiene flujo")]
|
|
[Description("Indica si hay flujo en la tubería")]
|
|
[ReadOnly(true)]
|
|
public bool HasFlow => Math.Abs(CurrentFlow) > 1e-6;
|
|
|
|
// Métodos básicos
|
|
private string nombre = NombreClase();
|
|
|
|
[Category("🏷️ Identificación")]
|
|
[Description("Nombre identificativo del objeto")]
|
|
[Name("Nombre")]
|
|
public override string Nombre
|
|
{
|
|
get => nombre;
|
|
set => SetProperty(ref nombre, value);
|
|
}
|
|
|
|
public override void OnMove(float LeftPixels, float TopPixels)
|
|
{
|
|
// Movimiento básico
|
|
}
|
|
|
|
public override void OnResize(float Delta_Width, float Delta_Height)
|
|
{
|
|
Ancho += Delta_Width;
|
|
Alto += Delta_Height;
|
|
}
|
|
|
|
public override void UpdateGeometryStart()
|
|
{
|
|
// El componente se registra automáticamente como IHydraulicComponent
|
|
}
|
|
|
|
public override void UpdateControl(int elapsedMilliseconds)
|
|
{
|
|
// Los valores provienen de TSNet
|
|
OnPropertyChanged(nameof(CurrentFlowLMin));
|
|
OnPropertyChanged(nameof(PressureDropBar));
|
|
OnPropertyChanged(nameof(HasFlow));
|
|
|
|
UpdatePipeColor();
|
|
}
|
|
|
|
private void UpdatePipeColor()
|
|
{
|
|
// Cambiar color según el flujo
|
|
if (HasFlow)
|
|
{
|
|
var flowPercent = Math.Min(1.0, CurrentFlowLMin / 100.0); // normalizar a 100 L/min
|
|
var intensity = (byte)(255 * flowPercent);
|
|
ColorButton_oculto = new SolidColorBrush(Color.FromRgb(intensity, (byte)(255 - intensity), 0));
|
|
}
|
|
else
|
|
{
|
|
ColorButton_oculto = Brushes.Gray;
|
|
}
|
|
}
|
|
|
|
private void InvalidateHydraulicNetwork()
|
|
{
|
|
// Invalidar la red hidráulica para que se recalcule
|
|
var mainViewModel = Application.Current?.MainWindow?.DataContext as MainViewModel;
|
|
mainViewModel?.InvalidateHydraulicNetwork();
|
|
}
|
|
|
|
// Implementación de interfaces hidráulicas
|
|
public void ApplyHydraulicPressure(double pressurePa)
|
|
{
|
|
// La caída de presión se calcula en TSNet
|
|
}
|
|
|
|
public void ApplyHydraulicFlow(double flowM3s)
|
|
{
|
|
CurrentFlow = flowM3s;
|
|
|
|
// Calcular velocidad
|
|
if (Diameter > 0)
|
|
{
|
|
var area = Math.PI * Math.Pow(Diameter / 2, 2); // m²
|
|
FluidVelocity = Math.Abs(CurrentFlow) / area; // m/s
|
|
}
|
|
}
|
|
|
|
public void UpdateHydraulicState(double timeSeconds)
|
|
{
|
|
// TSNet maneja el estado
|
|
}
|
|
|
|
// Métodos para TSNet
|
|
public void UpdateFromTSNetResults(double flow, double pressureDrop)
|
|
{
|
|
CurrentFlow = flow;
|
|
PressureDrop = pressureDrop;
|
|
|
|
// Calcular velocidad
|
|
if (Diameter > 0)
|
|
{
|
|
var area = Math.PI * Math.Pow(Diameter / 2, 2); // m²
|
|
FluidVelocity = Math.Abs(CurrentFlow) / area; // m/s
|
|
}
|
|
}
|
|
|
|
// Crear adapter para TSNet
|
|
public TSNetPipeAdapter CreateTSNetAdapter()
|
|
{
|
|
TSNetAdapter = new TSNetPipeAdapter(this);
|
|
return TSNetAdapter;
|
|
}
|
|
|
|
// Implementación de IHydraulicComponent
|
|
[JsonIgnore]
|
|
public bool HasHydraulicComponents => true;
|
|
|
|
public List<HydraulicNodeDefinition> GetHydraulicNodes()
|
|
{
|
|
// Las tuberías no crean nodos propios, se conectan entre nodos existentes
|
|
return new List<HydraulicNodeDefinition>();
|
|
}
|
|
|
|
public void ApplyHydraulicResults(Dictionary<string, double> flows, Dictionary<string, double> pressures)
|
|
{
|
|
try
|
|
{
|
|
// Buscar resultados de esta tubería en TSNet
|
|
var pipeElementName = $"PIPE_{Nombre}";
|
|
if (flows.ContainsKey(pipeElementName))
|
|
{
|
|
var pipeFlow = flows[pipeElementName];
|
|
ApplyHydraulicFlow(pipeFlow);
|
|
}
|
|
|
|
// Calcular caída de presión si tenemos datos de los nodos conectados
|
|
if (!string.IsNullOrEmpty(Id_ComponenteA) && !string.IsNullOrEmpty(Id_ComponenteB))
|
|
{
|
|
if (pressures.ContainsKey(Id_ComponenteA) && pressures.ContainsKey(Id_ComponenteB))
|
|
{
|
|
var pressureA = pressures[Id_ComponenteA];
|
|
var pressureB = pressures[Id_ComponenteB];
|
|
PressureDrop = Math.Abs(pressureA - pressureB);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"Error en Pipe {Nombre} ApplyHydraulicResults: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public List<HydraulicElementDefinition> GetHydraulicElements()
|
|
{
|
|
var elements = new List<HydraulicElementDefinition>();
|
|
|
|
// Verificar que la tubería esté conectada a dos componentes
|
|
if (!string.IsNullOrEmpty(Id_ComponenteA) && !string.IsNullOrEmpty(Id_ComponenteB))
|
|
{
|
|
try
|
|
{
|
|
// Resolver los nombres de los componentes conectados
|
|
var nodeNameA = ResolveComponentNodeName(Id_ComponenteA);
|
|
var nodeNameB = ResolveComponentNodeName(Id_ComponenteB);
|
|
|
|
if (!string.IsNullOrEmpty(nodeNameA) && !string.IsNullOrEmpty(nodeNameB))
|
|
{
|
|
// Crear elemento pipe con propiedades correctas
|
|
var pipeElement = new Pipe(Length, Diameter, Roughness);
|
|
|
|
elements.Add(new HydraulicElementDefinition(
|
|
$"PIPE_{Nombre}",
|
|
nodeNameA,
|
|
nodeNameB,
|
|
pipeElement,
|
|
$"Tubería - L:{Length:F1}m, D:{Diameter*1000:F0}mm, Rough:{Roughness*1000:F2}mm"
|
|
));
|
|
|
|
if (VerboseOutput)
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: Conectando nodos '{nodeNameA}' -> '{nodeNameB}'");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine($"Warning: Pipe {Nombre} no pudo resolver nombres de nodos. " +
|
|
$"ComponenteA='{Id_ComponenteA}', ComponenteB='{Id_ComponenteB}'");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"Error en GetHydraulicElements para pipe {Nombre}: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
return elements;
|
|
}
|
|
|
|
public void UpdateHydraulicProperties()
|
|
{
|
|
// Actualizar propiedades antes de la simulación
|
|
// Validar conexiones
|
|
if (string.IsNullOrEmpty(Id_ComponenteA) || string.IsNullOrEmpty(Id_ComponenteB))
|
|
{
|
|
Debug.WriteLine($"Warning: Tubería {Nombre} no está completamente conectada");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resuelve el ID de un componente al nombre del nodo hidráulico correspondiente
|
|
/// THREAD-SAFE: No accede a objetos WPF desde background threads
|
|
/// </summary>
|
|
private string ResolveComponentNodeName(string componentId)
|
|
{
|
|
try
|
|
{
|
|
// Debug: Log the original componentId
|
|
Debug.WriteLine($"Pipe {Nombre}: Resolviendo componentId '{componentId}'");
|
|
|
|
// Primero intentar usar el ID directamente como nombre (para compatibilidad)
|
|
if (!string.IsNullOrEmpty(componentId))
|
|
{
|
|
// Para evitar problemas de threading, usar el Dispatcher para acceder a objetos UI
|
|
MainViewModel mainViewModel = null;
|
|
|
|
// Solo acceder a la UI desde el thread principal
|
|
if (Application.Current?.Dispatcher?.CheckAccess() == true)
|
|
{
|
|
mainViewModel = Application.Current?.MainWindow?.DataContext as MainViewModel;
|
|
}
|
|
else
|
|
{
|
|
// Si estamos en un background thread, usar Invoke para acceder de forma segura
|
|
Application.Current?.Dispatcher?.Invoke(() =>
|
|
{
|
|
mainViewModel = Application.Current?.MainWindow?.DataContext as MainViewModel;
|
|
});
|
|
}
|
|
|
|
if (mainViewModel?.ObjetosSimulables != null)
|
|
{
|
|
List<osBase> hydraulicComponents = null;
|
|
|
|
// Obtener componentes de forma thread-safe
|
|
if (Application.Current?.Dispatcher?.CheckAccess() == true)
|
|
{
|
|
hydraulicComponents = mainViewModel.ObjetosSimulables
|
|
.OfType<IHydraulicComponent>()
|
|
.Where(comp => comp is osBase)
|
|
.Cast<osBase>()
|
|
.ToList();
|
|
}
|
|
else
|
|
{
|
|
Application.Current?.Dispatcher?.Invoke(() =>
|
|
{
|
|
hydraulicComponents = mainViewModel.ObjetosSimulables
|
|
.OfType<IHydraulicComponent>()
|
|
.Where(comp => comp is osBase)
|
|
.Cast<osBase>()
|
|
.ToList();
|
|
});
|
|
}
|
|
|
|
if (hydraulicComponents != null)
|
|
{
|
|
// Debug: Log available components
|
|
Debug.WriteLine($"Pipe {Nombre}: Componentes hidráulicos disponibles:");
|
|
foreach (var comp in hydraulicComponents)
|
|
{
|
|
Debug.WriteLine($" - Nombre: '{comp.Nombre}', ID: '{comp.Id?.Value}'");
|
|
}
|
|
|
|
// Buscar por nombre primero (caso más común)
|
|
var componentByName = hydraulicComponents
|
|
.FirstOrDefault(comp => comp.Nombre == componentId);
|
|
|
|
if (componentByName != null)
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: Encontrado componente por nombre: '{componentByName.Nombre}'");
|
|
|
|
// Verificar si es una bomba (requiere resolución especial de nodos)
|
|
if (componentByName is osHydPump)
|
|
{
|
|
var sanitizedName = SanitizeNodeName(componentByName.Nombre);
|
|
|
|
// Determinar si esta tubería está conectada a la entrada o salida de la bomba
|
|
// Basándonos en si la bomba es origen (ComponenteA) o destino (ComponenteB) de esta tubería
|
|
if (componentId == Id_ComponenteA)
|
|
{
|
|
// La bomba es ComponenteA (origen de esta tubería)
|
|
// Por lo tanto, conectamos desde la salida de la bomba (NODE_B)
|
|
Debug.WriteLine($"Pipe {Nombre}: Bomba como origen - conectando desde salida: NODE_B_{sanitizedName}");
|
|
return $"NODE_B_{sanitizedName}";
|
|
}
|
|
else if (componentId == Id_ComponenteB)
|
|
{
|
|
// La bomba es ComponenteB (destino de esta tubería)
|
|
// Por lo tanto, conectamos hacia la entrada de la bomba (NODE_A)
|
|
Debug.WriteLine($"Pipe {Nombre}: Bomba como destino - conectando hacia entrada: NODE_A_{sanitizedName}");
|
|
return $"NODE_A_{sanitizedName}";
|
|
}
|
|
else
|
|
{
|
|
// Fallback: usar salida por defecto
|
|
Debug.WriteLine($"Pipe {Nombre}: Usando salida por defecto de bomba: NODE_B_{sanitizedName}");
|
|
return $"NODE_B_{sanitizedName}";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Para tanques y otras componentes, usar el nombre sanitizado
|
|
return SanitizeNodeName(componentByName.Nombre);
|
|
}
|
|
}
|
|
|
|
// Si no se encuentra por nombre, buscar por ID único (convertir string a int)
|
|
if (int.TryParse(componentId, out int idValue))
|
|
{
|
|
var componentById = hydraulicComponents
|
|
.FirstOrDefault(comp => comp.Id?.Value == idValue);
|
|
|
|
if (componentById != null)
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: Encontrado componente por ID {idValue}: '{componentById.Nombre}'");
|
|
|
|
// Verificar si es una bomba (requiere resolución especial de nodos)
|
|
if (componentById is osHydPump)
|
|
{
|
|
var sanitizedName = SanitizeNodeName(componentById.Nombre);
|
|
|
|
// Determinar si esta tubería está conectada a la entrada o salida de la bomba
|
|
if (componentId == Id_ComponenteA)
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: Bomba como origen (ID) - conectando desde salida: NODE_B_{sanitizedName}");
|
|
return $"NODE_B_{sanitizedName}";
|
|
}
|
|
else if (componentId == Id_ComponenteB)
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: Bomba como destino (ID) - conectando hacia entrada: NODE_A_{sanitizedName}");
|
|
return $"NODE_A_{sanitizedName}";
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: Usando salida por defecto de bomba (ID): NODE_B_{sanitizedName}");
|
|
return $"NODE_B_{sanitizedName}";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return SanitizeNodeName(componentById.Nombre);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Último intento: usar el componentId directamente si es un nombre válido
|
|
Debug.WriteLine($"Pipe {Nombre}: No se encontró componente, usando '{componentId}' directamente");
|
|
return SanitizeNodeName(componentId);
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: MainViewModel o ObjetosSimulables es null");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine($"Pipe {Nombre}: componentId está vacío");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"Error resolviendo componente '{componentId}': {ex.Message}");
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sanitiza nombres de nodos para compatibilidad con EPANET INP
|
|
/// </summary>
|
|
private string SanitizeNodeName(string nodeName)
|
|
{
|
|
if (string.IsNullOrEmpty(nodeName))
|
|
return string.Empty;
|
|
|
|
// Reemplazar espacios y caracteres especiales con guiones bajos
|
|
var sanitized = nodeName
|
|
.Replace(" ", "_")
|
|
.Replace("á", "a")
|
|
.Replace("é", "e")
|
|
.Replace("í", "i")
|
|
.Replace("ó", "o")
|
|
.Replace("ú", "u")
|
|
.Replace("ü", "u")
|
|
.Replace("ñ", "n")
|
|
.Replace("Á", "A")
|
|
.Replace("É", "E")
|
|
.Replace("Í", "I")
|
|
.Replace("Ó", "O")
|
|
.Replace("Ú", "U")
|
|
.Replace("Ü", "U")
|
|
.Replace("Ñ", "N");
|
|
|
|
// Remover caracteres no válidos para EPANET
|
|
var validChars = sanitized.Where(c => char.IsLetterOrDigit(c) || c == '_' || c == '-').ToArray();
|
|
return new string(validChars);
|
|
}
|
|
|
|
private bool VerboseOutput => true; // Habilitar salida detallada para debugging
|
|
|
|
// Implementación de IHydraulicFlowReceiver
|
|
public void SetFlow(double flow)
|
|
{
|
|
ApplyHydraulicFlow(flow);
|
|
}
|
|
|
|
public double GetFlow()
|
|
{
|
|
return CurrentFlow;
|
|
}
|
|
|
|
// Implementación de IHydraulicPressureReceiver
|
|
public void SetPressure(double pressure)
|
|
{
|
|
// Las tuberías no tienen presión propia, solo caída de presión
|
|
}
|
|
|
|
public double GetPressure()
|
|
{
|
|
return PressureDrop;
|
|
}
|
|
|
|
// Implementación de IosBase
|
|
public void Start()
|
|
{
|
|
// Inicialización de la tubería para la simulación
|
|
}
|
|
|
|
public void Inicializar(int valorInicial)
|
|
{
|
|
// Inicialización con valor inicial
|
|
}
|
|
|
|
public void Disposing()
|
|
{
|
|
// Limpieza si es necesaria
|
|
}
|
|
|
|
public int zIndex_fromFrames { get; set; } = 1;
|
|
|
|
public ZIndexEnum ZIndex_Base()
|
|
{
|
|
return ZIndexEnum.Estaticos;
|
|
}
|
|
|
|
public override void CopyFrom(osBase source)
|
|
{
|
|
if (source is osHydPipe sourcePipe)
|
|
{
|
|
Length = sourcePipe.Length;
|
|
Diameter = sourcePipe.Diameter;
|
|
Roughness = sourcePipe.Roughness;
|
|
Id_ComponenteA = sourcePipe.Id_ComponenteA;
|
|
Id_ComponenteB = sourcePipe.Id_ComponenteB;
|
|
}
|
|
base.CopyFrom(source);
|
|
}
|
|
}
|
|
}
|