fixed under damping inertance
This commit is contained in:
@@ -184,45 +184,51 @@ namespace FluidSim.Core
|
||||
|
||||
if (d.UseInertance)
|
||||
{
|
||||
// ---- Inertance ODE with 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; // linear resistance
|
||||
float Rlin = d.LossCoefficient;
|
||||
|
||||
// Forward Euler
|
||||
float dmdot_dt = (dp - Rlin * d.CurrentMdot) / MathF.Max(inertance, 1e-12f);
|
||||
float mdotNew = d.CurrentMdot + dmdot_dt * dt;
|
||||
|
||||
// ---------- Symmetric flow limiter ----------
|
||||
// 1) limit by cavity mass
|
||||
// ---------- Symmetric flow limiters (existing) ----------
|
||||
if (d.VolumePort.Owner is Volume0D vol0)
|
||||
{
|
||||
float maxOut = vol0.Mass / dt;
|
||||
if (mdotNew > maxOut) mdotNew = maxOut; // cavity → pipe
|
||||
if (mdotNew < -maxOut) mdotNew = -maxOut; // pipe → cavity
|
||||
if (mdotNew > maxOut) mdotNew = maxOut;
|
||||
if (mdotNew < -maxOut) mdotNew = -maxOut;
|
||||
}
|
||||
|
||||
// 2) limit by mass in the adjacent pipe cell
|
||||
int adjCell = d.IsLeftEnd ? _pipeSystem.GetPipeStart(d.PipeIndex)
|
||||
: _pipeSystem.GetPipeEnd(d.PipeIndex) - 1;
|
||||
float pipeRhoAdj = _pipeSystem.GetCellDensity(adjCell);
|
||||
float pipeDxAdj = _pipeSystem.GetCellDx(adjCell); // uses the new public method
|
||||
float pipeDxAdj = _pipeSystem.GetCellDx(adjCell);
|
||||
float pipeCellMass = pipeRhoAdj * area * pipeDxAdj;
|
||||
float maxFromPipe = pipeCellMass / dt;
|
||||
if (mdotNew < -maxFromPipe) mdotNew = -maxFromPipe; // prevent emptying the pipe cell
|
||||
if (mdotNew < -maxFromPipe) mdotNew = -maxFromPipe;
|
||||
|
||||
// ---------- Velocity clamp to Mach 0.9 ----------
|
||||
float rhoFacePrelim = mdotNew >= 0 ? volRho : pipeRho;
|
||||
float uFacePrelim = MathF.Abs(mdotNew) / MathF.Max(rhoFacePrelim * area, 1e-12f);
|
||||
float cUp = mdotNew >= 0 ? MathF.Sqrt(Gamma * Rgas * volT) : MathF.Sqrt(Gamma * Rgas * pipeT);
|
||||
float maxU = 0.9f * cUp;
|
||||
if (uFacePrelim > maxU)
|
||||
{
|
||||
uFacePrelim = maxU;
|
||||
mdotNew = rhoFacePrelim * uFacePrelim * area * (mdotNew >= 0 ? 1f : -1f);
|
||||
}
|
||||
|
||||
// NaN safety
|
||||
if (float.IsNaN(mdotNew)) mdotNew = 0f;
|
||||
|
||||
// Store for next step
|
||||
d.CurrentMdot = mdotNew;
|
||||
mdotFinal = mdotNew;
|
||||
|
||||
// Ghost state: use the isentropic face pressure (pFaceEst) as reference,
|
||||
// but compute velocity from mdotFinal.
|
||||
// Ghost state
|
||||
rhoFace = mdotFinal >= 0 ? volRho : pipeRho;
|
||||
pFace = pFaceEst; // approximate face pressure
|
||||
pFace = pFaceEst;
|
||||
uFace = MathF.Abs(mdotFinal) / MathF.Max(rhoFace * area, 1e-12f);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace FluidSim.Tests
|
||||
|
||||
float rho0 = 101325f / (287f * 300f);
|
||||
pipeSystem = new PipeSystem(neckCells, pipeStart, pipeEnd, areas, dxs, rho0, 0f, 101325f);
|
||||
pipeSystem.DampingMultiplier = 500f;
|
||||
|
||||
// --- Boundary system ---
|
||||
boundaries = new BoundarySystem(pipeSystem, maxOrifices: 1, maxOpenEnds: 1);
|
||||
@@ -72,7 +73,7 @@ namespace FluidSim.Tests
|
||||
areaIndex: cavityOrificeIdx,
|
||||
dischargeCoeff: 0.9f,
|
||||
effectiveLength: neckLength, // physical length (or L_eff)
|
||||
lossCoefficient: 9000 // start with this, adjust for decay time
|
||||
lossCoefficient: 7000 // start with this, adjust for decay time
|
||||
);
|
||||
|
||||
// Open end at right side of pipe
|
||||
|
||||
Reference in New Issue
Block a user