using System.Globalization; using System.Linq; using System.Reflection; using FluidSim.Core; using FluidSim.Components; using FluidSim.Tests; static T PrivateField(object target, string name) { var field = target.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new InvalidOperationException($"Could not find scenario field '{name}'."); return (T)(field.GetValue(target) ?? throw new InvalidOperationException($"Field '{name}' is null.")); } const int sampleRate = 44100; const int sampleCount = sampleRate; int[] checkpoints = [.. Enumerable.Range(1, 100), 300, 500, 1000, 4410, 11025, 22050, 33075, 44100]; var scenario = new SingleCylScenario(); var originalOutput = Console.Out; Console.SetOut(TextWriter.Null); scenario.Initialize(sampleRate); scenario.Throttle = 0.35f; scenario.Load = 0.0f; scenario.Clutch = 0.0f; var crankshaft = PrivateField(scenario, "crankshaft"); var cylinder1 = PrivateField(scenario, "cylinder"); var cylinder2 = PrivateField(scenario, "cylinder2"); var intakePlenum = PrivateField(scenario, "intakePlenum"); var exhaustCollector = PrivateField(scenario, "exhaustCollector"); var vehicle = PrivateField(scenario, "vehicle"); var boundaries = PrivateField(scenario, "boundaries"); var pipeSystem = PrivateField(scenario, "pipeSystem"); cylinder1.EnergyVariationFraction = 0.0f; cylinder2.EnergyVariationFraction = 0.0f; Console.SetOut(originalOutput); Console.WriteLine("step,rpm,angle,cylinder1_pa,cylinder2_pa,intake_pa,exhaust_pa,speed_kmh,valve1_in,valve2_in,intake_flow,exhaust_flow,pipe0_left_pa,pipe0_right_pa,pipe1_left_pa,pipe1_right_pa,pipe2_left_pa,pipe2_right_pa,pipe3_left_pa,pipe3_right_pa,pipe4_left_pa,pipe4_right_pa,throttle_port_flow,runner1_port_flow,runner2_port_flow,cyl1_intake_flow,cyl2_intake_flow,cyl1_exhaust_flow,cyl2_exhaust_flow,pipe0_right_rho,pipe0_right_u,pipe1_left_rho,pipe1_left_u,pipe1_right_rho,pipe1_right_u,pipe2_left_rho,pipe2_left_u,pipe2_right_rho,pipe2_right_u,intake_rho,intake_temperature,pipe0_left_rho,pipe0_left_u"); var checkpointIndex = 0; Console.SetOut(TextWriter.Null); for (var step = 1; step <= sampleCount; ++step) { scenario.Process(); if (checkpointIndex < checkpoints.Length && step == checkpoints[checkpointIndex]) { Console.SetOut(originalOutput); Console.WriteLine(string.Join(',', step.ToString(CultureInfo.InvariantCulture), (crankshaft.AngularVelocity * 60f / (2f * MathF.PI)).ToString("R", CultureInfo.InvariantCulture), crankshaft.CrankAngle.ToString("R", CultureInfo.InvariantCulture), cylinder1.Pressure.ToString("R", CultureInfo.InvariantCulture), cylinder2.Pressure.ToString("R", CultureInfo.InvariantCulture), intakePlenum.Pressure.ToString("R", CultureInfo.InvariantCulture), exhaustCollector.Pressure.ToString("R", CultureInfo.InvariantCulture), vehicle.SpeedKmh.ToString("R", CultureInfo.InvariantCulture), cylinder1.IntakeValveArea.ToString("R", CultureInfo.InvariantCulture), cylinder2.IntakeValveArea.ToString("R", CultureInfo.InvariantCulture), boundaries.GetOpenEndMassFlow(0).ToString("R", CultureInfo.InvariantCulture), boundaries.GetOpenEndMassFlow(1).ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(0).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(0).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(1).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(1).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(2).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(2).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(3).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(3).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(4).p.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(4).p.ToString("R", CultureInfo.InvariantCulture), intakePlenum.Ports[0].MassFlowRate.ToString("R", CultureInfo.InvariantCulture), intakePlenum.Ports[2].MassFlowRate.ToString("R", CultureInfo.InvariantCulture), intakePlenum.Ports[3].MassFlowRate.ToString("R", CultureInfo.InvariantCulture), cylinder1.IntakePort.MassFlowRate.ToString("R", CultureInfo.InvariantCulture), cylinder2.IntakePort.MassFlowRate.ToString("R", CultureInfo.InvariantCulture), cylinder1.ExhaustPort.MassFlowRate.ToString("R", CultureInfo.InvariantCulture), cylinder2.ExhaustPort.MassFlowRate.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(0).rho.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(0).u.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(1).rho.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(1).u.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(1).rho.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(1).u.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(2).rho.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(2).u.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(2).rho.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateRight(2).u.ToString("R", CultureInfo.InvariantCulture), intakePlenum.Density.ToString("R", CultureInfo.InvariantCulture), intakePlenum.Temperature.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(0).rho.ToString("R", CultureInfo.InvariantCulture), pipeSystem.GetInteriorStateLeft(0).u.ToString("R", CultureInfo.InvariantCulture))); Console.SetOut(TextWriter.Null); ++checkpointIndex; } }