diff --git a/VectoCore/Models/Declaration/AirDrag.cs b/VectoCore/Models/Declaration/AirDrag.cs new file mode 100644 index 0000000000000000000000000000000000000000..909d2a72204dccfa332f692d08f0f80266b6bf18 --- /dev/null +++ b/VectoCore/Models/Declaration/AirDrag.cs @@ -0,0 +1,49 @@ +using System; +using System.Data; +using System.Linq; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration +{ + public class AirDrag : LookupData<string, AirDrag.AirDragEntry> + { + private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VCDV.parameters.csv"; + + public AirDrag() + { + ParseData(ReadCsvResource(ResourceId)); + } + + protected override void ParseData(DataTable table) + { + Data = table.Rows.Cast<DataRow>().ToDictionary(row => row.Field<string>("Parameters"), row => new AirDragEntry { + A1 = row.ParseDouble("a1"), + A2 = row.ParseDouble("a2"), + A3 = row.ParseDouble("a3") + }); + } + + public AirDragEntry Lookup(VehicleCategory category) + { + switch (category) { + case VehicleCategory.CityBus: + case VehicleCategory.InterurbanBus: + case VehicleCategory.Coach: + return Lookup("CoachBus"); + case VehicleCategory.Tractor: + return Lookup("TractorSemitrailer"); + case VehicleCategory.RigidTruck: + return Lookup("RigidSolo"); + default: + throw new ArgumentOutOfRangeException("category", category, null); + } + } + + public class AirDragEntry + { + public double A1 { get; set; } + public double A2 { get; set; } + public double A3 { get; set; } + } + } +} \ No newline at end of file diff --git a/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/Models/Declaration/DeclarationData.cs index 4bb5d7f3b6bb2106fb71b5f8f6857ee4aae8d711..beb6b1ef705d299a57005e3e8270134f4ba8156c 100644 --- a/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/Models/Declaration/DeclarationData.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Data; -using System.Linq; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Models.SimulationComponent.Impl; @@ -222,75 +220,4 @@ namespace TUGraz.VectoCore.Models.Declaration } } } - - internal class AirDrag : LookupData<VehicleCategory, double> - { - private const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.VCDV.parameters.csv"; - - public AirDrag() - { - ParseData(ReadCsvResource(ResourceId)); - } - - - protected override void ParseData(DataTable table) - { - // todo: constant!! - var vWind = 3.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(); - - // todo: get from vehicle or move whole procedure to vehicle - var cdA0Actual = 0; - - Data.Clear(); - foreach (DataRow row in table.Rows) { - var cat = row.Field<string>("Parameters"); - var values = new { a1 = row.ParseDouble("a1"), a2 = row.ParseDouble("a2"), a3 = row.ParseDouble("a3") }; - - var betas = new List<double>(); - var deltaCdAs = new List<double>(); - for (var beta = 0; beta <= 12; beta++) { - betas.Add(beta); - var deltaCdA = values.a1 * beta + values.a2 * beta * beta + values.a3 * beta * beta * beta; - deltaCdAs.Add(deltaCdA); - } - - var cdX = new List<double> { 0 }; - var cdY = new List<double> { 0 }; - - for (var vVeh = 60; vVeh <= 100; vVeh += 5) { - var cdASum = 0.0; - for (var alpha = 0; alpha <= 180; alpha += 10) { - var vWindX = vWind * Math.Cos(alpha * Math.PI / 180); - var vWindY = vWind * Math.Sin(alpha * Math.PI / 180); - var vAirX = vVeh + vWindX; - var vAirY = vWindY; - var vAir = VectoMath.Sqrt<MeterPerSecond>(vAirX * vAirX + vAirY * vAirY); - var beta = Math.Atan((vAirY / vAirX).Double()) * 180 / Math.PI; - - var k = 1; - if (betas.First() < beta) { - k = 0; - while (betas[k] < beta && k < betas.Count) { - k++; - } - } - - var deltaCdA = VectoMath.Interpolate(betas[k - 1], betas[k], deltaCdAs[k - 1], deltaCdAs[k], beta); - - var cdA = cdA0Actual + deltaCdA; - - var share = 10 / 180; - if (vVeh == 0 || vVeh == 180) { - share /= 2; - } - cdASum += share * cdA * (vAir * vAir / (vVeh * vVeh)).Double(); - } - cdX.Add(vVeh); - cdY.Add(cdASum); - } - - cdY[0] = cdY[1]; - } - } - } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs index bbe6145774a4b67d675e9ff0aa283a1e480aa858..f79930c4765f48e26dc984ab4a0d8bad673e5830 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs @@ -1,5 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; +using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Models.Connector.Ports; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; using TUGraz.VectoCore.Models.SimulationComponent.Data; @@ -83,6 +87,60 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return (Cd * _data.CrossSectionArea * Physics.AirDensity / 2 * vAir * vAir).Cast<Newton>(); } + protected void CalculateAirResistanceCurve() + { + // todo: get from vehicle or move whole procedure to vehicle + var cdA0Actual = 0; + + var values = DeclarationData.AirDrag.Lookup(_data.VehicleCategory); + + var betas = new List<double>(); + var deltaCdAs = new List<double>(); + for (var beta = 0; beta <= 12; beta++) { + betas.Add(beta); + var deltaCdA = values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta; + deltaCdAs.Add(deltaCdA); + } + + var cdX = new List<double> { 0 }; + var cdY = new List<double> { 0 }; + + for (var vVeh = 60; vVeh <= 100; vVeh += 5) { + var cdASum = 0.0; + for (var alpha = 0; alpha <= 180; alpha += 10) { + var vWindX = Physics.BaseWindSpeed * Math.Cos(alpha * Math.PI / 180); + var vWindY = Physics.BaseWindSpeed * Math.Sin(alpha * Math.PI / 180); + var vAirX = vVeh + vWindX; + var vAirY = vWindY; + var vAir = VectoMath.Sqrt<MeterPerSecond>(vAirX * vAirX + vAirY * vAirY); + var beta = Math.Atan((vAirY / vAirX).Double()) * 180 / Math.PI; + + var k = 1; + if (betas.First() < beta) { + k = 0; + while (betas[k] < beta && k < betas.Count) { + k++; + } + } + + var deltaCdA = VectoMath.Interpolate(betas[k - 1], betas[k], deltaCdAs[k - 1], deltaCdAs[k], beta); + + var cdA = cdA0Actual + deltaCdA; + + var share = 10 / 180; + if (vVeh == 0 || vVeh == 180) { + share /= 2; + } + cdASum += share * cdA * (vAir * vAir / (vVeh * vVeh)).Double(); + } + cdX.Add(vVeh); + cdY.Add(cdASum); + } + + cdY[0] = cdY[1]; + } + + protected Newton AccelerationForce(MeterPerSquareSecond accelleration) { return ((_data.TotalVehicleWeight() + _data.ReducedMassWheels) * accelleration).Cast<Newton>(); diff --git a/VectoCore/Utils/Physics.cs b/VectoCore/Utils/Physics.cs index 2e7566be7f033ed030357f9f59a6671b6b2212c8..cfb90dfe6985d1a4265b245969edba817f19cf50 100644 --- a/VectoCore/Utils/Physics.cs +++ b/VectoCore/Utils/Physics.cs @@ -7,5 +7,7 @@ public static readonly SI AirDensity = 1.188.SI().Kilo.Gramm.Per.Cubic.Meter; public static readonly double RollResistanceExponent = 0.9; + + public static readonly MeterPerSecond BaseWindSpeed = 3.SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(); } } \ No newline at end of file diff --git a/VectoCore/Utils/VectoMath.cs b/VectoCore/Utils/VectoMath.cs index ae853e3781282565e21c61be7d77f84c95676126..425a61c3d2e5027d47b854be6448e2a84dfe22b9 100644 --- a/VectoCore/Utils/VectoMath.cs +++ b/VectoCore/Utils/VectoMath.cs @@ -67,7 +67,7 @@ namespace TUGraz.VectoCore.Utils public static T Sqrt<T>(SI si) where T : SIBase<T> { - si.Sqrt().Cast<T>(); + return si.Sqrt().Cast<T>(); } } } \ No newline at end of file diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index c61527e774ef8e409942450c1c8cf4294cd71182..18a99f6512b40ab5c33d91972456fd6785454bbb 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -139,6 +139,7 @@ <Compile Include="Models\Connector\Ports\Impl\Response.cs" /> <Compile Include="Models\Connector\Ports\IFvPort.cs" /> <Compile Include="Models\Connector\Ports\ITnPort.cs" /> + <Compile Include="Models\Declaration\AirDrag.cs" /> <Compile Include="Models\Declaration\Fan.cs" /> <Compile Include="Models\Declaration\HVAC.cs" /> <Compile Include="Models\Declaration\PneumaticSystem.cs" />