Engine working

This commit is contained in:
max
2026-05-07 21:48:37 +02:00
parent 92d84eacfe
commit b3230844b7
14 changed files with 441 additions and 486 deletions

View File

@@ -9,6 +9,7 @@ namespace FluidSim.Core
/// from the isentropic expansion to ambient pressure, using the pipe's entropy,
/// and the outgoing Riemann invariant. This avoids a density jump at flow reversal.
/// Supersonic outflow extrapolates the interior state.
/// Now includes air fraction tracking: incoming air is fresh (AF=1), outgoing uses interior pipe AF.
/// </summary>
public class OpenEndLink
{
@@ -34,34 +35,34 @@ namespace FluidSim.Core
? Pipe.GetInteriorStateLeft()
: Pipe.GetInteriorStateRight();
double airFracInt = IsLeftEnd
? Pipe.GetInteriorAirFractionLeft()
: Pipe.GetInteriorAirFractionRight();
double gamma = Gamma;
double gm1 = gamma - 1.0;
double cInt = Math.Sqrt(gamma * pInt / Math.Max(rhoInt, 1e-12));
double pAmb = AmbientPressure;
// Riemann invariants
double J_plus = uInt + 2.0 * cInt / gm1;
double J_plus = uInt + 2.0 * cInt / gm1;
double J_minus = uInt - 2.0 * cInt / gm1;
double rhoGhost, uGhost, pGhost;
double rhoGhost, uGhost, pGhost, airFracGhost;
// ---- Subsonic branch (used for both outflow and inflow) ----
// Isentropic expansion to ambient pressure using pipe's entropy
double s = pInt / Math.Pow(rhoInt, gamma); // entropy constant
double rhoIso = Math.Pow(pAmb / s, 1.0 / gamma);
double cIso = Math.Sqrt(gamma * pAmb / Math.Max(rhoIso, 1e-12));
double uIso = IsLeftEnd
? (J_minus + 2.0 * cIso / gm1)
: (J_plus - 2.0 * cIso / gm1);
: (J_plus - 2.0 * cIso / gm1);
// Check for supersonic outflow: if the isentropic velocity exceeds the speed of sound,
// the flow is supersonic and we extrapolate the interior state.
// Check for supersonic outflow
bool supersonic = IsLeftEnd
? (uInt <= -cInt) // left end: outflow is when u < -c
: (uInt >= cInt); // right end: outflow is when u > c
? (uInt <= -cInt)
: (uInt >= cInt);
// Extra check: if the isentropic velocity is supersonic in the outflow direction,
// also treat as supersonic (this can happen when the interior pressure is very high).
if (!supersonic)
{
if (IsLeftEnd)
@@ -74,27 +75,42 @@ namespace FluidSim.Core
{
// Supersonic outflow extrapolate interior
rhoGhost = rhoInt;
uGhost = uInt;
pGhost = pInt;
uGhost = uInt;
pGhost = pInt;
airFracGhost = airFracInt; // whatever is leaving
}
else
{
// Subsonic flow use the isentropic state
// Subsonic flow use isentropic state to ambient
rhoGhost = rhoIso;
uGhost = uIso;
pGhost = pAmb;
uGhost = uIso;
pGhost = pAmb;
// Determine if inflow or outflow
bool isInflow = IsLeftEnd ? (uIso >= 0) : (uIso <= 0); // positive u means into pipe from left end? Wait: left end: u>0 means flow to the right, into pipe. Right end: u>0 means flow to the right, out of pipe. Let's use mass flow sign later.
// More straightforward: if using the isentropic state, the ghost velocity direction indicates flow. For inflow (ambient to pipe), airFraction = 1.0; for outflow, airFraction = interior's AF.
if ((IsLeftEnd && uIso >= 0) || (!IsLeftEnd && uIso <= 0))
{
// Inflow (ambient enters pipe)
airFracGhost = 1.0;
}
else
{
// Outflow (pipe exits to ambient)
airFracGhost = airFracInt;
}
}
// Apply ghost to pipe
if (IsLeftEnd)
Pipe.SetGhostLeft(rhoGhost, uGhost, pGhost);
Pipe.SetGhostLeft(rhoGhost, uGhost, pGhost, airFracGhost);
else
Pipe.SetGhostRight(rhoGhost, uGhost, pGhost);
Pipe.SetGhostRight(rhoGhost, uGhost, pGhost, airFracGhost);
// Mass flow out of the pipe (positive = leaving)
double area = Pipe.Area;
double mdot = rhoGhost * uGhost * area;
if (IsLeftEnd) mdot = -mdot; // left end: positive u is into pipe, so out is -u
if (IsLeftEnd) mdot = -mdot; // left end: positive u is into pipe, outward flow is -u
LastMassFlowRate = mdot;
LastFaceDensity = rhoGhost;
LastFaceVelocity = uGhost;