180 lines
8.7 KiB
C#
180 lines
8.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using HydraulicSimulator.Models;
|
|
using CtrEditor.HydraulicSimulator;
|
|
using CtrEditor.ObjetosSim.HydraulicComponents;
|
|
|
|
namespace CtrEditor.HydraulicSimulator.Examples
|
|
{
|
|
/// <summary>
|
|
/// Ejemplo de uso de los componentes hidráulicos según la documentación
|
|
/// Muestra cómo crear una red simple: Bomba -> Tubería -> Tanque de Descarga
|
|
/// </summary>
|
|
public class SimpleHydraulicSystemExample
|
|
{
|
|
/// <summary>
|
|
/// Crea un sistema hidráulico simple con bomba, tubería y tanque
|
|
/// </summary>
|
|
public static void RunExample()
|
|
{
|
|
Console.WriteLine("🚀 Iniciando ejemplo de sistema hidráulico simple");
|
|
Console.WriteLine("Sistema: Bomba -> Tubería -> Tanque de Descarga");
|
|
Console.WriteLine();
|
|
|
|
// 1. Crear la red hidráulica
|
|
var network = new HydraulicNetwork();
|
|
|
|
// 2. Agregar nodos según la documentación
|
|
network.AddNode("SUMINISTRO", 0); // Tanque de suministro a presión atmosférica
|
|
network.AddNode("BOMBA_OUT"); // Salida de bomba (presión calculada)
|
|
network.AddNode("TANQUE_DESCARGA", 0); // Tanque de descarga libre
|
|
|
|
// 3. Crear elementos hidráulicos
|
|
var pump = new PumpHQ(
|
|
h0: 80, // Cabeza a caudal cero: 80 metros
|
|
q0: 0.01, // Caudal a cabeza cero: 0.01 m³/s (36 m³/h)
|
|
speedRel: 1.0, // Velocidad nominal
|
|
direction: 1 // Dirección normal
|
|
);
|
|
|
|
var pipe = new Pipe(
|
|
length: 50, // 50 metros de longitud
|
|
diameter: 0.08, // 80mm de diámetro
|
|
roughness: 0.0015 // Rugosidad del acero comercial
|
|
);
|
|
|
|
// 4. Conectar elementos en ramas según la documentación
|
|
network.AddBranch("SUMINISTRO", "BOMBA_OUT",
|
|
new List<Element> { pump }, "Bomba_Principal");
|
|
|
|
network.AddBranch("BOMBA_OUT", "TANQUE_DESCARGA",
|
|
new List<Element> { pipe }, "Tuberia_Descarga");
|
|
|
|
// 5. Resolver la red
|
|
Console.WriteLine("⚙️ Resolviendo red hidráulica...");
|
|
var result = network.Solve(
|
|
maxIterations: 200,
|
|
tolerance: 1e-4,
|
|
verbose: true
|
|
);
|
|
|
|
// 6. Mostrar resultados
|
|
if (result.Converged)
|
|
{
|
|
Console.WriteLine("✅ Simulación exitosa!");
|
|
Console.WriteLine($"Convergió en {result.Iterations} iteraciones");
|
|
Console.WriteLine();
|
|
|
|
ShowResults(result);
|
|
ShowComponentAnalysis(result, pump, pipe);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"❌ No convergió después de {result.Iterations} iteraciones");
|
|
Console.WriteLine($"Error final: {result.Residual:E6}");
|
|
}
|
|
}
|
|
|
|
private static void ShowResults(SolutionResult result)
|
|
{
|
|
Console.WriteLine("📊 RESULTADOS DE LA SIMULACIÓN:");
|
|
Console.WriteLine("═══════════════════════════════");
|
|
|
|
// Flujos
|
|
Console.WriteLine("🌊 Flujos:");
|
|
foreach (var flow in result.Flows)
|
|
{
|
|
double flowM3h = flow.Value * 3600; // Convertir a m³/h
|
|
double flowLmin = flow.Value * 60000; // Convertir a L/min
|
|
Console.WriteLine($" {flow.Key}:");
|
|
Console.WriteLine($" {flow.Value:F6} m³/s = {flowM3h:F2} m³/h = {flowLmin:F1} L/min");
|
|
}
|
|
|
|
Console.WriteLine();
|
|
|
|
// Presiones
|
|
Console.WriteLine("📈 Presiones:");
|
|
foreach (var pressure in result.Pressures)
|
|
{
|
|
double pressureBar = pressure.Value / 100000.0; // Convertir a bar
|
|
double pressureKPa = pressure.Value / 1000.0; // Convertir a kPa
|
|
Console.WriteLine($" {pressure.Key}:");
|
|
Console.WriteLine($" {pressure.Value:F0} Pa = {pressureKPa:F1} kPa = {pressureBar:F3} bar");
|
|
}
|
|
}
|
|
|
|
private static void ShowComponentAnalysis(SolutionResult result, PumpHQ pump, Pipe pipe)
|
|
{
|
|
Console.WriteLine();
|
|
Console.WriteLine("🔧 ANÁLISIS DE COMPONENTES:");
|
|
Console.WriteLine("═══════════════════════════");
|
|
|
|
// Análisis de la bomba
|
|
if (result.Flows.TryGetValue("Bomba_Principal", out double pumpFlow))
|
|
{
|
|
double pumpFlowM3h = pumpFlow * 3600;
|
|
double pumpHead = pump.Dp(pumpFlow, Fluid.Water20C) / (1000 * 9.81); // Convertir Pa a metros
|
|
double pumpPower = pumpFlow * pump.Dp(pumpFlow, Fluid.Water20C) / 1000; // Potencia hidráulica en kW
|
|
|
|
Console.WriteLine("💨 Bomba:");
|
|
Console.WriteLine($" Caudal: {pumpFlowM3h:F1} m³/h");
|
|
Console.WriteLine($" Cabeza: {pumpHead:F1} m");
|
|
Console.WriteLine($" Potencia hidráulica: {pumpPower:F2} kW");
|
|
}
|
|
|
|
// Análisis de la tubería
|
|
if (result.Flows.TryGetValue("Tuberia_Descarga", out double pipeFlow))
|
|
{
|
|
double pipePressureDrop = pipe.Dp(pipeFlow, Fluid.Water20C);
|
|
double pipeHeadLoss = pipePressureDrop / (1000 * 9.81); // Convertir Pa a metros
|
|
double velocity = Math.Abs(pipeFlow) / (Math.PI * (pipe.D * pipe.D) / 4.0);
|
|
|
|
Console.WriteLine();
|
|
Console.WriteLine("🚰 Tubería:");
|
|
Console.WriteLine($" Caudal: {pipeFlow * 3600:F1} m³/h");
|
|
Console.WriteLine($" Velocidad: {velocity:F2} m/s");
|
|
Console.WriteLine($" Pérdida de carga: {pipeHeadLoss:F2} m");
|
|
Console.WriteLine($" Pérdida de presión: {pipePressureDrop / 1000:F1} kPa");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ejemplo de cómo los objetos gráficos osHyd* se integrarían en la simulación
|
|
/// </summary>
|
|
public static void ShowGraphicObjectsIntegration()
|
|
{
|
|
Console.WriteLine();
|
|
Console.WriteLine("🎨 INTEGRACIÓN CON OBJETOS GRÁFICOS:");
|
|
Console.WriteLine("═══════════════════════════════════");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Los objetos creados (osHydPump, osHydPipe, osHydDischargeTank)");
|
|
Console.WriteLine("se integran automáticamente en el sistema de la siguiente manera:");
|
|
Console.WriteLine();
|
|
Console.WriteLine("1. 📋 Registro automático:");
|
|
Console.WriteLine(" - Se registran por reflexión usando NombreCategoria() = \"Hidráulicos\"");
|
|
Console.WriteLine(" - Aparecen en la categoría \"Hidráulicos\" del editor");
|
|
Console.WriteLine();
|
|
Console.WriteLine("2. 🔗 Sistema de conexiones:");
|
|
Console.WriteLine(" - Usan ItemsSource<IHydraulicComponent> para filtrar componentes");
|
|
Console.WriteLine(" - Similar al sistema Motor/Transporte existente");
|
|
Console.WriteLine(" - Conexiones: Id_InletComponent, Id_OutletComponent");
|
|
Console.WriteLine();
|
|
Console.WriteLine("3. 🚫 No participan en Bepu:");
|
|
Console.WriteLine(" - Override Start() sin crear geometrías Bepu");
|
|
Console.WriteLine(" - Solo participan en el simulador hidráulico");
|
|
Console.WriteLine();
|
|
Console.WriteLine("4. 📊 Integración con HydraulicSimulationManager:");
|
|
Console.WriteLine(" - Implementan IHydraulicComponent para GetHydraulicNodes()");
|
|
Console.WriteLine(" - Implementan GetHydraulicElements() para el solver");
|
|
Console.WriteLine(" - Reciben resultados via ApplyHydraulicResults()");
|
|
Console.WriteLine();
|
|
Console.WriteLine("5. 🎯 Ejemplo de configuración:");
|
|
Console.WriteLine(" osHydPump (Nombre=\"Bomba_01\", H0=80m, Q0=36m³/h)");
|
|
Console.WriteLine(" ↓ (Id_OutletComponent=\"Tuberia_01\")");
|
|
Console.WriteLine(" osHydPipe (Nombre=\"Tuberia_01\", L=50m, D=80mm)");
|
|
Console.WriteLine(" ↓ (Id_OutletComponent=\"Tanque_01\")");
|
|
Console.WriteLine(" osHydDischargeTank (Nombre=\"Tanque_01\", Area=1m²)");
|
|
}
|
|
}
|
|
}
|