added 4 cyl
This commit is contained in:
@@ -46,9 +46,7 @@ namespace FluidSim.Components
|
||||
public double FuelLowerHeatingValue { get; set; } = 44e6;
|
||||
|
||||
// Cycle‑to‑cycle randomness
|
||||
/// <summary>Fractional variation in fuel energy (±). 0.05 = ±5%.</summary>
|
||||
public double EnergyVariationFraction { get; set; } = 0.05;
|
||||
/// <summary>Probability of a misfire (0‑1).</summary>
|
||||
public double MisfireProbability { get; set; } = 0.01;
|
||||
|
||||
// Heat loss
|
||||
@@ -56,7 +54,14 @@ namespace FluidSim.Components
|
||||
public double HeatTransferCoefficient { get; set; } = 100.0;
|
||||
public double AmbientTemperature { get; set; } = 300.0;
|
||||
|
||||
// State
|
||||
// ---- Multi‑cylinder support ----
|
||||
/// <summary>
|
||||
/// Phase offset (radians) added to the crankshaft angle for this cylinder.
|
||||
/// Used for multi‑cylinder engines; set to 0 for single‑cylinder.
|
||||
/// </summary>
|
||||
public double PhaseOffset { get; set; } = 0.0;
|
||||
|
||||
// State (public for drawing)
|
||||
public double Volume => cylinderVolume;
|
||||
public double Pressure => (Gamma - 1.0) * cylinderEnergy / Math.Max(cylinderVolume, 1e-12);
|
||||
public double Temperature => Pressure / Math.Max(Density * GasConstant, 1e-12);
|
||||
@@ -75,8 +80,7 @@ namespace FluidSim.Components
|
||||
private bool combustionActive;
|
||||
private bool fuelInjected;
|
||||
|
||||
// per‑cycle randomness
|
||||
private double _energyFactor = 1.0; // applied to FuelLowerHeatingValue this cycle
|
||||
private double _energyFactor = 1.0;
|
||||
private readonly Random _random = new Random();
|
||||
|
||||
private const double Gamma = 1.4;
|
||||
@@ -115,7 +119,10 @@ namespace FluidSim.Components
|
||||
private double clearanceVolume => SweptVolume / (CompressionRatio - 1.0);
|
||||
private double CrankRadius => Stroke / 2.0;
|
||||
private double Obliquity => CrankRadius / ConRodLength;
|
||||
private double CrankDeg => (Crankshaft.CrankAngle % (4.0 * Math.PI)) * 180.0 / Math.PI % 720.0;
|
||||
|
||||
// Offset-aware crank angle in degrees
|
||||
private double CrankDeg =>
|
||||
((Crankshaft.CrankAngle + PhaseOffset) % (4.0 * Math.PI)) * 180.0 / Math.PI % 720.0;
|
||||
|
||||
public double ComputeVolume(double thetaRad)
|
||||
{
|
||||
@@ -174,7 +181,9 @@ namespace FluidSim.Components
|
||||
public void PreStep(double dt)
|
||||
{
|
||||
double prevVolume = cylinderVolume;
|
||||
double crankAngleRad = Crankshaft.CrankAngle;
|
||||
|
||||
// ----- Use phase‑offset crank angle for this cylinder -----
|
||||
double crankAngleRad = Crankshaft.CrankAngle + PhaseOffset;
|
||||
cylinderVolume = ComputeVolume(crankAngleRad);
|
||||
|
||||
double dV = cylinderVolume - prevVolume;
|
||||
@@ -191,7 +200,9 @@ namespace FluidSim.Components
|
||||
|
||||
cylinderEnergy -= Pressure * dV;
|
||||
|
||||
double prevDeg = Crankshaft.PreviousAngle * 180.0 / Math.PI % 720.0;
|
||||
// Also use offset angle for event detection
|
||||
double crankshaftPrevAngle = Crankshaft.PreviousAngle;
|
||||
double prevDeg = (crankshaftPrevAngle + PhaseOffset) * 180.0 / Math.PI % 720.0;
|
||||
double currDeg = crankAngleRad * 180.0 / Math.PI % 720.0;
|
||||
|
||||
// ----- Intake closing: capture trapped air mass and compute fuel -----
|
||||
@@ -202,7 +213,7 @@ namespace FluidSim.Components
|
||||
fuelInjected = true;
|
||||
}
|
||||
|
||||
// ----- Spark ignition (once per cycle, with misfire chance) -----
|
||||
// ----- Spark ignition -----
|
||||
double sparkAngle = 0.0 - SparkAdvance;
|
||||
if (sparkAngle < 0) sparkAngle += 720.0;
|
||||
|
||||
@@ -210,19 +221,15 @@ namespace FluidSim.Components
|
||||
(prevDeg > sparkAngle + 360.0 && currDeg < sparkAngle);
|
||||
if (crossedSpark && !combustionActive && fuelInjected)
|
||||
{
|
||||
// Decide misfire
|
||||
bool misfire = _random.NextDouble() < MisfireProbability;
|
||||
if (misfire)
|
||||
{
|
||||
combustionActive = false; // no combustion this cycle
|
||||
// fuel is not burned – will remain in cylinder and eventually exit as unburned mixture
|
||||
combustionActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
combustionActive = true;
|
||||
burnFraction = 0.0;
|
||||
|
||||
// Energy variation factor for this cycle
|
||||
double range = EnergyVariationFraction;
|
||||
_energyFactor = 1.0 + range * (2.0 * _random.NextDouble() - 1.0);
|
||||
}
|
||||
@@ -239,7 +246,6 @@ namespace FluidSim.Components
|
||||
{
|
||||
newFraction = 1.0;
|
||||
combustionActive = false;
|
||||
// All gas becomes exhaust
|
||||
double totalMass = _airMass + _exhaustMass;
|
||||
_airMass = 0.0;
|
||||
_exhaustMass = totalMass;
|
||||
@@ -255,7 +261,7 @@ namespace FluidSim.Components
|
||||
}
|
||||
}
|
||||
|
||||
// ----- Heat loss to cylinder walls -----
|
||||
// ----- Heat loss -----
|
||||
double dQ_loss = HeatTransferCoefficient * CylinderWallArea *
|
||||
(Temperature - AmbientTemperature) * dt;
|
||||
cylinderEnergy -= dQ_loss;
|
||||
|
||||
Reference in New Issue
Block a user