Files
FluidSim/Core/Solver.cs
2026-05-02 18:05:14 +02:00

79 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using FluidSim.Components;
using FluidSim.Interfaces;
namespace FluidSim.Core
{
public class Solver
{
private readonly List<Volume0D> _volumes = new();
private readonly List<Pipe1D> _pipes = new();
private readonly List<Connection> _connections = new();
public void AddVolume(Volume0D v) => _volumes.Add(v);
public void AddPipe(Pipe1D p) => _pipes.Add(p);
public void AddConnection(Connection c) => _connections.Add(c);
public void Step()
{
// 1. Volumes publish state to their ports
foreach (var v in _volumes)
v.PushStateToPort();
// 2. Set volume states as boundary conditions on pipes
foreach (var conn in _connections)
{
if (IsPipePort(conn.PortA) && IsVolumePort(conn.PortB))
SetVolumeBC(conn.PortA, conn.PortB);
else if (IsVolumePort(conn.PortA) && IsPipePort(conn.PortB))
SetVolumeBC(conn.PortB, conn.PortA);
}
// 3. Run pipe simulations
foreach (var p in _pipes)
p.Simulate();
// 4. Transfer pipeport flows to volume ports
foreach (var conn in _connections)
{
if (IsPipePort(conn.PortA) && IsVolumePort(conn.PortB))
TransferPipeToVolume(conn.PortA, conn.PortB);
else if (IsVolumePort(conn.PortA) && IsPipePort(conn.PortB))
TransferPipeToVolume(conn.PortB, conn.PortA);
}
// 5. Integrate volumes
foreach (var v in _volumes)
v.Integrate();
}
bool IsVolumePort(Port p) => _volumes.Exists(v => v.Port == p);
bool IsPipePort(Port p) => _pipes.Exists(pp => pp.PortA == p || pp.PortB == p);
Pipe1D GetPipe(Port p) => _pipes.Find(pp => pp.PortA == p || pp.PortB == p);
void SetVolumeBC(Port pipePort, Port volPort)
{
Pipe1D pipe = GetPipe(pipePort);
if (pipe == null) return;
bool isLeft = pipe.PortA == pipePort;
if (isLeft)
pipe.SetLeftVolumeState(volPort.Density, volPort.Pressure);
else
pipe.SetRightVolumeState(volPort.Density, volPort.Pressure);
}
void TransferPipeToVolume(Port pipePort, Port volPort)
{
double mdot = pipePort.MassFlowRate;
volPort.MassFlowRate = -mdot;
if (mdot < 0) // pipe → volume
{
// pipePort.SpecificEnthalpy is already total (h + ½u²)
volPort.SpecificEnthalpy = pipePort.SpecificEnthalpy;
}
// else: volume → pipe, volumes own static enthalpy is used (already set)
}
}
}