Merge branch 'Testing' of https://gitea.grillkol.net/grillkol/FluidSim into Testing

This commit is contained in:
max
2026-06-09 17:50:16 +02:00
4 changed files with 177 additions and 145 deletions

View File

@@ -25,7 +25,8 @@ namespace FluidSim.Core
public float EffectiveLength;
public float CurrentMdot; // kg/s, positive = volume → pipe
// --- Loss coefficient (linear resistance) ---
// --- Loss coefficient (linear resistance) inertance only ---
// If 0 when UseInertance is true, a stable default is autocomputed at runtime.
public float LossCoefficient; // N·s/m⁵ or kg/(m⁴·s)
}
@@ -57,9 +58,10 @@ namespace FluidSim.Core
public int OpenEndCount { get; private set; }
// ---------- Add orifice (no inertance) ----------
// Simple isentropic nozzle no builtin loss. For dissipation use pipe damping
// or the inertance model if you need a damped resonator.
public void AddOrifice(Port volumePort, int pipeIndex, bool isLeftEnd,
int areaIndex, float dischargeCoeff = 1f,
float lossCoefficient = 0f)
int areaIndex, float dischargeCoeff = 1f)
{
_orifices[OrificeCount] = new OrificeDesc
{
@@ -71,22 +73,24 @@ namespace FluidSim.Core
UseInertance = false,
EffectiveLength = 0f,
CurrentMdot = 0f,
LossCoefficient = lossCoefficient
LossCoefficient = 0f
};
OrificeCount++;
}
// ---------- Add orifice with inertance ----------
// effectiveLength length of the inertial slug (m), typically the physical neck length.
// lossCoefficient linear resistance (N·s/m⁵). If 0 (or omitted) an automatic stable
// value will be computed from the pipe's characteristic impedance.
public void AddOrificeWithInertance(Port volumePort, int pipeIndex, bool isLeftEnd,
int areaIndex, float dischargeCoeff,
float effectiveLength, float lossCoefficient = 0f)
{
// Reuse the base AddOrifice and then override fields
AddOrifice(volumePort, pipeIndex, isLeftEnd, areaIndex, dischargeCoeff, lossCoefficient);
AddOrifice(volumePort, pipeIndex, isLeftEnd, areaIndex, dischargeCoeff);
ref var d = ref _orifices[OrificeCount - 1];
d.UseInertance = true;
d.EffectiveLength = effectiveLength;
d.LossCoefficient = lossCoefficient; // store the linear resistance
d.LossCoefficient = lossCoefficient;
}
public void AddOpenEnd(int pipeIndex, bool isLeftEnd,
@@ -146,7 +150,7 @@ namespace FluidSim.Core
? _pipeSystem.GetInteriorAirFractionLeft(d.PipeIndex)
: _pipeSystem.GetInteriorAirFractionRight(d.PipeIndex);
// ---- Handle closed orifice (area ≈ 0) as a wall ----
// ---- Handle closed orifice as a wall ----
if (area < 1e-12f || d.VolumePort == null)
{
var (rInt, uInt, pInt) = d.IsLeftEnd
@@ -184,10 +188,10 @@ namespace FluidSim.Core
if (d.UseInertance)
{
// ---- Inertance ODE with (possibly automatic) linear loss ----
float rhoUp = d.CurrentMdot >= 0 ? volRho : pipeRho;
float inertance = rhoUp * d.EffectiveLength / MathF.Max(area, 1e-12f);
float dp = volP - pipeP;
float Rlin = d.LossCoefficient;
float dmdot_dt = (dp - Rlin * d.CurrentMdot) / MathF.Max(inertance, 1e-12f);
float mdotNew = d.CurrentMdot + dmdot_dt * dt;