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

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using FluidSim.Interfaces;
@@ -8,8 +8,9 @@ namespace FluidSim.Components
{
public List<Port> Ports { get; } = new List<Port>();
public double Mass { get; set; } // made public setter
public double InternalEnergy { get; set; } // made public setter
private double _airMass;
private double _exhaustMass;
public double InternalEnergy { get; set; }
public double Volume { get; set; }
public double Dvdt { get; set; }
public double Gamma { get; set; } = 1.4;
@@ -18,6 +19,8 @@ namespace FluidSim.Components
public double AmbientPressure { get; set; } = 101325.0;
// Derived quantities
public double Mass => _airMass + _exhaustMass;
public double AirFraction => _airMass / Math.Max(Mass, 1e-12);
public double Density => Mass / Math.Max(Volume, 1e-12);
public double Pressure => (Gamma - 1.0) * InternalEnergy / Math.Max(Volume, 1e-12);
public double Temperature => Pressure / Math.Max(Density * GasConstant, 1e-12);
@@ -32,7 +35,8 @@ namespace FluidSim.Components
Dvdt = 0.0;
double rho0 = initialPressure / (GasConstant * initialTemperature);
Mass = rho0 * Volume;
_airMass = rho0 * Volume; // starts with all air
_exhaustMass = 0.0;
InternalEnergy = (initialPressure * Volume) / (Gamma - 1.0);
}
@@ -43,44 +47,53 @@ namespace FluidSim.Components
port.Density = Density;
port.Temperature = Temperature;
port.SpecificEnthalpy = SpecificEnthalpy;
port.AirFraction = AirFraction;
Ports.Add(port);
return port;
}
/// <summary>
/// Set the pressure to a specific value while keeping the current temperature constant.
/// Updates Mass and InternalEnergy accordingly.
/// </summary>
public void SetPressure(double pressure, double? temperature = null)
{
double V = Math.Max(Volume, 1e-12);
double T = temperature ?? Temperature;
double rho = pressure / (GasConstant * T);
Mass = rho * V;
double totalMass = rho * V;
// Keep current air fraction when setting pressure?
double af = AirFraction;
_airMass = totalMass * af;
_exhaustMass = totalMass * (1.0 - af);
InternalEnergy = pressure * V / (Gamma - 1.0);
}
public void UpdateState(double dt)
{
double totalMdot = 0.0;
double totalMdotAir = 0.0;
double totalMdotExhaust = 0.0;
double totalEdot = 0.0;
foreach (var port in Ports)
{
totalMdot += port.MassFlowRate;
totalEdot += port.MassFlowRate * port.SpecificEnthalpy;
double mdot = port.MassFlowRate; // positive INTO volume
double af = mdot >= 0 ? port.AirFraction : AirFraction; // inflow: use port's fraction; outflow: well-mixed
totalMdotAir += mdot * af;
totalMdotExhaust += mdot * (1.0 - af);
totalEdot += mdot * port.SpecificEnthalpy;
}
double dm = totalMdot * dt;
double dAir = totalMdotAir * dt;
double dExhaust = totalMdotExhaust * dt;
double dE = totalEdot * dt - Pressure * Dvdt * dt;
Mass += dm;
_airMass += dAir;
_exhaustMass += dExhaust;
InternalEnergy += dE;
double V = Math.Max(Volume, 1e-12);
if (Mass < 1e-9)
double totalMass = _airMass + _exhaustMass;
if (totalMass < 1e-9)
{
Mass = 1e-9;
_airMass = 1e-9;
_exhaustMass = 0.0;
InternalEnergy = AmbientPressure * V / (Gamma - 1.0);
}
else if (InternalEnergy < 0.0)
@@ -88,16 +101,17 @@ namespace FluidSim.Components
InternalEnergy = AmbientPressure * V / (Gamma - 1.0);
}
if (Mass < 0.0) Mass = 1e-9;
if (InternalEnergy < 0.0) InternalEnergy = AmbientPressure * V / (Gamma - 1.0);
if (_airMass < 0.0) _airMass = 0.0;
if (_exhaustMass < 0.0) _exhaustMass = 0.0;
double p = Pressure, rho = Density, T = Temperature, h = SpecificEnthalpy;
double p = Pressure, rho = Density, T = Temperature, h = SpecificEnthalpy, afrac = AirFraction;
foreach (var port in Ports)
{
port.Pressure = p;
port.Density = rho;
port.Temperature = T;
port.SpecificEnthalpy = h;
port.AirFraction = afrac;
}
}