84 lines
2.6 KiB
C#
84 lines
2.6 KiB
C#
using System;
|
||
using FluidSim.Interfaces;
|
||
using FluidSim.Utils;
|
||
|
||
namespace FluidSim.Components
|
||
{
|
||
public class Volume0D
|
||
{
|
||
public Port Port { get; private set; }
|
||
|
||
public double Mass { get; private set; }
|
||
public double InternalEnergy { get; private set; }
|
||
|
||
public double Gamma { get; set; } = 1.4;
|
||
public double GasConstant { get; set; } = 287.0;
|
||
|
||
public double Volume { get; set; }
|
||
public double dVdt { get; set; }
|
||
|
||
private double _dt;
|
||
|
||
public double Density => Mass / Volume;
|
||
public double Pressure => (Gamma - 1.0) * InternalEnergy / Volume;
|
||
public double Temperature => Pressure / (Density * GasConstant);
|
||
public double SpecificEnthalpy => Gamma / (Gamma - 1.0) * Pressure / Density;
|
||
|
||
public Volume0D(double initialVolume, double initialPressure,
|
||
double initialTemperature, int sampleRate,
|
||
double gasConstant = 287.0, double gamma = 1.4)
|
||
{
|
||
GasConstant = gasConstant;
|
||
Gamma = gamma;
|
||
Volume = initialVolume;
|
||
dVdt = 0.0;
|
||
_dt = 1.0 / sampleRate;
|
||
|
||
double rho0 = initialPressure / (GasConstant * initialTemperature);
|
||
Mass = rho0 * Volume;
|
||
InternalEnergy = (initialPressure * Volume) / (Gamma - 1.0);
|
||
|
||
Port = new Port();
|
||
PushStateToPort();
|
||
}
|
||
|
||
public void PushStateToPort()
|
||
{
|
||
Port.Pressure = Pressure;
|
||
Port.Density = Density;
|
||
Port.Temperature = Temperature;
|
||
Port.SpecificEnthalpy = SpecificEnthalpy;
|
||
}
|
||
|
||
// Original integrate (uses the constructor’s sample rate)
|
||
public void Integrate()
|
||
{
|
||
Integrate(_dt);
|
||
}
|
||
|
||
public void SetPressure(double newPressure)
|
||
{
|
||
InternalEnergy = newPressure * Volume / (Gamma - 1.0);
|
||
// Mass stays the same, so density is unchanged
|
||
}
|
||
|
||
// New overload: integrate with a custom time step (for sub‑steps)
|
||
public void Integrate(double dtOverride)
|
||
{
|
||
double mdot = Port.MassFlowRate;
|
||
double h_in = Port.SpecificEnthalpy;
|
||
|
||
double dm = mdot * dtOverride;
|
||
double dE = (mdot * h_in) * dtOverride - Pressure * dVdt * dtOverride;
|
||
|
||
Mass += dm;
|
||
InternalEnergy += dE;
|
||
|
||
// Hard physical bounds – prevent NaN and unphysical states
|
||
if (Mass < 1e-12) Mass = 1e-12;
|
||
if (InternalEnergy < 1e-12) InternalEnergy = 1e-12;
|
||
|
||
PushStateToPort();
|
||
}
|
||
}
|
||
} |