Adding initial Project to git
This commit is contained in:
154
BWR.core/Components/Abstract/Component.cs
Normal file
154
BWR.core/Components/Abstract/Component.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
namespace MyBWRSimulator.Core.Components.Abstract
|
||||
{
|
||||
using MyBWRSimulator.Core.Interfaces;
|
||||
using MyBWRSimulator.Core.Ports;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq; // Needed for .ToList()
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for all simulated physical components.
|
||||
/// Implements ISimulatable, IFluidConnectable, and IThermalConnectable.
|
||||
/// </summary>
|
||||
public abstract class Component : ISimulatable, IFluidConnectable, IThermalConnectable
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique identifier for the component.
|
||||
/// </summary>
|
||||
public string ID { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable name of the component.
|
||||
/// </summary>
|
||||
public string Name { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Detailed description of the component.
|
||||
/// </summary>
|
||||
public string Description { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// An integer value indicating the order in which components should be updated.
|
||||
/// Lower numbers mean higher priority (updated first).
|
||||
/// </summary>
|
||||
public int UpdatePriority { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the component is receiving sufficient Thermal power.
|
||||
/// </summary>
|
||||
public bool IsPowered { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Collection of fluid ports belonging to this component, accessible by their ID.
|
||||
/// </summary>
|
||||
protected Dictionary<string, FluidPort> FluidPorts { get; set; } = new Dictionary<string, FluidPort>();
|
||||
|
||||
/// <summary>
|
||||
/// Collection of Thermal ports belonging to this component, accessible by their ID.
|
||||
/// </summary>
|
||||
protected Dictionary<string, ThermalPort> ThermalPorts { get; set; } = new Dictionary<string, ThermalPort>();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the Component base class.
|
||||
/// </summary>
|
||||
/// <param name="id">Unique identifier.</param>
|
||||
/// <param name="name">Human-readable name.</param>
|
||||
/// <param name="description">Description of the component.</param>
|
||||
/// <param name="updatePriority">Priority for simulation updates.</param>
|
||||
protected Component(string id, string name, string description, int updatePriority)
|
||||
{
|
||||
ID = id;
|
||||
Name = name;
|
||||
Description = description;
|
||||
UpdatePriority = updatePriority;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the component. Called once when the simulation starts or component is added.
|
||||
/// </summary>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
Console.WriteLine($"Initializing {Name} ({ID})...");
|
||||
// Placeholder for component-specific initialization logic
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down the component. Called once when the simulation ends or component is removed.
|
||||
/// </summary>
|
||||
public virtual void Shutdown()
|
||||
{
|
||||
Console.WriteLine($"Shutting down {Name} ({ID})...");
|
||||
// Placeholder for component-specific cleanup logic
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract method to update the component's state over a time step.
|
||||
/// Must be implemented by concrete component classes.
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">The time elapsed.</param>
|
||||
public abstract void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all fluid ports for this component.
|
||||
/// </summary>
|
||||
/// <returns>A list of FluidPort objects.</returns>
|
||||
public List<FluidPort> GetFluidPorts() => FluidPorts.Values.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a fluid port by its unique ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the fluid port.</param>
|
||||
/// <returns>The FluidPort object if found, otherwise null.</returns>
|
||||
public FluidPort GetFluidPortById(string id)
|
||||
{
|
||||
FluidPorts.TryGetValue(id, out FluidPort port);
|
||||
return port;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all Thermal ports for this component.
|
||||
/// </summary>
|
||||
/// <returns>A list of Thermal objects.</returns>
|
||||
public List<ThermalPort> GetThermalPorts() => ThermalPorts.Values.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an Thermal port by its unique ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the Thermal port.</param>
|
||||
/// <returns>The ThermalPort object if found, otherwise null.</returns>
|
||||
public ThermalPort GetThermalPortById(string id)
|
||||
{
|
||||
ThermalPorts.TryGetValue(id, out ThermalPort port);
|
||||
return port;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to add a fluid port to this component.
|
||||
/// </summary>
|
||||
/// <param name="port">The FluidPort to add.</param>
|
||||
/// <exception cref="ArgumentException">Thrown if a port with the same ID already exists.</exception>
|
||||
protected void AddFluidPort(FluidPort port)
|
||||
{
|
||||
if (FluidPorts.ContainsKey(port.ID))
|
||||
{
|
||||
throw new ArgumentException($"A fluid port with ID '{port.ID}' already exists on component '{Name}' ({ID}).");
|
||||
}
|
||||
port.ParentComponent = this;
|
||||
FluidPorts.Add(port.ID, port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to add an Thermal port to this component.
|
||||
/// </summary>
|
||||
/// <param name="port">The ThermalPort to add.</param>
|
||||
/// <exception cref="ArgumentException">Thrown if an Thermal port with the same ID already exists.</exception>
|
||||
protected void AddThermalPort(ThermalPort port)
|
||||
{
|
||||
if (ThermalPorts.ContainsKey(port.ID))
|
||||
{
|
||||
throw new ArgumentException($"An Thermal port with ID '{port.ID}' already exists on component '{Name}' ({ID}).");
|
||||
}
|
||||
port.ParentComponent = this;
|
||||
ThermalPorts.Add(port.ID, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
BWR.core/Components/Abstract/Port.cs
Normal file
77
BWR.core/Components/Abstract/Port.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
// MyBWRSimulator.Core/Components/Abstract/Port.cs
|
||||
namespace MyBWRSimulator.Core.Components.Abstract
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for all types of connection points on components.
|
||||
/// </summary>
|
||||
public abstract class Port
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID for the port (e.g., "Inlet1", "OutletA").
|
||||
/// </summary>
|
||||
public string ID { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A reference to the Port it's connected to. Null if not connected.
|
||||
/// </summary>
|
||||
public Port ConnectedPort { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A reference back to the component this port belongs to.
|
||||
/// </summary>
|
||||
public Component ParentComponent { get; internal set; } // Internal set by AddPort methods
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the Port base class.
|
||||
/// </summary>
|
||||
/// <param name="id">Unique identifier for the port.</param>
|
||||
protected Port(string id)
|
||||
{
|
||||
ID = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Establishes a connection between this port and another port.
|
||||
/// </summary>
|
||||
/// <param name="otherPort">The port to connect to.</param>
|
||||
public virtual void Connect(Port otherPort)
|
||||
{
|
||||
if (otherPort == null)
|
||||
{
|
||||
Console.WriteLine($"Error: Cannot connect {ID} to null port.");
|
||||
return;
|
||||
}
|
||||
if (ConnectedPort != null && ConnectedPort != otherPort)
|
||||
{
|
||||
Console.WriteLine($"Warning: {ID} is already connected to {ConnectedPort.ID}. Disconnecting first.");
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
ConnectedPort = otherPort;
|
||||
// For bidirectional connection, the other port should also connect to this one
|
||||
if (otherPort.ConnectedPort != this)
|
||||
{
|
||||
otherPort.Connect(this);
|
||||
}
|
||||
Console.WriteLine($"Port {ID} connected to {otherPort.ID}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Breaks the connection of this port.
|
||||
/// </summary>
|
||||
public virtual void Disconnect()
|
||||
{
|
||||
if (ConnectedPort != null)
|
||||
{
|
||||
Port oldConnectedPort = ConnectedPort;
|
||||
ConnectedPort = null;
|
||||
// Ensure the other port also disconnects from this one
|
||||
if (oldConnectedPort.ConnectedPort == this)
|
||||
{
|
||||
oldConnectedPort.Disconnect();
|
||||
}
|
||||
Console.WriteLine($"Port {ID} disconnected from {oldConnectedPort.ID}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
BWR.core/Components/Concrete/FluidTank.cs
Normal file
67
BWR.core/Components/Concrete/FluidTank.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
// MyBWRSimulator.Core/Components/Concrete/FluidTank.cs
|
||||
namespace MyBWRSimulator.Core.Components.Concrete
|
||||
{
|
||||
using MyBWRSimulator.Core.Components.Abstract;
|
||||
//using MyBWRSimulator.Core.Components.Enums;
|
||||
using MyBWRSimulator.Core.Ports;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Fluid Tank component in the BWR simulation.
|
||||
/// </summary>
|
||||
public class FluidTank : Component
|
||||
{
|
||||
public double MaxVolume { get; private set; } // Maximum capacity of the tank (m^3)
|
||||
public double CurrentVolume { get; private set; } // Current fluid volume in the tank (m^3)
|
||||
public double CurrentLevel => CurrentVolume / MaxVolume; // 0.0 to 1.0 (0% to 100%)
|
||||
public double ContentsTemperature { get; private set; } // Average temperature of fluid in tank
|
||||
|
||||
public FluidPort Inlet => GetFluidPortById("Inlet");
|
||||
public FluidPort Outlet => GetFluidPortById("Outlet");
|
||||
|
||||
public FluidTank(string id, string name, double maxVolume, int numInlets, int numOutlets, double initialVolume = 0.0, double initialTemp = 293.15)
|
||||
: base(id, name, $"A fluid tank with max volume {maxVolume} m^3.", 5) // Priority 5 (updates last)
|
||||
{
|
||||
MaxVolume = maxVolume;
|
||||
CurrentVolume = Math.Clamp(initialVolume, 0.0, MaxVolume);
|
||||
ContentsTemperature = initialTemp;
|
||||
|
||||
|
||||
AddFluidPort(new FluidPort("Inlet"));
|
||||
AddFluidPort(new FluidPort("Outlet"));
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
double FlowVolume = 0.0;
|
||||
double InletEnergy = 0.0; // For temperature calculation
|
||||
|
||||
FlowVolume += Inlet.FlowRate * deltaTime; // FlowRate is volume/time, so FlowRate * deltaTime = volume
|
||||
InletEnergy += Inlet.FlowRate * Inlet.Temperature * deltaTime; // Simple energy balance
|
||||
|
||||
// Sum outgoing flow (assuming outlets draw based on their connected components)
|
||||
// For a tank, outlets typically "demand" flow, and the tank supplies it if available.
|
||||
// For simplicity here, we'll assume outlets simply remove fluid.
|
||||
// In a real system, outlet flow depends on downstream pressure and tank level.
|
||||
FlowVolume -= Outlet.FlowRate * deltaTime;
|
||||
|
||||
|
||||
// Update volume
|
||||
double newVolume = CurrentVolume + FlowVolume;
|
||||
CurrentVolume = Math.Clamp(newVolume, 0.0, MaxVolume);
|
||||
|
||||
// Update outlet port properties (e.g., pressure based on level)
|
||||
// This is a simplification; in reality, outlet pressure also depends on downstream pressure
|
||||
double pressureFromLevel = CurrentLevel * 100000; // Example: 100kPa at full level
|
||||
|
||||
Outlet.Pressure = pressureFromLevel; // Or a more complex calculation
|
||||
Outlet.Temperature = ContentsTemperature;
|
||||
// Mirror values to connected ports
|
||||
Outlet.MirrorToConnectedPort();
|
||||
|
||||
|
||||
Console.WriteLine($"{Name} ({ID}) - Volume: {CurrentVolume:F2} m^3 ({CurrentLevel * 100:F1}%), Temp: {ContentsTemperature:F1} K");
|
||||
}
|
||||
}
|
||||
}
|
||||
0
BWR.core/Components/Concrete/PressureVessel.cs
Normal file
0
BWR.core/Components/Concrete/PressureVessel.cs
Normal file
74
BWR.core/Components/Concrete/Pump.cs
Normal file
74
BWR.core/Components/Concrete/Pump.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
// MyBWRSimulator.Core/Components/Concrete/Pump.cs
|
||||
namespace MyBWRSimulator.Core.Components.Concrete
|
||||
{
|
||||
using MyBWRSimulator.Core.Components.Abstract;
|
||||
using MyBWRSimulator.Core.Ports;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Pump component in the BWR simulation.
|
||||
/// </summary>
|
||||
public class Pump : Component
|
||||
{
|
||||
public double PumpSpeed { get; set; } // 0.0 to 1.0 (0% to 100%)
|
||||
public double MaxFlowRate { get; private set; } // Max flow at 100% speed
|
||||
public double MaxHeadPressure { get; private set; } // Max pressure at 100% speed
|
||||
|
||||
// Publicly expose ports for easier named access if needed, but GetFluidPortById is preferred
|
||||
public FluidPort Inlet => GetFluidPortById("Inlet");
|
||||
public FluidPort Outlet => GetFluidPortById("Outlet");
|
||||
|
||||
|
||||
public Pump(string id, string name, double maxFlowRate, double maxHeadPressure)
|
||||
: base(id, name, $"A pump component with max flow {maxFlowRate} and max head {maxHeadPressure}.", 1) // Priority 1
|
||||
{
|
||||
MaxFlowRate = maxFlowRate;
|
||||
MaxHeadPressure = maxHeadPressure;
|
||||
PumpSpeed = 0.0; // Initially off
|
||||
|
||||
// Use descriptive IDs for ports
|
||||
AddFluidPort(new FluidPort("Inlet"));
|
||||
AddFluidPort(new FluidPort("Outlet"));
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (PumpSpeed > 0)
|
||||
{
|
||||
// Simple pump model: Flow proportional to speed, pressure based on head
|
||||
double actualFlowRate = PumpSpeed * MaxFlowRate;
|
||||
double actualPressureIncrease = PumpSpeed * MaxHeadPressure;
|
||||
|
||||
// Read from inlet
|
||||
double inletPressure = Inlet.Pressure;
|
||||
double inletTemperature = Inlet.Temperature;
|
||||
|
||||
// Calculate outlet properties
|
||||
Outlet.FlowRate = actualFlowRate;
|
||||
Outlet.Pressure = inletPressure + actualPressureIncrease;
|
||||
Outlet.Temperature = inletTemperature; // Assuming no temperature change by pump
|
||||
|
||||
// Mirror values to connected ports
|
||||
Outlet.MirrorToConnectedPort();
|
||||
|
||||
Console.WriteLine($"{Name} ({ID}) - Flow: {actualFlowRate:F2} kg/s, Outlet P: {Outlet.Pressure:F2} Pa");
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not powered or off, no flow
|
||||
Outlet.FlowRate = 0.0;
|
||||
Outlet.Pressure = Inlet.Pressure; // Outlet pressure equals inlet if no pumping
|
||||
Outlet.Temperature = Inlet.Temperature;
|
||||
Outlet.MirrorToConnectedPort();
|
||||
Console.WriteLine($"{Name} ({ID}) - Off/No Power.");
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPumpSpeed(double speed)
|
||||
{
|
||||
PumpSpeed = Math.Clamp(speed, 0.0, 1.0);
|
||||
Console.WriteLine($"{Name} ({ID}) - Pump speed set to {PumpSpeed * 100:F0}%.");
|
||||
}
|
||||
}
|
||||
}
|
||||
25
BWR.core/Components/Concrete/ReactorCore.cs
Normal file
25
BWR.core/Components/Concrete/ReactorCore.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
// MyBWRSimulator.Core/Components/Concrete/Pump.cs
|
||||
namespace MyBWRSimulator.Core.Components.Concrete
|
||||
{
|
||||
using MyBWRSimulator.Core.Components.Abstract;
|
||||
//using MyBWRSimulator.Core.Components.Enums;
|
||||
using MyBWRSimulator.Core.Ports;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Pump component in the BWR simulation.
|
||||
/// </summary>
|
||||
public class ReactorCore : Component
|
||||
{
|
||||
public ReactorCore(string id, string name, int priority)
|
||||
: base(id, name, "Simulates all fuel rods and control rods", priority)
|
||||
{
|
||||
AddFluidPort(new FluidPort("FeedwaterInlet"));
|
||||
}
|
||||
public override void Update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
63
BWR.core/Components/Concrete/pipe.cs
Normal file
63
BWR.core/Components/Concrete/pipe.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
// MyBWRSimulator.Core/Components/Concrete/Pipe.cs
|
||||
namespace MyBWRSimulator.Core.Components.Concrete
|
||||
{
|
||||
using MyBWRSimulator.Core.Components.Abstract;
|
||||
using MyBWRSimulator.Core.Ports;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Pipe component in the BWR simulation.
|
||||
/// </summary>
|
||||
public class Pipe : Component
|
||||
{
|
||||
public double Length { get; private set; } // Length of the pipe (m)
|
||||
public double Diameter { get; private set; } // Inner diameter of the pipe (m)
|
||||
public double Roughness { get; private set; } = 0.000045; // Example roughness for steel (m)
|
||||
|
||||
// Publicly expose ports for easier named access if needed
|
||||
public FluidPort Inlet => GetFluidPortById("Inlet");
|
||||
public FluidPort Outlet => GetFluidPortById("Outlet");
|
||||
|
||||
public Pipe(string id, string name, double length, double diameter)
|
||||
: base(id, name, $"A pipe of length {length}m and diameter {diameter}m.", 4) // Priority 4
|
||||
{
|
||||
Length = length;
|
||||
Diameter = diameter;
|
||||
|
||||
// Use descriptive IDs for ports
|
||||
AddFluidPort(new FluidPort("Inlet"));
|
||||
AddFluidPort(new FluidPort("Outlet"));
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// Read properties from the inlet port (which should have been updated by upstream component)
|
||||
double inletFlowRate = Inlet.FlowRate;
|
||||
double inletPressure = Inlet.Pressure;
|
||||
double inletTemperature = Inlet.Temperature;
|
||||
|
||||
// Simple pressure drop calculation (e.g., Darcy-Weisbach or simpler linear drop)
|
||||
// This is very simplified. For high fidelity, you'd need fluid properties (density, viscosity).
|
||||
double pressureDrop = 0.0;
|
||||
if (inletFlowRate > 0)
|
||||
{
|
||||
// A very basic linear pressure drop for demonstration
|
||||
pressureDrop = (inletFlowRate * Length * 10.0) / (Diameter * Diameter);
|
||||
}
|
||||
|
||||
// Simple heat loss/gain (e.g., based on ambient temperature, not modeled here)
|
||||
double outletTemperature = inletTemperature; // Assuming no heat loss for now
|
||||
|
||||
// Update outlet port properties
|
||||
Outlet.FlowRate = inletFlowRate;
|
||||
Outlet.Pressure = inletPressure - pressureDrop;
|
||||
Outlet.Temperature = outletTemperature;
|
||||
|
||||
// Mirror values to connected ports
|
||||
Outlet.MirrorToConnectedPort();
|
||||
|
||||
Console.WriteLine($"{Name} ({ID}) - Flow: {inletFlowRate:F2} kg/s, Pressure Drop: {pressureDrop:F2} Pa");
|
||||
}
|
||||
}
|
||||
}
|
||||
14
BWR.core/Components/Enums/FluidPortType.cs
Normal file
14
BWR.core/Components/Enums/FluidPortType.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// MyBWRSimulator.Core/Components/Enums/FluidPortType.cs
|
||||
/*
|
||||
namespace MyBWRSimulator.Core.Components.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the type of a fluid port (e.g., inlet or outlet).
|
||||
/// </summary>
|
||||
public enum FluidPortType
|
||||
{
|
||||
Inlet,
|
||||
Outlet
|
||||
}
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user