refactoring (broken right now)
This commit is contained in:
123
Core/OpenEndLink.cs
Normal file
123
Core/OpenEndLink.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using FluidSim.Components;
|
||||
|
||||
namespace FluidSim.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Characteristic open‑end boundary condition.
|
||||
/// For subsonic outflow the outgoing Riemann invariant is conserved,
|
||||
/// and the ghost pressure is set to the prescribed ambient value.
|
||||
/// </summary>
|
||||
public class OpenEndLink
|
||||
{
|
||||
public Pipe1D Pipe { get; }
|
||||
public bool IsLeftEnd { get; }
|
||||
public double AmbientPressure { get; set; } = 101325.0;
|
||||
public double Gamma { get; set; } = 1.4;
|
||||
|
||||
// Last resolved state (for audio / monitoring)
|
||||
public double LastMassFlowRate { get; private set; }
|
||||
public double LastFaceDensity { get; private set; }
|
||||
public double LastFaceVelocity { get; private set; }
|
||||
public double LastFacePressure { get; private set; }
|
||||
|
||||
public OpenEndLink(Pipe1D pipe, bool isLeftEnd)
|
||||
{
|
||||
Pipe = pipe ?? throw new ArgumentNullException(nameof(pipe));
|
||||
IsLeftEnd = isLeftEnd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute the ghost state and mass flow for one sub‑step.
|
||||
/// </summary>
|
||||
public void Resolve(double dtSub)
|
||||
{
|
||||
(double rhoInt, double uInt, double pInt) = IsLeftEnd
|
||||
? Pipe.GetInteriorStateLeft()
|
||||
: Pipe.GetInteriorStateRight();
|
||||
|
||||
double gamma = Gamma;
|
||||
double gm1 = gamma - 1.0;
|
||||
double cInt = Math.Sqrt(gamma * pInt / Math.Max(rhoInt, 1e-12));
|
||||
double pAmb = AmbientPressure;
|
||||
|
||||
double rhoGhost, uGhost, pGhost;
|
||||
double mdot;
|
||||
|
||||
if (IsLeftEnd)
|
||||
{
|
||||
// Left end: outgoing invariant is J- = u - 2c/(γ-1)
|
||||
double J_minus = uInt - 2.0 * cInt / gm1;
|
||||
|
||||
if (uInt <= -cInt) // supersonic inflow (all info from outside)
|
||||
{
|
||||
// Simple reservoir model – use ambient density and temperature 300 K
|
||||
rhoGhost = pAmb / (287.0 * 300.0);
|
||||
uGhost = uInt; // keep interior velocity (should be supersonic inward)
|
||||
pGhost = pAmb;
|
||||
}
|
||||
else if (uInt < 0) // subsonic inflow
|
||||
{
|
||||
double rhoAmb = pAmb / (287.0 * 300.0);
|
||||
double cAmb = Math.Sqrt(gamma * pAmb / rhoAmb);
|
||||
uGhost = J_minus + 2.0 * cAmb / gm1;
|
||||
rhoGhost = rhoAmb;
|
||||
pGhost = pAmb;
|
||||
}
|
||||
else // subsonic outflow (uInt >= 0)
|
||||
{
|
||||
double s = pInt / Math.Pow(rhoInt, gamma);
|
||||
rhoGhost = Math.Pow(pAmb / s, 1.0 / gamma);
|
||||
double cGhost = Math.Sqrt(gamma * pAmb / rhoGhost);
|
||||
uGhost = J_minus + 2.0 * cGhost / gm1;
|
||||
if (uGhost < 0) uGhost = 0;
|
||||
pGhost = pAmb;
|
||||
}
|
||||
}
|
||||
else // Right end
|
||||
{
|
||||
// Right end: outgoing invariant is J+ = u + 2c/(γ-1)
|
||||
double J_plus = uInt + 2.0 * cInt / gm1;
|
||||
|
||||
if (uInt >= cInt) // supersonic outflow
|
||||
{
|
||||
rhoGhost = rhoInt;
|
||||
uGhost = uInt;
|
||||
pGhost = pInt;
|
||||
}
|
||||
else if (uInt >= 0) // subsonic outflow
|
||||
{
|
||||
double s = pInt / Math.Pow(rhoInt, gamma);
|
||||
rhoGhost = Math.Pow(pAmb / s, 1.0 / gamma);
|
||||
double cGhost = Math.Sqrt(gamma * pAmb / rhoGhost);
|
||||
uGhost = J_plus - 2.0 * cGhost / gm1;
|
||||
if (uGhost < 0) uGhost = 0;
|
||||
pGhost = pAmb;
|
||||
}
|
||||
else // subsonic inflow (uInt < 0)
|
||||
{
|
||||
double rhoAmb = pAmb / (287.0 * 300.0);
|
||||
double cAmb = Math.Sqrt(gamma * pAmb / rhoAmb);
|
||||
uGhost = J_plus - 2.0 * cAmb / gm1;
|
||||
rhoGhost = rhoAmb;
|
||||
pGhost = pAmb;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply ghost to pipe
|
||||
if (IsLeftEnd)
|
||||
Pipe.SetGhostLeft(rhoGhost, uGhost, pGhost);
|
||||
else
|
||||
Pipe.SetGhostRight(rhoGhost, uGhost, pGhost);
|
||||
|
||||
// Mass flow (positive = out of pipe)
|
||||
double area = Pipe.Area;
|
||||
mdot = rhoGhost * uGhost * area;
|
||||
if (IsLeftEnd) mdot = -mdot; // positive u into pipe, so out of pipe is negative u
|
||||
LastMassFlowRate = mdot;
|
||||
LastFaceDensity = rhoGhost;
|
||||
LastFaceVelocity = uGhost;
|
||||
LastFacePressure = pGhost;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user