diff --git a/VECTO.sln b/VECTO.sln index d3fe7288cf10583ec65bea9d47a9263601d0c840..ec0fd339db19911702fa90c37db7897ace0bc9f4 100644 --- a/VECTO.sln +++ b/VECTO.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VECTO", "VECTO\VECTO.vbproj", "{AAC0F132-0A9F-45B3-B682-77AC9B24B352}" ProjectSection(ProjectDependencies) = postProject @@ -65,11 +65,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashingTool", "HashingTool\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashingCmd", "HashingCmd\HashingCmd.csproj", "{33F9848E-9257-4BE2-915F-68E748AEB204}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{B5A298FD-8117-4443-9419-66BADA094716}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug PerformanceStats|Any CPU = Debug PerformanceStats|Any CPU @@ -144,8 +139,8 @@ Global {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.Build.0 = Release|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|x64.ActiveCfg = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|x86.ActiveCfg = Debug|Any CPU {FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -172,8 +167,8 @@ Global {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.Build.0 = Release|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|x64.ActiveCfg = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|x86.ActiveCfg = Debug|Any CPU {CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -199,7 +194,6 @@ Global {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|Any CPU.Build.0 = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|x64.ActiveCfg = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|x86.ActiveCfg = Debug|Any CPU {6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -227,7 +221,6 @@ Global {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|Any CPU.Build.0 = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|x64.ActiveCfg = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|x86.ActiveCfg = Debug|Any CPU {6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -273,8 +266,8 @@ Global {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.Build.0 = Release|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|x64.ActiveCfg = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|x86.ActiveCfg = Debug|Any CPU {B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -301,8 +294,8 @@ Global {60AD4DF0-6648-4374-83CB-C7A162EFB391}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.Build.0 = Release|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|x64.ActiveCfg = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|x86.ActiveCfg = Debug|Any CPU {60AD4DF0-6648-4374-83CB-C7A162EFB391}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -330,7 +323,6 @@ Global {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|Any CPU.Build.0 = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|x64.ActiveCfg = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|x86.ActiveCfg = Debug|Any CPU {6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -358,7 +350,6 @@ Global {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|Any CPU.Build.0 = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|x64.ActiveCfg = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|x86.ActiveCfg = Debug|Any CPU {2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -386,7 +377,6 @@ Global {E8B0B447-1A54-4BEC-A160-AF0017000781}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|Any CPU.Build.0 = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|x64.ActiveCfg = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|x86.ActiveCfg = Debug|Any CPU {E8B0B447-1A54-4BEC-A160-AF0017000781}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -411,8 +401,8 @@ Global {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.Build.0 = Release|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|x64.ActiveCfg = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|x86.ActiveCfg = Debug|Any CPU {79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -485,7 +475,6 @@ Global {D959CB7C-F514-4F5E-9C33-684D0012474B}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|Any CPU.Build.0 = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|x64.ActiveCfg = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|x86.ActiveCfg = Debug|Any CPU {D959CB7C-F514-4F5E-9C33-684D0012474B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -508,8 +497,8 @@ Global {41314A40-AB3E-4F43-B1A4-58443F4014F2}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.Build.0 = Release|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|x64.ActiveCfg = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|x86.ActiveCfg = Debug|Any CPU {41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -556,7 +545,6 @@ Global {2C58BA97-2954-4D19-920F-A24B78FC80A4}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|Any CPU.Build.0 = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|x64.ActiveCfg = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|x86.ActiveCfg = Debug|Any CPU {2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -580,7 +568,6 @@ Global {7C364099-9B85-473A-8A42-BBEBE4798FF5}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|Any CPU.Build.0 = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|x64.ActiveCfg = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|x86.ActiveCfg = Debug|Any CPU {7C364099-9B85-473A-8A42-BBEBE4798FF5}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -604,8 +591,8 @@ Global {B673E12F-D323-4C4C-8805-9915B2C72D3D}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.Build.0 = Release|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|x64.ActiveCfg = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|x86.ActiveCfg = Debug|Any CPU {B673E12F-D323-4C4C-8805-9915B2C72D3D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -631,7 +618,6 @@ Global {760C1C5B-A767-463E-BA85-F0BCFC23A550}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.DebugTUG|x86.ActiveCfg = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|Any CPU.Build.0 = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|x64.ActiveCfg = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|x86.ActiveCfg = Debug|Any CPU {760C1C5B-A767-463E-BA85-F0BCFC23A550}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -656,8 +642,8 @@ Global {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.ActiveCfg = Deploy|Any CPU + {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.Build.0 = Deploy|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|x64.ActiveCfg = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|x86.ActiveCfg = Debug|Any CPU {E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -682,8 +668,8 @@ Global {33F9848E-9257-4BE2-915F-68E748AEB204}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.DebugTUG|x64.ActiveCfg = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.DebugTUG|x86.ActiveCfg = Debug|Any CPU - {33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU - {33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.Build.0 = Debug|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.ActiveCfg = Release|Any CPU + {33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.Build.0 = Release|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|x64.ActiveCfg = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|x86.ActiveCfg = Debug|Any CPU {33F9848E-9257-4BE2-915F-68E748AEB204}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs index 4f2186ef0ce080d4106b511ccc40c5df896f4cd8..ca229ce4c55b2f178c28759bd29ad31d19e7c5a5 100644 --- a/VectoCommon/VectoCommon/Utils/SI.cs +++ b/VectoCommon/VectoCommon/Utils/SI.cs @@ -1,1623 +1,1647 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using TUGraz.VectoCommon.Exceptions; - -// ReSharper disable ClassNeverInstantiated.Global - -namespace TUGraz.VectoCommon.Utils -{ - /// <summary> - /// SI Class for Scalar Values. Converts implicitely to double and is only castable if the SI value has no units. - /// </summary> - public class Scalar : SIBase<Scalar> - { - private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Scalar(double val) : base(val, Units) { } - - public static implicit operator double(Scalar self) - { - return self.Val; - } - - [DebuggerHidden] - public static Scalar operator +(Scalar si1, Scalar si2) - { - return Create(si1.Val + si2.Val); - } - - [DebuggerHidden] - public static Scalar operator +(Scalar si1, double si2) - { - return Create(si1.Val + si2); - } - - [DebuggerHidden] - public static Scalar operator +(double si1, Scalar si2) - { - return Create(si1 + si2.Val); - } - - [DebuggerHidden] - public static Scalar operator -(Scalar si1, Scalar si2) - { - return Create(si1.Val - si2.Val); - } - - [DebuggerHidden] - public static Scalar operator -(Scalar si1, double si2) - { - return Create(si1.Val - si2); - } - - [DebuggerHidden] - public static Scalar operator -(double si1, Scalar si2) - { - return Create(si1 - si2.Val); - } - } - - /// <summary> - /// SI Class for Newton [N]. - /// </summary> - public class Newton : SIBase<Newton> - { - private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Newton(double val) : base(val, Units) { } - - [DebuggerHidden] - public static NewtonMeter operator *(Newton newton, Meter meter) - { - return SIBase<NewtonMeter>.Create(newton.Val * meter.Value()); - } - - [DebuggerHidden] - public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond) - { - return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); - } - - [DebuggerHidden] - public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton) - { - return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); - } - } - - /// <summary> - /// SI Class for Radian [] (rad). - /// </summary> - public class Radian : SIBase<Radian> - { - private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Radian(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for PerSquareSecond [1/s^2]. - /// </summary> - public class PerSquareSecond : SIBase<PerSquareSecond> - { - private static readonly int[] Units = { 0, 0, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private PerSquareSecond(double val) : base(val, Units) { } - - [DebuggerHidden] - public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second) - { - return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value()); - } - } - - /// <summary> - /// SI Class for Meter per square second [m/s^2]. - /// </summary> - public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond> - { - private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private MeterPerSquareSecond(double val) : base(val, Units) { } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second) - { - return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value()); - } - } - - /// <summary> - /// SI Class for Second [s]. - /// </summary> - public class Second : SIBase<Second> - { - private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Second(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for Meter [m]. - /// </summary> - public class Meter : SIBase<Meter> - { - private static readonly int[] Units = { 0, 1, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Meter(double val) : base(val, Units) { } - - [DebuggerHidden] - public static MeterPerSecond operator /(Meter meter, Second second) - { - return SIBase<MeterPerSecond>.Create(meter.Val / second.Value()); - } - - [DebuggerHidden] - public static MeterPerSecond operator *(Meter meter, PerSecond perSecond) - { - return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static Second operator /(Meter second, MeterPerSecond meterPerSecond) - { - return SIBase<Second>.Create(second.Val / meterPerSecond.Value()); - } - } - - /// <summary> - /// SI Class for KilogramPerMeter [kg/m]. - /// </summary> - public class KilogramPerMeter : SIBase<KilogramPerMeter> - { - private static readonly int[] Units = { 1, -1, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerMeter(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for Liter per Second [l/s]. - /// </summary> - public class LiterPerSecond : SIBase<LiterPerSecond> - { - private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; - - private LiterPerSecond(double val) : base(val * 0.001, Units) { } - } - - /// <summary> - /// SI Class for Kilogram [kg]. - /// </summary> - public class Kilogram : SIBase<Kilogram> - { - private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Kilogram(double val) : base(val, Units) { } - - [DebuggerHidden] - public static KilogramPerSecond operator /(Kilogram kg, Second second) - { - return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value()); - } - - [DebuggerHidden] - public static SI operator /(Kilogram kg, Joule j) - { - return (kg as SI) / j; - } - - [DebuggerHidden] - public static Scalar operator /(Kilogram kg, Kilogram kg2) - { - return SIBase<Scalar>.Create(kg.Val / kg2.Val); - } - - [DebuggerHidden] - public static KilogramPerMeter operator /(Kilogram kg, Meter m) - { - return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value()); - } - - [DebuggerHidden] - public static Newton operator *(Kilogram kg, MeterPerSquareSecond m) - { - return SIBase<Newton>.Create(kg.Val * m.Value()); - } - - [DebuggerHidden] - public static Kilogram operator *(Kilogram kg, double d) - { - return new Kilogram(kg.Val * d); - } - - [DebuggerHidden] - public static Kilogram operator *(double d, Kilogram kg) - { - return new Kilogram(d * kg.Val); - } - - public static Liter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter) - { - return SIBase<Liter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value() * 1000); - } - } - - public class Liter : SIBase<Liter> - { - private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Liter(double val) : base(val * 0.001, Units) { } - - public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter) - { - return SIBase<Kilogram>.Create(liter.Val / 1000 * kilogramPerCubicMeter.Value()); - } - } - - /// <summary> - /// - /// </summary> - public class NormLiter : SIBase<NormLiter> - { - private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private NormLiter(double val) : base(val * 0.001, Units) { } - - public static NormLiterPerSecond operator /(NormLiter nl, Second s) - { - return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value()); - } - } - - /// <summary> - /// - /// </summary> - public class NormLiterPerSecond : SIBase<NormLiterPerSecond> - { - private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private NormLiterPerSecond(double val) : base(val * 0.001, Units) { } - - public static NormLiter operator *(NormLiterPerSecond nips, Second s) - { - return SIBase<NormLiter>.Create(nips.Val * s.Value()); - } - - public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val) - { - return Create(nps.Val * val); - } - } - - /// <summary> - /// SI Class for Kilogram per Second [kg]. - /// </summary> - public class KilogramPerSecond : SIBase<KilogramPerSecond> - { - private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerSecond(double value) : base(value, Units) { } - - [DebuggerHidden] - public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second) - { - return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value()); - } - } - - /// <summary> - /// SI Class for Square meter [m^2]. - /// </summary> - public class SquareMeter : SIBase<SquareMeter> - { - private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private SquareMeter(double value) : base(value, Units) { } - } - - /// <summary> - /// SI Class for cubic meter [m^3]. - /// </summary> - public class CubicMeter : SIBase<CubicMeter> - { - private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private CubicMeter(double value) - : base(value, Units) { } - } - - /// <summary> - /// SI Class for Kilogram Square Meter [kgm^2]. - /// </summary> - public class KilogramSquareMeter : SIBase<KilogramSquareMeter> - { - private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramSquareMeter(double value) : base(value, Units) { } - - [DebuggerHidden] - public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond) - { - return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value()); - } - } - - /// <summary> - /// SI Class for Kilogram Square Meter [kgm^2]. - /// </summary> - public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter> - { - private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerCubicMeter(double value) : base(value, Units) { } - - [DebuggerHidden] - public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter) - { - return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value()); - } - - public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, Liter liter) - { - return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * liter.Value() / 1000); - } - - //public static CubicMeter operator /(Kilogram kg, KilogramPerCubicMeter kgm3) - //{ - // return SIBase<CubicMeter>.Create(kg.Value() / kgm3.Val); - //} - } - - /// <summary> - /// SI Class for Kilogramm per watt second [kg/Ws]. - /// W = kgm^2/s^3 - /// </summary> - public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond> - { - private static readonly int[] Units = { 0, -2, 2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerWattSecond(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for watt second [Ws]. - /// W = kgm^2/s^3 - /// </summary> - public class WattSecond : SIBase<WattSecond> - { - private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private WattSecond(double val) : base(val, Units) { } - - [DebuggerHidden] - public static Watt operator /(WattSecond wattSecond, Second second) - { - return SIBase<Watt>.Create(wattSecond.Val / second.Value()); - } - } - - /// <summary> - /// SI Class for Watt [W]. - /// </summary> - public class Watt : SIBase<Watt> - { - private static readonly int[] Units = { 1, 2, -3, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Watt(double val) : base(val, Units) { } - - /// <summary> - /// Implements the operator /. - /// </summary> - /// <param name="watt">The watt.</param> - /// <param name="newtonMeter">The newton meter.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter) - { - return SIBase<PerSecond>.Create(watt.Val / newtonMeter.Value()); - } - - [DebuggerHidden] - public static Newton operator /(Watt watt, MeterPerSecond meterPerSecond) - { - return SIBase<Newton>.Create(watt.Val / meterPerSecond.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - /// <param name="watt">The watt.</param> - /// <param name="perSecond">The per second.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static NewtonMeter operator /(Watt watt, PerSecond perSecond) - { - return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value()); - } - - [DebuggerHidden] - public static WattSecond operator *(Watt watt, Second second) - { - return SIBase<WattSecond>.Create(watt.Val * second.Value()); - } - - [DebuggerHidden] - public static Watt operator *(Watt watt, double val) - { - return Create(watt.Val * val); - } - } - - /// <summary> - /// SI Class for Joule [J]. - /// J = Ws = kgm^2/s^2 - /// </summary> - public class Joule : SIBase<Joule> - { - private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Joule(double val) : base(val, Units) { } - - public static implicit operator Joule(WattSecond self) - { - return Create(self.Value()); - } - - public static Joule operator +(Joule joule, WattSecond ws) - { - return Create(joule.Val + ws.Value()); - } - - public static Watt operator /(Joule joule, Second s) - { - return SIBase<Watt>.Create(joule.Val / s.Value()); - } - - public static JoulePerMeter operator /(Joule joule, Meter meter) - { - return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value()); - } - } - - /// <summary> - /// SI Class for Watt [W]. - /// J = Ws - /// W = kgm^2/s^3 - /// </summary> - public class JoulePerKilogramm : SIBase<JoulePerKilogramm> - { - private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 }; - - private JoulePerKilogramm(double val) : base(val, Units) { } - - public static Joule operator *(Kilogram kg, JoulePerKilogramm jpg) - { - return SIBase<Joule>.Create(kg.Value() * jpg.Val); - } - } - - /// <summary> - /// SI Class for Joule per Meter [J/m]. - /// J = Ws - /// W = kgm^2/s^3 - /// </summary> - public class JoulePerMeter : SIBase<JoulePerMeter> - { - private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private JoulePerMeter(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for one per second [1/s]. - /// </summary> - [DebuggerDisplay("rad/s: {Val} | rpm: {AsRPM}")] - public class PerSecond : SIBase<PerSecond> - { - private static readonly int[] Units = { 0, 0, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private PerSecond(double val) : base(val, Units) { } - - [DebuggerHidden] - public static PerSquareSecond operator /(PerSecond perSecond, Second second) - { - return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value()); - } - - public double AsRPM - { - get { return Val * 60 / (2 * Math.PI); } - } - } - - /// <summary> - /// SI Class for Meter per second [m/s]. - /// </summary> - [DebuggerDisplay("{Val} | {AsKmph}")] - public class MeterPerSecond : SIBase<MeterPerSecond> - { - private static readonly int[] Units = { 0, 1, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private MeterPerSecond(double val) : base(val, Units) { } - - public double AsKmph - { - get { return Val * 3.6; } - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter) - { - return SIBase<PerSecond>.Create(meterPerSecond.Val / meter.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond) - { - return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second) - { - return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value()); - } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static Meter operator *(MeterPerSecond meterPerSecond, Second second) - { - return SIBase<Meter>.Create(meterPerSecond.Val * second.Value()); - } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static MeterPerSquareSecond operator *(MeterPerSecond meterPerSecond, PerSecond perSecond) - { - return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val * perSecond.Value()); - } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static Meter operator *(Second second, MeterPerSecond meterPerSecond) - { - return SIBase<Meter>.Create(second.Value() * meterPerSecond.Val); - } - } - - /// <summary> - /// SI Class for NewtonMeter [Nm]. - /// N = kgm/s^2 - /// </summary> - public class NewtonMeter : SIBase<NewtonMeter> - { - private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private NewtonMeter(double val) : base(val, Units) { } - - [DebuggerHidden] - public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond) - { - return SIBase<Watt>.Create(newtonMeter.Val * perSecond.Value()); - } - - [DebuggerHidden] - public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter) - { - return SIBase<Watt>.Create(perSecond.Value() * newtonMeter.Val); - } - - [DebuggerHidden] - public static Second operator /(NewtonMeter newtonMeter, Watt watt) - { - return SIBase<Second>.Create(newtonMeter.Val / watt.Value()); - } - - [DebuggerHidden] - public static PerSquareSecond operator /(NewtonMeter newtonMeter, KilogramSquareMeter kgKilogramSquareMeter) - { - return SIBase<PerSquareSecond>.Create(newtonMeter.Val / kgKilogramSquareMeter.Value()); - } - - [DebuggerHidden] - public static PerSecond operator /(NewtonMeter newtonMeter, NewtonMeterSecond newtonMeterSecond) - { - return SIBase<PerSecond>.Create(newtonMeter.Val / newtonMeterSecond.Value()); - } - - [DebuggerHidden] - public static Newton operator /(NewtonMeter newtonMeter, Meter meter) - { - return SIBase<Newton>.Create(newtonMeter.Val / meter.Value()); - } - - [DebuggerHidden] - public static NewtonMeterSecond operator /(NewtonMeter newtonMeter, PerSecond perSecond) - { - return SIBase<NewtonMeterSecond>.Create(newtonMeter.Val / perSecond.Value()); - } - } - - /// <summary> - /// SI Class for NewtonMeterSecond [Nms]. - /// N = kgm/s^2 - /// </summary> - public class NewtonMeterSecond : SIBase<NewtonMeterSecond> - { - private static readonly int[] Units = { 1, 2, -1, 0, 0, 0, 0 }; - private NewtonMeterSecond(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for Amperer [A]. - /// </summary> - public class Ampere : SIBase<Ampere> - { - private static readonly int[] Units = { 0, 0, 0, 1, 0, 0, 0 }; - private Ampere(double val) : base(val, Units) { } - - public static Watt operator *(Ampere ampere, Volt volt) - { - return SIBase<Watt>.Create(volt.Value() * ampere.Val); - } - - public static Ampere operator *(Ampere ampere, double val) - { - return Create(ampere.Val * val); - } - - public static Volt operator /(Watt watt, Ampere ampere) - { - return SIBase<Volt>.Create(watt.Value() / ampere.Value()); - } - } - - /// <summary> - /// SI Class for Amperer [V]. - /// V = kgm^2/As^2 - /// </summary> - public class Volt : SIBase<Volt> - { - private static readonly int[] Units = { 1, 2, -2, -1, 0, 0, 0 }; - private Volt(double val) : base(val, Units) { } - - public static Watt operator *(Volt volt, Ampere ampere) - { - return SIBase<Watt>.Create(volt.Val * ampere.Value()); - } - - public static Ampere operator /(Watt watt, Volt volt) - { - return SIBase<Ampere>.Create(watt.Value() / volt.Value()); - } - } - - /// <summary> - /// Base Class for all special SI Classes. Not intended to be used directly. - /// Implements templated operators for type safety and convenience. - /// </summary> - /// <typeparam name="T"></typeparam> - public abstract class SIBase<T> : SI where T : SIBase<T> - { - private static readonly T ZeroPrototype; - - static SIBase() - { - const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; - var constructorInfo = typeof(T).GetConstructor(bindingFlags, null, new[] { typeof(double) }, null); - var parameter = Expression.Parameter(typeof(double)); - var lambda = Expression.Lambda<Func<double, T>>(Expression.New(constructorInfo, parameter), parameter); - Constructor = lambda.Compile(); - ZeroPrototype = Constructor(0); - } - - /// <summary> - /// The constructor for the generic type T. - /// </summary> - private static readonly Func<double, T> Constructor; - - /// <summary> - /// Creates the specified special SI object. - /// </summary> - /// <param name="val">The value of the SI object.</param> - [DebuggerStepThrough] - public static T Create(double val) - { - if (val == 0) { - return ZeroPrototype; - } - - return Constructor(val); - } - - [DebuggerStepThrough] - protected SIBase(double value, int[] units) : base(value, units) { } - - [DebuggerStepThrough] - public new T Abs() - { - return Create(Math.Abs(Val)); - } - - #region Operators - - /// <summary> - /// Implements the operator + for two specialized SI Classes. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator +(SIBase<T> si1, SIBase<T> si2) - { - return Create(si1.Val + si2.Val); - } - - /// <summary> - /// Implements the operator + for a specialized SI Class and a generic SI Class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator +(SIBase<T> si1, SI si2) - { - return ((si1 as SI) + si2).Cast<T>(); - } - - /// <summary> - /// Implements the operator + for a generic SI Class and a specialized SI Class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator +(SI si1, SIBase<T> si2) - { - return (si1 + (si2 as SI)).Cast<T>(); - } - - /// <summary> - /// Implements the unary operator -. - /// </summary> - /// <param name="si1">The si1.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SIBase<T> si1) - { - return Create(-si1.Val); - } - - /// <summary> - /// Implements the operator - for two specialized SI classes. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SIBase<T> si1, SIBase<T> si2) - { - return Create(si1.Val - si2.Val); - } - - /// <summary> - /// Implements the operator - for a specialized SI class and a generic SI class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SIBase<T> si1, SI si2) - { - return ((si1 as SI) - si2).Cast<T>(); - } - - /// <summary> - /// Implements the operator - for a generic SI class and a specialized SI class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SI si1, SIBase<T> si2) - { - return (si1 - (si2 as SI)).Cast<T>(); - } - - /// <summary> - /// Implements the operator * for a double and a specialized SI class. - /// </summary> - /// <param name="d">The double value.</param> - /// <param name="si">The si.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator *(double d, SIBase<T> si) - { - return Create(d * si.Val); - } - - /// <summary> - /// Implements the operator * for a specialized SI class and a double. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="d">The double.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator *(SIBase<T> si, double d) - { - return Create(si.Val * d); - } - - /// <summary> - /// Implements the operator / for a specialized SI class and a double. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="d">The double.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator /(SIBase<T> si, double d) - { - return Create(si.Val / d); - } - - [DebuggerHidden] - public static Scalar operator /(SIBase<T> si, SIBase<T> si2) - { - return SIBase<Scalar>.Create(si.Val / si2.Val); - } - - #endregion - } - - /// <summary> - /// Class for representing generic SI Units. - /// </summary> - /// <remarks> - /// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute - /// </remarks> - [DebuggerDisplay("{Val}")] - public class SI : IComparable - { - /// <summary> - /// The basic scalar value of the SI. - /// </summary> - protected readonly double Val; - - /// <summary> - /// The array of the SI units. - /// </summary> - private readonly int[] _units; - - /// <summary> - /// Initializes a new instance of the <see cref="SI"/> class which allows to construct a new SI with all parameters. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="units">The units.</param> - /// <param name="isMassParam"></param> - protected SI(double val, int[] units) - { - Val = val; - _units = units; - - if (double.IsNaN(Val)) { - throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); - } - - if (double.IsInfinity(Val)) { - throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); - } - } - - public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits()) { } - - /// <summary> - /// Initializes a new instance of the <see cref="SI"/> class which copies the units from an already existing SI. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="unit">The unit.</param> - [DebuggerHidden] - private SI(double val, SI unit) : this(val, unit._units) { } - - /// <summary> - /// Casts the SI Unit to the concrete unit type (if the units allow such an cast). - /// </summary> - /// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam> - [DebuggerHidden] - public T Cast<T>() where T : SIBase<T> - { - var si = ToBasicUnits(); - var t = SIBase<T>.Create(si.Val); - if (!si.HasEqualUnit(t)) { - throw new VectoException("SI Unit Conversion failed: From {0} to {1}", si, t); - } - return t; - } - - /// <summary> - /// Converts the derived SI units to the basic units and returns this as a new SI object. - /// </summary> - public SI ToBasicUnits() - { - return new SI(Val, _units); - } - - - /// <summary> - /// Gets the underlying scalar double value. - /// </summary> - [DebuggerHidden] - public double Value() - { - return Val; - } - - /// <summary> - /// Clones this instance. - /// </summary> - public SI Clone() - { - return new SI(Val, _units); - } - - /// <summary> - /// Returns the absolute value. - /// </summary> - public SI Abs() - { - return new SI(Math.Abs(Val), this); - } - - /// <summary> - /// Returns the numerical sign of the SI. - /// </summary> - /// <returns>-1 if si < 0. 0 if si==0, 1 if si > 0.</returns> - [DebuggerHidden] - public int Sign() - { - return Math.Sign(Val); - } - - #region Operators - - [DebuggerHidden] - public static SI operator +(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2); - } - - - return new SI(si1.Val + si2.Val, si1); - } - - [DebuggerHidden] - public static SI operator -(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2); - } - return new SI(si1.Val - si2.Val, si1); - } - - [DebuggerHidden] - public static SI operator -(SI si1) - { - return new SI(-si1.Val, si1); - } - - public static SI operator *(SI si1, SI si2) - { - var unitArray = SIUtils.CombineUnits(si1._units, si2._units); - return new SI(si1.Val * si2.Val, unitArray); - } - - [DebuggerHidden] - public static SI operator *(SI si1, double d) - { - return new SI(si1.Val * d, si1); - } - - [DebuggerHidden] - public static SI operator *(double d, SI si1) - { - return new SI(d * si1.Val, si1); - } - - public static SI operator /(SI si1, SI si2) - { - double result; - try { - result = si1.Val / si2.Val; - - // bad cases: Infinity = x / 0.0 (for x != 0), NaN = 0.0 / 0.0 - if (double.IsInfinity(result) || double.IsNaN(result)) { - throw new DivideByZeroException(); - } - } catch (DivideByZeroException ex) { - throw new VectoException( - string.Format("Can not compute division by zero ([{0}] / 0[{1}])", si1.GetUnitString(), si2.GetUnitString()), ex); - } - - var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1)); - - return new SI(result, unitArray); - } - - [DebuggerHidden] - public static SI operator /(SI si1, double d) - { - if (d.IsEqual(0)) { - throw new VectoException(string.Format("Can not compute division by zero ([{0}] / 0)", si1.GetUnitString()), new DivideByZeroException()); - } - - return new SI(si1.Val / d, si1); - } - - [DebuggerHidden] - public static SI operator /(double d, SI si1) - { - if (si1.IsEqual(0)) { - throw new VectoException(string.Format("Can not compute division by zero (x / 0[{0}])", si1.GetUnitString()), - new DivideByZeroException()); - } - - return new SI(d / si1.Val, si1._units.Select(u => -u).ToArray()); - } - - [DebuggerHidden] - public static bool operator <(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2); - } - return si1.Val < si2.Val; - } - - [DebuggerHidden] - public static bool operator <(SI si1, double d) - { - return si1 != null && si1.Val < d; - } - - [DebuggerHidden] - public static bool operator >(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2); - } - return si1.Val > si2.Val; - } - - [DebuggerHidden] - public static bool operator >(SI si1, double d) - { - return si1 != null && si1.Val > d; - } - - [DebuggerHidden] - public static bool operator >(double d, SI si1) - { - return si1 != null && d > si1.Val; - } - - [DebuggerHidden] - public static bool operator <(double d, SI si1) - { - return si1 != null && d < si1.Val; - } - - [DebuggerHidden] - public static bool operator <=(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1, - si2); - } - return si1.Val <= si2.Val; - } - - [DebuggerHidden] - public static bool operator <=(SI si1, double d) - { - return si1 != null && si1.Val <= d; - } - - [DebuggerHidden] - public static bool operator >=(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1, - si2); - } - return si1.Val >= si2.Val; - } - - [DebuggerHidden] - public static bool operator >=(SI si1, double d) - { - return si1 != null && si1.Val >= d; - } - - [DebuggerHidden] - public static bool operator >=(double d, SI si1) - { - return si1 != null && d >= si1.Val; - } - - [DebuggerHidden] - public static bool operator <=(double d, SI si1) - { - return si1 != null && d <= si1.Val; - } - - /// <summary> - /// Determines whether the SI is between lower and uppper bound. - /// </summary> - /// <param name="lower">The lower bound.</param> - /// <param name="upper">The upper bound.</param> - /// <returns></returns> - public bool IsBetween(SI lower, SI upper) - { - return lower <= Val && Val <= upper; - } - - /// <summary> - /// Determines whether the SI is between lower and upper bound. - /// </summary> - /// <param name="lower">The lower bound.</param> - /// <param name="upper">The upper bound.</param> - /// <returns></returns> - public bool IsBetween(double lower, double upper) - { - return lower <= Val && Val <= upper; - } - - #endregion - - #region ToString - - /// <summary> - /// Returns the Unit Part of the SI Unit Expression. - /// </summary> - public string GetUnitString(int[] units = null) - { - if (units == null) { - units = _units; - } - return Unit.GetUnitString(units); - } - - public override string ToString() - { - return ToString(null); - } - - private string ToString(string format) - { - if (string.IsNullOrEmpty(format)) { - format = "F4"; - } - - return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, GetUnitString()); - } - - #endregion - - #region Equality members - - /// <summary> - /// Compares the Unit-Parts of two SI Units. - /// </summary> - /// <param name="si">The si.</param> - /// <returns></returns> - [DebuggerHidden] - public bool HasEqualUnit(SI si) - { - return SIUtils.CompareUnits(_units, si._units); - } - - /// <summary> - /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. - /// </summary> - /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> - /// <returns> - /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. - /// </returns> - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - var other = obj as SI; - - return other != null && Val.Equals(other.Val) && HasEqualUnit(other); - } - - /// <summary> - /// Determines whether the specified si is equal. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsEqual(SI si, SI tolerance = null) - { - return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) && - Val.IsEqual(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified value is equal. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerHidden] - public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsEqual(val, tolerance); - } - - /// <summary> - /// Determines whether the specified si is smaller. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsSmaller(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return Val.IsSmaller(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified si is smaller. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsSmaller(SI si, double tolerance) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - - return Val.IsSmaller(si.Val, tolerance); - } - - /// <summary> - /// Determines whether [is smaller or equal] [the specified si]. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsSmallerOrEqual(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return Val.IsSmallerOrEqual(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified si is greater. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsGreater(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return Val.IsGreater(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified si is greater. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreater(SI si, double tolerance) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - - return Val.IsGreater(si.Val, tolerance); - } - - /// <summary> - /// Determines whether [is greater or equal] [the specified si]. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreaterOrEqual(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return Val.IsGreaterOrEqual(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified value is smaller. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsSmaller(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsSmaller(val, tolerance); - } - - /// <summary> - /// Determines whether [is smaller or equal] [the specified value]. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsSmallerOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsSmallerOrEqual(val, tolerance); - } - - /// <summary> - /// Determines whether the specified value is greater. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreater(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsGreater(val, tolerance); - } - - /// <summary> - /// Determines whether [is greater or equal] [the specified value]. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreaterOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsGreaterOrEqual(val, tolerance); - } - - public override int GetHashCode() - { - unchecked { - // ReSharper disable once NonReadonlyMemberInGetHashCode - var hashCode = Val.GetHashCode(); - hashCode = (hashCode * 397) ^ (_units != null ? _units.GetHashCode() : 0); - return hashCode; - } - } - - public int CompareTo(object obj) - { - var si = obj as SI; - if (si == null) { - return 1; - } - - if (!HasEqualUnit(si)) { - var sum1 = 0; - var sum2 = 0; - for (var i = 0; i < _units.Length; i++) { - sum1 = Math.Abs(si._units[i]); - sum2 = Math.Abs(_units[i]); - } - return sum1 >= sum2 ? 1 : -1; - } - - if (this > si) { - return 1; - } - - if (this < si) { - return -1; - } - - return 0; - } - - public static bool operator ==(SI left, SI right) - { - return Equals(left, right); - } - - public static bool operator !=(SI left, SI right) - { - return !Equals(left, right); - } - - #endregion - - /// <summary> - /// Convert the SI to a string in the wished output format. - /// </summary> - /// <param name="decimals">The decimals.</param> - /// <param name="outputFactor">The output factor.</param> - /// <param name="showUnit">The show unit.</param> - /// <returns></returns> - public string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null) - { - decimals = decimals ?? 4; - outputFactor = outputFactor ?? 1.0; - showUnit = showUnit ?? false; - - if (showUnit.Value) { - return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture) + " [" + - GetUnitString() + "]"; - } - - return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture); - } - - public string ToGUIFormat() - { - return Val.ToGUIFormat(); - } - - public string ToXMLFormat(uint? decimals = null) - { - decimals = decimals ?? 2; - return Val.ToString("F" + decimals.Value, CultureInfo.InvariantCulture); - } - - public class EqualityComparer<T> : IEqualityComparer<T> where T : SI - { - private readonly double _precision; - - public EqualityComparer(double precision = DoubleExtensionMethods.Tolerance) - { - _precision = precision; - } - - public bool Equals(T x, T y) - { - return y != null && x != null && x.IsEqual(y.Value(), _precision); - } - - public int GetHashCode(T obj) - { - return obj.Value().GetHashCode(); - } - } - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using TUGraz.VectoCommon.Exceptions; + +// ReSharper disable ClassNeverInstantiated.Global + +namespace TUGraz.VectoCommon.Utils +{ + /// <summary> + /// SI Class for Scalar Values. Converts implicitely to double and is only castable if the SI value has no units. + /// </summary> + public class Scalar : SIBase<Scalar> + { + private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Scalar(double val) : base(val, Units) { } + + public static implicit operator double(Scalar self) + { + return self.Val; + } + + [DebuggerHidden] + public static Scalar operator +(Scalar si1, Scalar si2) + { + return Create(si1.Val + si2.Val); + } + + [DebuggerHidden] + public static Scalar operator +(Scalar si1, double si2) + { + return Create(si1.Val + si2); + } + + [DebuggerHidden] + public static Scalar operator +(double si1, Scalar si2) + { + return Create(si1 + si2.Val); + } + + [DebuggerHidden] + public static Scalar operator -(Scalar si1, Scalar si2) + { + return Create(si1.Val - si2.Val); + } + + [DebuggerHidden] + public static Scalar operator -(Scalar si1, double si2) + { + return Create(si1.Val - si2); + } + + [DebuggerHidden] + public static Scalar operator -(double si1, Scalar si2) + { + return Create(si1 - si2.Val); + } + } + + /// <summary> + /// SI Class for Newton [N]. + /// </summary> + public class Newton : SIBase<Newton> + { + private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Newton(double val) : base(val, Units) { } + + [DebuggerHidden] + public static NewtonMeter operator *(Newton newton, Meter meter) + { + return SIBase<NewtonMeter>.Create(newton.Val * meter.Value()); + } + + [DebuggerHidden] + public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond) + { + return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); + } + + [DebuggerHidden] + public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton) + { + return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); + } + } + + /// <summary> + /// SI Class for Radian [] (rad). + /// </summary> + public class Radian : SIBase<Radian> + { + private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Radian(double val) : base(val, Units) { } + } + + /// <summary> + /// SI Class for PerSquareSecond [1/s^2]. + /// </summary> + public class PerSquareSecond : SIBase<PerSquareSecond> + { + private static readonly int[] Units = { 0, 0, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private PerSquareSecond(double val) : base(val, Units) { } + + [DebuggerHidden] + public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second) + { + return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value()); + } + } + + /// <summary> + /// SI Class for Meter per square second [m/s^2]. + /// </summary> + public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond> + { + private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private MeterPerSquareSecond(double val) : base(val, Units) { } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second) + { + return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value()); + } + } + + /// <summary> + /// SI Class for Second [s]. + /// </summary> + public class Second : SIBase<Second> + { + private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Second(double val) : base(val, Units) { } + } + + /// <summary> + /// SI Class for Meter [m]. + /// </summary> + public class Meter : SIBase<Meter> + { + private static readonly int[] Units = { 0, 1, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Meter(double val) : base(val, Units) { } + + [DebuggerHidden] + public static MeterPerSecond operator /(Meter meter, Second second) + { + return SIBase<MeterPerSecond>.Create(meter.Val / second.Value()); + } + + [DebuggerHidden] + public static MeterPerSecond operator *(Meter meter, PerSecond perSecond) + { + return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static Second operator /(Meter second, MeterPerSecond meterPerSecond) + { + return SIBase<Second>.Create(second.Val / meterPerSecond.Value()); + } + } + + /// <summary> + /// SI Class for KilogramPerMeter [kg/m]. + /// </summary> + public class KilogramPerMeter : SIBase<KilogramPerMeter> + { + private static readonly int[] Units = { 1, -1, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private KilogramPerMeter(double val) : base(val, Units) { } + } + + /// <summary> + /// SI Class for Liter per Second [l/s]. + /// </summary> + public class LiterPerSecond : SIBase<LiterPerSecond> + { + private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; + + private LiterPerSecond(double val) : base(val, 0.001, Units) { } + + [DebuggerHidden] + public static Liter operator *(LiterPerSecond l, Second second) + { + return SIBase<Liter>.Create(l.Val * second.Value()); + } + + [DebuggerHidden] + public static Liter operator *(Second second, LiterPerSecond l) + { + return SIBase<Liter>.Create(l.Val * second.Value()); + } + } + + /// <summary> + /// SI Class for Kilogram [kg]. + /// </summary> + public class Kilogram : SIBase<Kilogram> + { + private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Kilogram(double val) : base(val, Units) { } + + [DebuggerHidden] + public static KilogramPerSecond operator /(Kilogram kg, Second second) + { + return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value()); + } + + [DebuggerHidden] + public static SI operator /(Kilogram kg, Joule j) + { + return (kg as SI) / j; + } + + [DebuggerHidden] + public static Scalar operator /(Kilogram kg, Kilogram kg2) + { + return SIBase<Scalar>.Create(kg.Val / kg2.Val); + } + + [DebuggerHidden] + public static KilogramPerMeter operator /(Kilogram kg, Meter m) + { + return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value()); + } + + [DebuggerHidden] + public static Newton operator *(Kilogram kg, MeterPerSquareSecond m) + { + return SIBase<Newton>.Create(kg.Val * m.Value()); + } + + [DebuggerHidden] + public static Kilogram operator *(Kilogram kg, double d) + { + return new Kilogram(kg.Val * d); + } + + [DebuggerHidden] + public static Kilogram operator *(double d, Kilogram kg) + { + return new Kilogram(d * kg.Val); + } + + public static CubicMeter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter) + { + return SIBase<CubicMeter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value()); + } + } + + public class Liter : SIBase<Liter> + { + private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + //[DebuggerHidden] + private Liter(double val) : base(val , 0.001, Units) { } + + public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter) + { + return SIBase<Kilogram>.Create(liter.AsBasicUnit * kilogramPerCubicMeter.Value()); + } + } + + /// <summary> + /// + /// </summary> + public class NormLiter : SIBase<NormLiter> + { + private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; + + //[DebuggerHidden] + private NormLiter(double val) : base(val , 0.001, Units) { } + + public static NormLiterPerSecond operator /(NormLiter nl, Second s) + { + return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value()); + } + } + + /// <summary> + /// + /// </summary> + public class NormLiterPerSecond : SIBase<NormLiterPerSecond> + { + private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; + + //[DebuggerHidden] + private NormLiterPerSecond(double val) : base(val, 0.001, Units) { } + + public static NormLiter operator *(NormLiterPerSecond nips, Second s) + { + return SIBase<NormLiter>.Create(nips.Val * s.Value()); + } + + public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val) + { + return Create(nps.Val * val); + } + + public static NormLiterPerSecond operator /(NormLiterPerSecond nps, double val) + { + return Create(nps.Val / val); + } + } + + /// <summary> + /// SI Class for Kilogram per Second [kg]. + /// </summary> + public class KilogramPerSecond : SIBase<KilogramPerSecond> + { + private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 }; + + [DebuggerHidden] + private KilogramPerSecond(double value) : base(value, Units) { } + + [DebuggerHidden] + public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second) + { + return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value()); + } + } + + /// <summary> + /// SI Class for Square meter [m^2]. + /// </summary> + public class SquareMeter : SIBase<SquareMeter> + { + private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private SquareMeter(double value) : base(value, Units) { } + } + + /// <summary> + /// SI Class for cubic meter [m^3]. + /// </summary> + public class CubicMeter : SIBase<CubicMeter> + { + private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private CubicMeter(double value) + : base(value, Units) { } + } + + /// <summary> + /// SI Class for Kilogram Square Meter [kgm^2]. + /// </summary> + public class KilogramSquareMeter : SIBase<KilogramSquareMeter> + { + private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private KilogramSquareMeter(double value) : base(value, Units) { } + + [DebuggerHidden] + public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond) + { + return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value()); + } + } + + /// <summary> + /// SI Class for Kilogram Square Meter [kgm^2]. + /// </summary> + public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter> + { + private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private KilogramPerCubicMeter(double value) : base(value, Units) { } + + [DebuggerHidden] + public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter) + { + return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value()); + } + + } + + /// <summary> + /// SI Class for Kilogramm per watt second [kg/Ws]. + /// W = kgm^2/s^3 + /// </summary> + public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond> + { + private static readonly int[] Units = { 0, -2, 2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private KilogramPerWattSecond(double val) : base(val, Units) { } + } + + /// <summary> + /// SI Class for watt second [Ws]. + /// W = kgm^2/s^3 + /// </summary> + public class WattSecond : SIBase<WattSecond> + { + private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private WattSecond(double val) : base(val, Units) { } + + [DebuggerHidden] + public static Watt operator /(WattSecond wattSecond, Second second) + { + return SIBase<Watt>.Create(wattSecond.Val / second.Value()); + } + } + + /// <summary> + /// SI Class for Watt [W]. + /// </summary> + public class Watt : SIBase<Watt> + { + private static readonly int[] Units = { 1, 2, -3, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Watt(double val) : base(val, Units) { } + + /// <summary> + /// Implements the operator /. + /// </summary> + /// <param name="watt">The watt.</param> + /// <param name="newtonMeter">The newton meter.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter) + { + return SIBase<PerSecond>.Create(watt.Val / newtonMeter.Value()); + } + + [DebuggerHidden] + public static Newton operator /(Watt watt, MeterPerSecond meterPerSecond) + { + return SIBase<Newton>.Create(watt.Val / meterPerSecond.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + /// <param name="watt">The watt.</param> + /// <param name="perSecond">The per second.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static NewtonMeter operator /(Watt watt, PerSecond perSecond) + { + return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value()); + } + + [DebuggerHidden] + public static WattSecond operator *(Watt watt, Second second) + { + return SIBase<WattSecond>.Create(watt.Val * second.Value()); + } + + [DebuggerHidden] + public static Watt operator *(Watt watt, double val) + { + return Create(watt.Val * val); + } + } + + /// <summary> + /// SI Class for Joule [J]. + /// J = Ws = kgm^2/s^2 + /// </summary> + public class Joule : SIBase<Joule> + { + private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Joule(double val) : base(val, Units) { } + + public static implicit operator Joule(WattSecond self) + { + return Create(self.Value()); + } + + public static Joule operator +(Joule joule, WattSecond ws) + { + return Create(joule.Val + ws.Value()); + } + + public static Watt operator /(Joule joule, Second s) + { + return SIBase<Watt>.Create(joule.Val / s.Value()); + } + + public static JoulePerMeter operator /(Joule joule, Meter meter) + { + return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value()); + } + } + + /// <summary> + /// SI Class for Watt [W]. + /// J = Ws + /// W = kgm^2/s^3 + /// </summary> + public class JoulePerKilogramm : SIBase<JoulePerKilogramm> + { + private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 }; + + private JoulePerKilogramm(double val) : base(val, Units) { } + + public static Joule operator *(Kilogram kg, JoulePerKilogramm jpg) + { + return SIBase<Joule>.Create(kg.Value() * jpg.Val); + } + } + + /// <summary> + /// SI Class for Joule per Meter [J/m]. + /// J = Ws + /// W = kgm^2/s^3 + /// </summary> + public class JoulePerMeter : SIBase<JoulePerMeter> + { + private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private JoulePerMeter(double val) : base(val, Units) { } + } + + /// <summary> + /// SI Class for one per second [1/s]. + /// </summary> + [DebuggerDisplay("rad/s: {Val} | rpm: {AsRPM}")] + public class PerSecond : SIBase<PerSecond> + { + private static readonly int[] Units = { 0, 0, -1, 0, 0, 0, 0 }; + + [DebuggerHidden] + private PerSecond(double val) : base(val, Units) { } + + [DebuggerHidden] + public static PerSquareSecond operator /(PerSecond perSecond, Second second) + { + return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value()); + } + + public double AsRPM + { + get { return Val * 60 / (2 * Math.PI); } + } + } + + /// <summary> + /// SI Class for Meter per second [m/s]. + /// </summary> + [DebuggerDisplay("{Val} | {AsKmph}")] + public class MeterPerSecond : SIBase<MeterPerSecond> + { + private static readonly int[] Units = { 0, 1, -1, 0, 0, 0, 0 }; + + [DebuggerHidden] + private MeterPerSecond(double val) : base(val, Units) { } + + public double AsKmph + { + get { return Val * 3.6; } + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter) + { + return SIBase<PerSecond>.Create(meterPerSecond.Val / meter.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond) + { + return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second) + { + return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value()); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static Meter operator *(MeterPerSecond meterPerSecond, Second second) + { + return SIBase<Meter>.Create(meterPerSecond.Val * second.Value()); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static MeterPerSquareSecond operator *(MeterPerSecond meterPerSecond, PerSecond perSecond) + { + return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val * perSecond.Value()); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static Meter operator *(Second second, MeterPerSecond meterPerSecond) + { + return SIBase<Meter>.Create(second.Value() * meterPerSecond.Val); + } + } + + /// <summary> + /// SI Class for NewtonMeter [Nm]. + /// N = kgm/s^2 + /// </summary> + public class NewtonMeter : SIBase<NewtonMeter> + { + private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private NewtonMeter(double val) : base(val, Units) { } + + [DebuggerHidden] + public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond) + { + return SIBase<Watt>.Create(newtonMeter.Val * perSecond.Value()); + } + + [DebuggerHidden] + public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter) + { + return SIBase<Watt>.Create(perSecond.Value() * newtonMeter.Val); + } + + [DebuggerHidden] + public static Second operator /(NewtonMeter newtonMeter, Watt watt) + { + return SIBase<Second>.Create(newtonMeter.Val / watt.Value()); + } + + [DebuggerHidden] + public static PerSquareSecond operator /(NewtonMeter newtonMeter, KilogramSquareMeter kgKilogramSquareMeter) + { + return SIBase<PerSquareSecond>.Create(newtonMeter.Val / kgKilogramSquareMeter.Value()); + } + + [DebuggerHidden] + public static PerSecond operator /(NewtonMeter newtonMeter, NewtonMeterSecond newtonMeterSecond) + { + return SIBase<PerSecond>.Create(newtonMeter.Val / newtonMeterSecond.Value()); + } + + [DebuggerHidden] + public static Newton operator /(NewtonMeter newtonMeter, Meter meter) + { + return SIBase<Newton>.Create(newtonMeter.Val / meter.Value()); + } + + [DebuggerHidden] + public static NewtonMeterSecond operator /(NewtonMeter newtonMeter, PerSecond perSecond) + { + return SIBase<NewtonMeterSecond>.Create(newtonMeter.Val / perSecond.Value()); + } + } + + /// <summary> + /// SI Class for NewtonMeterSecond [Nms]. + /// N = kgm/s^2 + /// </summary> + public class NewtonMeterSecond : SIBase<NewtonMeterSecond> + { + private static readonly int[] Units = { 1, 2, -1, 0, 0, 0, 0 }; + private NewtonMeterSecond(double val) : base(val, Units) { } + } + + /// <summary> + /// SI Class for Amperer [A]. + /// </summary> + public class Ampere : SIBase<Ampere> + { + private static readonly int[] Units = { 0, 0, 0, 1, 0, 0, 0 }; + private Ampere(double val) : base(val, Units) { } + + public static Watt operator *(Ampere ampere, Volt volt) + { + return SIBase<Watt>.Create(volt.Value() * ampere.Val); + } + + public static Ampere operator *(Ampere ampere, double val) + { + return Create(ampere.Val * val); + } + + public static Volt operator /(Watt watt, Ampere ampere) + { + return SIBase<Volt>.Create(watt.Value() / ampere.Value()); + } + } + + /// <summary> + /// SI Class for Amperer [V]. + /// V = kgm^2/As^2 + /// </summary> + public class Volt : SIBase<Volt> + { + private static readonly int[] Units = { 1, 2, -2, -1, 0, 0, 0 }; + private Volt(double val) : base(val, Units) { } + + public static Watt operator *(Volt volt, Ampere ampere) + { + return SIBase<Watt>.Create(volt.Val * ampere.Value()); + } + + public static Ampere operator /(Watt watt, Volt volt) + { + return SIBase<Ampere>.Create(watt.Value() / volt.Value()); + } + } + + /// <summary> + /// Base Class for all special SI Classes. Not intended to be used directly. + /// Implements templated operators for type safety and convenience. + /// </summary> + /// <typeparam name="T"></typeparam> + public abstract class SIBase<T> : SI where T : SIBase<T> + { + private static readonly T ZeroPrototype; + + static SIBase() + { + const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; + var constructorInfo = typeof(T).GetConstructor(bindingFlags, null, new[] { typeof(double) }, null); + var parameter = Expression.Parameter(typeof(double)); + var lambda = Expression.Lambda<Func<double, T>>(Expression.New(constructorInfo, parameter), parameter); + Constructor = lambda.Compile(); + ZeroPrototype = Constructor(0); + } + + /// <summary> + /// The constructor for the generic type T. + /// </summary> + private static readonly Func<double, T> Constructor; + + /// <summary> + /// Creates the specified special SI object. + /// </summary> + /// <param name="val">The value of the SI object.</param> + [DebuggerStepThrough] + public static T Create(double val) + { + if (val == 0) { + return ZeroPrototype; + } + + return Constructor(val); + } + + [DebuggerStepThrough] + protected SIBase(double value, int[] units) : base(value, units) { } + + protected SIBase(double value, double unitFactor, int[] units) : base(value, unitFactor, units) { } + + [DebuggerStepThrough] + public new T Abs() + { + return Create(Math.Abs(Val)); + } + + #region Operators + + /// <summary> + /// Implements the operator + for two specialized SI Classes. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator +(SIBase<T> si1, SIBase<T> si2) + { + return Create(si1.Val + si2.Val); + } + + /// <summary> + /// Implements the operator + for a specialized SI Class and a generic SI Class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator +(SIBase<T> si1, SI si2) + { + return ((si1 as SI) + si2).Cast<T>(); + } + + /// <summary> + /// Implements the operator + for a generic SI Class and a specialized SI Class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator +(SI si1, SIBase<T> si2) + { + return (si1 + (si2 as SI)).Cast<T>(); + } + + /// <summary> + /// Implements the unary operator -. + /// </summary> + /// <param name="si1">The si1.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SIBase<T> si1) + { + return Create(-si1.Val); + } + + /// <summary> + /// Implements the operator - for two specialized SI classes. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SIBase<T> si1, SIBase<T> si2) + { + return Create(si1.Val - si2.Val); + } + + /// <summary> + /// Implements the operator - for a specialized SI class and a generic SI class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SIBase<T> si1, SI si2) + { + return ((si1 as SI) - si2).Cast<T>(); + } + + /// <summary> + /// Implements the operator - for a generic SI class and a specialized SI class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SI si1, SIBase<T> si2) + { + return (si1 - (si2 as SI)).Cast<T>(); + } + + /// <summary> + /// Implements the operator * for a double and a specialized SI class. + /// </summary> + /// <param name="d">The double value.</param> + /// <param name="si">The si.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator *(double d, SIBase<T> si) + { + return Create(d * si.Val); + } + + /// <summary> + /// Implements the operator * for a specialized SI class and a double. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="d">The double.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator *(SIBase<T> si, double d) + { + return Create(si.Val * d); + } + + /// <summary> + /// Implements the operator / for a specialized SI class and a double. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="d">The double.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator /(SIBase<T> si, double d) + { + return Create(si.Val / d); + } + + [DebuggerHidden] + public static Scalar operator /(SIBase<T> si, SIBase<T> si2) + { + return SIBase<Scalar>.Create(si.Val / si2.Val); + } + + #endregion + } + + /// <summary> + /// Class for representing generic SI Units. + /// </summary> + /// <remarks> + /// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute + /// </remarks> + [DebuggerDisplay("{Val}")] + public class SI : IComparable + { + /// <summary> + /// The basic scalar value of the SI. + /// </summary> + protected readonly double Val; + + /// <summary> + /// The array of the SI units. + /// </summary> + private readonly int[] _units; + + private double UnitFactor; + + /// <summary> + /// Initializes a new instance of the <see cref="SI"/> class which allows to construct a new SI with all parameters. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="unitFactor"></param> + /// <param name="units">The units.</param> + protected SI(double val, double unitFactor, int[] units) + { + Val = val; + _units = units; + UnitFactor = unitFactor; + + if (double.IsNaN(Val)) { + throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); + } + + if (double.IsInfinity(Val)) { + throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); + } + } + + protected SI(double val, int[] units) : this(val, 1, units) { } + + + public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits()) { } + + /// <summary> + /// Initializes a new instance of the <see cref="SI"/> class which copies the units from an already existing SI. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="unit">The unit.</param> + [DebuggerHidden] + private SI(double val, SI unit) : this(val, unit.UnitFactor,unit._units) { } + + /// <summary> + /// Casts the SI Unit to the concrete unit type (if the units allow such an cast). + /// </summary> + /// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam> + [DebuggerHidden] + public T Cast<T>() where T : SIBase<T> + { + var si = ToBasicUnits(); + var zero = SIBase<T>.Create(0); + var t = SIBase<T>.Create(si.Val / zero.UnitFactor); + if (!si.HasEqualUnit(t)) { + throw new VectoException("SI Unit Conversion failed: From {0} to {1}", si, t); + } + return t; + } + + /// <summary> + /// Converts the derived SI units to the basic units and returns this as a new SI object. + /// </summary> + public SI ToBasicUnits() + { + return new SI(Val * UnitFactor, _units); + } + + protected double AsBasicUnit + { + get { return Val * UnitFactor; } + } + + + /// <summary> + /// Gets the underlying scalar double value. + /// </summary> + [DebuggerHidden] + public double Value() + { + return Val; + } + + /// <summary> + /// Clones this instance. + /// </summary> + public SI Clone() + { + return new SI(Val, _units); + } + + /// <summary> + /// Returns the absolute value. + /// </summary> + public SI Abs() + { + return new SI(Math.Abs(Val), this); + } + + /// <summary> + /// Returns the numerical sign of the SI. + /// </summary> + /// <returns>-1 if si < 0. 0 if si==0, 1 if si > 0.</returns> + [DebuggerHidden] + public int Sign() + { + return Math.Sign(Val); + } + + #region Operators + + [DebuggerHidden] + public static SI operator +(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2); + } + + + return new SI(si1.Val + si2.Val, si1); + } + + [DebuggerHidden] + public static SI operator -(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2); + } + return new SI(si1.Val - si2.Val, si1); + } + + [DebuggerHidden] + public static SI operator -(SI si1) + { + return new SI(-si1.Val, si1); + } + + public static SI operator *(SI si1, SI si2) + { + var unitArray = SIUtils.CombineUnits(si1._units, si2._units); + return new SI(si1.AsBasicUnit * si2.AsBasicUnit, unitArray); + } + + [DebuggerHidden] + public static SI operator *(SI si1, double d) + { + return new SI(si1.Val * d, si1); + } + + [DebuggerHidden] + public static SI operator *(double d, SI si1) + { + return new SI(d * si1.Val, si1); + } + + public static SI operator /(SI si1, SI si2) + { + double result; + try { + result = si1.AsBasicUnit / si2.AsBasicUnit; + + // bad cases: Infinity = x / 0.0 (for x != 0), NaN = 0.0 / 0.0 + if (double.IsInfinity(result) || double.IsNaN(result)) { + throw new DivideByZeroException(); + } + } catch (DivideByZeroException ex) { + throw new VectoException( + string.Format("Can not compute division by zero ([{0}] / 0[{1}])", si1.GetUnitString(), si2.GetUnitString()), ex); + } + + var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1)); + + return new SI(result, unitArray); + } + + [DebuggerHidden] + public static SI operator /(SI si1, double d) + { + if (d.IsEqual(0)) { + throw new VectoException(string.Format("Can not compute division by zero ([{0}] / 0)", si1.GetUnitString()), new DivideByZeroException()); + } + + return new SI(si1.Val / d, si1); + } + + [DebuggerHidden] + public static SI operator /(double d, SI si1) + { + if (si1.IsEqual(0)) { + throw new VectoException(string.Format("Can not compute division by zero (x / 0[{0}])", si1.GetUnitString()), + new DivideByZeroException()); + } + + return new SI(d / si1.AsBasicUnit, si1._units.Select(u => -u).ToArray()); + } + + [DebuggerHidden] + public static bool operator <(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2); + } + return si1.AsBasicUnit < si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator <(SI si1, double d) + { + return si1 != null && si1.Val < d; + } + + [DebuggerHidden] + public static bool operator >(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2); + } + return si1.AsBasicUnit > si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator >(SI si1, double d) + { + return si1 != null && si1.Val > d; + } + + [DebuggerHidden] + public static bool operator >(double d, SI si1) + { + return si1 != null && d > si1.Val; + } + + [DebuggerHidden] + public static bool operator <(double d, SI si1) + { + return si1 != null && d < si1.Val; + } + + [DebuggerHidden] + public static bool operator <=(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1, + si2); + } + return si1.AsBasicUnit <= si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator <=(SI si1, double d) + { + return si1 != null && si1.Val <= d; + } + + [DebuggerHidden] + public static bool operator >=(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1, + si2); + } + return si1.AsBasicUnit >= si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator >=(SI si1, double d) + { + return si1 != null && si1.Val >= d; + } + + [DebuggerHidden] + public static bool operator >=(double d, SI si1) + { + return si1 != null && d >= si1.Val; + } + + [DebuggerHidden] + public static bool operator <=(double d, SI si1) + { + return si1 != null && d <= si1.Val; + } + + /// <summary> + /// Determines whether the SI is between lower and uppper bound. + /// </summary> + /// <param name="lower">The lower bound.</param> + /// <param name="upper">The upper bound.</param> + /// <returns></returns> + public bool IsBetween(SI lower, SI upper) + { + return lower <= Val && Val <= upper; + } + + /// <summary> + /// Determines whether the SI is between lower and upper bound. + /// </summary> + /// <param name="lower">The lower bound.</param> + /// <param name="upper">The upper bound.</param> + /// <returns></returns> + public bool IsBetween(double lower, double upper) + { + return lower <= Val && Val <= upper; + } + + #endregion + + #region ToString + + /// <summary> + /// Returns the Unit Part of the SI Unit Expression. + /// </summary> + public string GetUnitString(int[] units = null) + { + if (units == null) { + units = _units; + } + return Unit.GetUnitString(units); + } + + public override string ToString() + { + return ToString(null); + } + + private string ToString(string format) + { + if (string.IsNullOrEmpty(format)) { + format = "F4"; + } + + return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, GetUnitString()); + } + + #endregion + + #region Equality members + + /// <summary> + /// Compares the Unit-Parts of two SI Units. + /// </summary> + /// <param name="si">The si.</param> + /// <returns></returns> + [DebuggerHidden] + public bool HasEqualUnit(SI si) + { + return SIUtils.CompareUnits(_units, si._units); + } + + /// <summary> + /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. + /// </summary> + /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. + /// </returns> + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } + var other = obj as SI; + + return other != null && AsBasicUnit.Equals(other.AsBasicUnit) && HasEqualUnit(other); + } + + /// <summary> + /// Determines whether the specified si is equal. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsEqual(SI si, SI tolerance = null) + { + return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) && + AsBasicUnit.IsEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified value is equal. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerHidden] + public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsEqual(val, tolerance); + } + + /// <summary> + /// Determines whether the specified si is smaller. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsSmaller(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsSmaller(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified si is smaller. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsSmaller(SI si, double tolerance) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + + return Val.IsSmaller(si.Val, tolerance); + } + + /// <summary> + /// Determines whether [is smaller or equal] [the specified si]. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsSmallerOrEqual(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsSmallerOrEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified si is greater. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsGreater(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsGreater(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified si is greater. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreater(SI si, double tolerance) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + + return Val.IsGreater(si.Val, tolerance); + } + + /// <summary> + /// Determines whether [is greater or equal] [the specified si]. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreaterOrEqual(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsGreaterOrEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified value is smaller. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsSmaller(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsSmaller(val, tolerance); + } + + /// <summary> + /// Determines whether [is smaller or equal] [the specified value]. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsSmallerOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsSmallerOrEqual(val, tolerance); + } + + /// <summary> + /// Determines whether the specified value is greater. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreater(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsGreater(val, tolerance); + } + + /// <summary> + /// Determines whether [is greater or equal] [the specified value]. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreaterOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsGreaterOrEqual(val, tolerance); + } + + public override int GetHashCode() + { + unchecked { + // ReSharper disable once NonReadonlyMemberInGetHashCode + var hashCode = Val.GetHashCode(); + hashCode = (hashCode * 397) ^ (_units != null ? _units.GetHashCode() : 0); + return hashCode; + } + } + + public int CompareTo(object obj) + { + var si = obj as SI; + if (si == null) { + return 1; + } + + if (!HasEqualUnit(si)) { + // TODO: thow exception! + var sum1 = 0; + var sum2 = 0; + for (var i = 0; i < _units.Length; i++) { + sum1 += Math.Abs(si._units[i]); + sum2 += Math.Abs(_units[i]); + } + return sum1 >= sum2 ? -1 : 1; + } + + if (this > si) { + return 1; + } + + if (this < si) { + return -1; + } + + return 0; + } + + public static bool operator ==(SI left, SI right) + { + return Equals(left, right); + } + + public static bool operator !=(SI left, SI right) + { + return !Equals(left, right); + } + + #endregion + + /// <summary> + /// Convert the SI to a string in the wished output format. + /// </summary> + /// <param name="decimals">The decimals.</param> + /// <param name="outputFactor">The output factor.</param> + /// <param name="showUnit">The show unit.</param> + /// <returns></returns> + public string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null) + { + decimals = decimals ?? 4; + outputFactor = outputFactor ?? 1.0; + showUnit = showUnit ?? false; + + if (showUnit.Value) { + return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture) + " [" + + GetUnitString() + "]"; + } + + return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture); + } + + public string ToGUIFormat() + { + return Val.ToGUIFormat(); + } + + public string ToXMLFormat(uint? decimals = null) + { + decimals = decimals ?? 2; + return Val.ToString("F" + decimals.Value, CultureInfo.InvariantCulture); + } + + public class EqualityComparer<T> : IEqualityComparer<T> where T : SI + { + private readonly double _precision; + + public EqualityComparer(double precision = DoubleExtensionMethods.Tolerance) + { + _precision = precision; + } + + public bool Equals(T x, T y) + { + return y != null && x != null && x.IsEqual(y.Value(), _precision); + } + + public int GetHashCode(T obj) + { + return obj.Value().GetHashCode(); + } + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs b/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs index c359576129196aa0df3820d5cba2d619d3876bd7..a4b749e7a08c396e8f1f0f3106fa611f5ad7e149 100644 --- a/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs +++ b/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs @@ -14,14 +14,37 @@ namespace TUGraz.VectoCommon.Utils _units = units; } - public static implicit operator double(ConvertedSI self) + protected bool Equals(ConvertedSI other) + { + return _value.Equals(other._value) && string.Equals(_units, other._units); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((ConvertedSI)obj); + } + + public override int GetHashCode() + { + unchecked { + return (_value.GetHashCode() * 397) ^ (_units != null ? _units.GetHashCode() : 0); + } + } + + public static implicit operator double(ConvertedSI self) { return self._value; } public static implicit operator ConvertedSI(SI self) { - return new ConvertedSI(self.Value(), self.GetUnitString()); + return self == null ? null : new ConvertedSI(self.Value(), self.GetUnitString()); } public override string ToString() @@ -41,94 +64,92 @@ namespace TUGraz.VectoCommon.Utils private const int Kilo = 1000; private const int SecondsPerHour = 60 * 60; - public static ConvertedSI ConvertToGramm(this SI value) + public static ConvertedSI ConvertToGramm(this Kilogram value) { return new ConvertedSI(value.Value() * Kilo, "g"); } - public static ConvertedSI ConvertToTon(this SI value) + public static ConvertedSI ConvertToTon(this Kilogram value) { - return new ConvertedSI(value.Value() * Kilo, "Ton"); + return new ConvertedSI(value.Value() / Kilo, "Ton"); } - public static ConvertedSI ConvertToKiloMeterPerHour(this SI value) + public static ConvertedSI ConvertToKiloMeterPerHour(this MeterPerSecond value) { return new ConvertedSI(value.Value() * SecondsPerHour / Kilo, "km/h"); } - public static ConvertedSI ConvertToGrammPerKiloMeter(this SI value) + public static ConvertedSI ConvertToGrammPerKiloMeter(this KilogramPerMeter value) { - return value == null ? null : new ConvertedSI(value.Value() * Kilo / Kilo, "g/km"); + return value == null ? null : new ConvertedSI(value.Value() * Kilo * Kilo, "g/km"); } public static ConvertedSI ConvertToLiterPer100Kilometer(this SI value) { - return new ConvertedSI(value.Value() * (10*10*10) / (100*1000), "l/100km"); + return value == null ? null : new ConvertedSI(value.Value() * (10*10*10) / (100*1000), "l/100km"); } public static ConvertedSI ConvertToLiterPer100TonKiloMeter(this SI value) { const int CubicMeterToLiter = 10 * 10 * 10; - const int MeterTo100KiloMeter = 100 * 1000; - const int KilogrammToTon = 1000; - return new ConvertedSI(value.Value() * CubicMeterToLiter / (MeterTo100KiloMeter * KilogrammToTon), "l/100tkm"); - } + const int MeterTo100KiloMeter = 100 * Kilo; + const int KilogrammToTon = Kilo; + return value == null ? null : new ConvertedSI(value.Value() * CubicMeterToLiter / (MeterTo100KiloMeter * KilogrammToTon), "l/100tkm"); + } - - public static ConvertedSI ConvertToLiterPerCubicMeter100KiloMeter(this SI value) + public static ConvertedSI ConvertToLiterPerCubicMeter100KiloMeter(this SI value) { const int CubicMeterToLiter = 10 * 10 * 10; - const int MeterTo100KiloMeter = 100 * 1000; + const int MeterTo100KiloMeter = 100 * Kilo; return new ConvertedSI(value.Value() * CubicMeterToLiter / MeterTo100KiloMeter, "l/100m^3km"); } - public static ConvertedSI ConvertToGrammPerHour(this SI value) + public static ConvertedSI ConvertToGrammPerHour(this KilogramPerSecond value) { - return new ConvertedSI(value.Value() * Kilo / SecondsPerHour, "g/h"); + return new ConvertedSI(value.Value() * Kilo * SecondsPerHour, "g/h"); } - public static ConvertedSI ConvertToKiloMeter(this SI value) + public static ConvertedSI ConvertToKiloMeter(this Meter value) { - return new ConvertedSI(value.Value() / Kilo, "km"); + return new ConvertedSI(value.Value() / Kilo, "km"); } - public static ConvertedSI ConvertToCubicCentiMeter(this SI value) + public static ConvertedSI ConvertToCubicCentiMeter(this CubicMeter value) { return new ConvertedSI(value.Value() * 100 * 100 * 100, "cm^3"); } public static ConvertedSI ConvertToGrammPerCubicMeterKiloMeter(this SI value) { - return new ConvertedSI(value.Value() * Kilo / Kilo * Kilo / Kilo / Kilo / Kilo, "g/m^3km"); + return new ConvertedSI(value.Value() * Kilo * Kilo, "g/m^3km"); } public static ConvertedSI ConvertToGrammPerTonKilometer(this SI value) { - return new ConvertedSI(value.Value() * Kilo / Kilo * Kilo, "g/tkm"); + return new ConvertedSI(value.Value() * Kilo * Kilo * Kilo, "g/tkm"); } - - + public static ConvertedSI ConvertToLiterPer100KiloMeter(this SI value) { return new ConvertedSI(value.Value() * 10 * 10 * 10 * 100 * Kilo, "l/100km"); } - public static ConvertedSI ConvertToKiloWattHour(this SI value) + public static ConvertedSI ConvertToKiloWattHour(this WattSecond value) { return new ConvertedSI(value.Value() / Kilo / SecondsPerHour, "kWh"); } - public static ConvertedSI ConvertToKiloWatt(this SI value) + public static ConvertedSI ConvertToKiloWatt(this Watt value) { return new ConvertedSI(value.Value() / Kilo, "kW"); } - public static ConvertedSI ConvertToRoundsPerMinute(this SI value) + public static ConvertedSI ConvertToRoundsPerMinute(this PerSecond value) { return new ConvertedSI(value.Value() * 2 * Math.PI / 60, "rpm"); } - public static ConvertedSI ConvertToCubicDeziMeter(this SI value) + public static ConvertedSI ConvertToCubicDeziMeter(this CubicMeter value) { return new ConvertedSI(value.Value() * 10 * 10 * 10, "dm^3"); } - public static ConvertedSI ConvertToMilliMeter(this SI value) + public static ConvertedSI ConvertToMilliMeter(this Meter value) { return new ConvertedSI(value.Value() * Kilo, "mm"); } diff --git a/VectoCommon/VectoCommon/Utils/SIUtils.cs b/VectoCommon/VectoCommon/Utils/SIUtils.cs index fa0e23b123ad01db94a8d31b45c9fb54e013d120..7cd4d30dcb5dfb3a18540bce25d561b744084cb9 100644 --- a/VectoCommon/VectoCommon/Utils/SIUtils.cs +++ b/VectoCommon/VectoCommon/Utils/SIUtils.cs @@ -2,394 +2,366 @@ namespace TUGraz.VectoCommon.Utils { - public struct SIUtils - { - public static bool CompareUnits(int[] units1, int[] units2) - { - for (var i = 0; i < units1.Length; i++) - { - if (units1[i] != units2[i]) - { - return false; - } - } - return true; - } - - public static int[] CombineUnits(int[] units1, int[] units2) - { - var units = new int[units1.Length]; - for (var i = 0; i < units1.Length; i++) - { - units[i] = units1[i] + units2[i]; - } - return units; - - } - - public static int[] MultiplyUnits(int[] units, int factor) - { - var result = new int[units.Length]; - for (var i = 0; i < units.Length; i++) - { - if (units[i] != 0) - { - result[i] = units[i] * factor; - } - } - return result; - } - } - - - public struct Unit - { - // TODO mk-2017-09-14: must be exact the same definition as in the SI class - find a way to de-duplicate this - private static readonly string[] Unitnames = { "kg", "m", "s", "A", "K", "mol", "cd" }; - - public static UnitInstance SI - { - get - { - return new UnitInstance(new[] { 0, 0, 0, 0, 0, 0, 0 }, 1, 1, 1); - } - } - - public static string GetUnitString(int[] siUnitParam) - { - var numerator = ""; - var denominator = ""; - - for (var i = 0; i < siUnitParam.Length; i++) - { - var currentValue = siUnitParam[i]; - - var exponent = Math.Abs(currentValue); - var exponentStr = ""; - if (currentValue != 0) - { - var currentUnit = Unitnames[i]; - - if (exponent > 1) - { - exponentStr = "^" + exponent; - } - - if (currentValue > 0) - { - numerator += currentUnit + exponentStr; - - } - else if (currentValue < 0) - { - denominator += currentUnit + exponentStr; - } - } - } - string result; - - if (numerator == "") - { - if (denominator == "") - { - result = "-"; - } - else - { - result = "1/" + denominator; - } - } - else - { - if (denominator == "") - { - result = numerator; - } - else - { - result = numerator + "/" + denominator; - } - } - - return result; - } - } - - public struct UnitInstance - { - /// <summary> - /// kg, m, s, A, K, mol, cd - /// </summary> - private readonly int[] _units; - - private int _exponent; - private int _reciproc; - - public double Factor { get; private set; } - - public UnitInstance(int[] units, double factor, int exponent, int reciproc) - { - _units = units; - Factor = factor; - _exponent = exponent; - _reciproc = reciproc; - } - - public int[] GetSIUnits() - { - return _units; - } - - /// <summary> - /// [g] (to basic unit: [kg]) - /// </summary> - public UnitInstance Gramm - { - get - { - _units[0] += 1 * _reciproc * _exponent; - - // division because kg is the base unit (g/1000 = kg) - Factor /= Math.Pow(1000, _reciproc * _exponent); - - // todo mk-2017-10-02: visual studio displays wrong units - check if still not working - return this; - } - } - - /// <summary> - /// Takes all following terms as cubic terms (=to the power of 3). - /// </summary> - public UnitInstance Cubic - { - get - { - _exponent = 3; - return this; - } - } - - /// <summary> - /// [s] Converts to/from Second. Internally everything is stored in seconds. - /// </summary> - public UnitInstance Hour - { - get - { - var reciprocAndExponent = _reciproc * _exponent; - _units[2] += 1 * reciprocAndExponent; - - Factor *= Math.Pow(3600, reciprocAndExponent); - - return this; - } - } - - /// <summary> - /// Quantifier for Kilo (1000). - /// </summary> - public UnitInstance Kilo - { - get - { - Factor *= Math.Pow(1000, _exponent * _reciproc); - - return this; - } - } - - /// <summary> - /// [m] - /// </summary> - public UnitInstance Meter - { - get - { - _units[1] += 1 * _reciproc * _exponent; - return this; - } - } - - /// <summary> - /// Quantifier for milli (1/1000). - /// </summary> - public UnitInstance Milli - { - get - { - Factor /= Math.Pow(1000, _exponent * _reciproc); - return this; - } - } - - /// <summary> - /// Quantifier for Centi (1/100) - /// </summary> - public UnitInstance Centi - { - get - { - Factor /= Math.Pow(100, _exponent * _reciproc); - return this; - } - } - - /// <summary> - /// Quantifier for Dezi (1/10) - /// </summary> - public UnitInstance Dezi - { - get - { - Factor /= Math.Pow(10, _exponent * _reciproc); - return this; - } - } - - /// <summary> - /// [s] Converts to/from Second. Internally everything is stored in seconds. - /// </summary> - public UnitInstance Minute - { - get - { - var reciprocAndExponent = _reciproc * _exponent; - _units[2] += 1 * reciprocAndExponent; - Factor *= Math.Pow(60, reciprocAndExponent); - return this; - } - } - - /// <summary> - /// [N] - /// </summary> - public UnitInstance Newton - { - get - { - var reciprocAndExponent = _reciproc * _exponent; - _units[0] += 1 * reciprocAndExponent; - _units[1] += 1 * reciprocAndExponent; - _units[2] -= 2 * reciprocAndExponent; - - return this; - } - } - - /// <summary> - /// Defines the denominator by the terms following after the Per. - /// </summary> - public UnitInstance Per - { - get - { - _exponent = 1; - _reciproc = _reciproc * -1; - return this; - } - } - - /// <summary> - /// [-]. Defines radian. Only virtual. Has no real SI unit. - /// </summary> - public UnitInstance Radian - { - get - { - return this; - } - } - - /// <summary> - /// [-]. Converts to/from Radiant. Internally everything is stored in radian. - /// </summary> - public UnitInstance Rounds - { - get - { - Factor *= Math.Pow(2 * Math.PI, _exponent * _reciproc); - return this; - } - } - - /// <summary> - /// [s] - /// </summary> - public UnitInstance Second - { - get - { - _units[2] += 1 * _reciproc * _exponent; - return this; - } - } - - /// <summary> - /// Takes all following terms as quadratic terms (=to the power of 2). - /// </summary> - public UnitInstance Square - { - get - { - _exponent = 2; - return this; - } - } - - /// <summary> - /// [t] (to basic unit: [kg]) - /// </summary> - public UnitInstance Ton - { - get - { - var reciprocAndExponent = _reciproc * _exponent; - _units[0] += 1 * reciprocAndExponent; - Factor *= Math.Pow(1000, reciprocAndExponent); - - return this; - } - } - - /// <summary> - /// [W] - /// </summary> - public UnitInstance Watt - { - get - { - var reciprocAndExponent = _reciproc * _exponent; - _units[0] += 1 * reciprocAndExponent; - _units[1] += 2 * reciprocAndExponent; - _units[2] -= 3 * reciprocAndExponent; - - return this; - } - } - public UnitInstance Joule - { - get - { - var reciprocAndExponent = _reciproc * _exponent; - _units[0] += 1 * reciprocAndExponent; - _units[1] += 2 * reciprocAndExponent; - _units[2] -= 2 * reciprocAndExponent; - - return this; - } - } - - public UnitInstance Liter - { - get - { - - var reciprocAndExponent = _reciproc * _exponent; - _units[1] += 3 * reciprocAndExponent; - Factor /= Math.Pow(1000, reciprocAndExponent); - - return this; - } - } - } -} + public struct SIUtils + { + public static bool CompareUnits(int[] units1, int[] units2) + { + for (var i = 0; i < units1.Length; i++) { + if (units1[i] != units2[i]) { + return false; + } + } + return true; + } + + public static int[] CombineUnits(int[] units1, int[] units2) + { + var units = new int[units1.Length]; + for (var i = 0; i < units1.Length; i++) { + units[i] = units1[i] + units2[i]; + } + return units; + } + + public static int[] MultiplyUnits(int[] units, int factor) + { + var result = new int[units.Length]; + for (var i = 0; i < units.Length; i++) { + if (units[i] != 0) { + result[i] = units[i] * factor; + } + } + return result; + } + } + + + public struct Unit + { + // TODO mk-2017-09-14: must be exact the same definition as in the SI class - find a way to de-duplicate this + private static readonly string[] Unitnames = { "kg", "m", "s", "A", "K", "mol", "cd" }; + + public static UnitInstance SI + { + get { return new UnitInstance(new[] { 0, 0, 0, 0, 0, 0, 0 }, 1, 1, 1); } + } + + public static string GetUnitString(int[] siUnitParam) + { + var numerator = ""; + var denominator = ""; + + for (var i = 0; i < siUnitParam.Length; i++) { + var currentValue = siUnitParam[i]; + + var exponent = Math.Abs(currentValue); + var exponentStr = ""; + if (currentValue != 0) { + var currentUnit = Unitnames[i]; + + if (exponent > 1) { + exponentStr = "^" + exponent; + } + + if (currentValue > 0) { + numerator += currentUnit + exponentStr; + } else if (currentValue < 0) { + denominator += currentUnit + exponentStr; + } + } + } + string result; + + if (numerator == "") { + if (denominator == "") { + result = "-"; + } else { + result = "1/" + denominator; + } + } else { + if (denominator == "") { + result = numerator; + } else { + result = numerator + "/" + denominator; + } + } + + return result; + } + } + + public struct UnitInstance + { + /// <summary> + /// kg, m, s, A, K, mol, cd + /// </summary> + private readonly int[] _units; + + private int _exponent; + private int _reciproc; + + public double Factor { get; private set; } + + public UnitInstance(int[] units, double factor, int exponent, int reciproc) + { + _units = units; + Factor = factor; + _exponent = exponent; + _reciproc = reciproc; + } + + public int[] GetSIUnits() + { + return _units; + } + + /// <summary> + /// [g] (to basic unit: [kg]) + /// </summary> + public UnitInstance Gramm + { + get + { + _units[0] += 1 * _reciproc * _exponent; + + // division because kg is the base unit (g/1000 = kg) + Factor /= Math.Pow(1000, _reciproc * _exponent); + + // todo mk-2017-10-02: visual studio displays wrong units - check if still not working + return this; + } + } + + /// <summary> + /// Takes all following terms as cubic terms (=to the power of 3). + /// </summary> + public UnitInstance Cubic + { + get + { + _exponent = 3; + return this; + } + } + + /// <summary> + /// [s] Converts to/from Second. Internally everything is stored in seconds. + /// </summary> + public UnitInstance Hour + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[2] += 1 * reciprocAndExponent; + + Factor *= Math.Pow(3600, reciprocAndExponent); + + return this; + } + } + + /// <summary> + /// Quantifier for Kilo (1000). + /// </summary> + public UnitInstance Kilo + { + get + { + Factor *= Math.Pow(1000, _exponent * _reciproc); + + return this; + } + } + + /// <summary> + /// [m] + /// </summary> + public UnitInstance Meter + { + get + { + _units[1] += 1 * _reciproc * _exponent; + return this; + } + } + + /// <summary> + /// Quantifier for milli (1/1000). + /// </summary> + public UnitInstance Milli + { + get + { + Factor /= Math.Pow(1000, _exponent * _reciproc); + return this; + } + } + + /// <summary> + /// Quantifier for Centi (1/100) + /// </summary> + public UnitInstance Centi + { + get + { + Factor /= Math.Pow(100, _exponent * _reciproc); + return this; + } + } + + /// <summary> + /// Quantifier for Dezi (1/10) + /// </summary> + public UnitInstance Dezi + { + get + { + Factor /= Math.Pow(10, _exponent * _reciproc); + return this; + } + } + + /// <summary> + /// [s] Converts to/from Second. Internally everything is stored in seconds. + /// </summary> + public UnitInstance Minute + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[2] += 1 * reciprocAndExponent; + Factor *= Math.Pow(60, reciprocAndExponent); + return this; + } + } + + /// <summary> + /// [N] + /// </summary> + public UnitInstance Newton + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[0] += 1 * reciprocAndExponent; + _units[1] += 1 * reciprocAndExponent; + _units[2] -= 2 * reciprocAndExponent; + + return this; + } + } + + /// <summary> + /// Defines the denominator by the terms following after the Per. + /// </summary> + public UnitInstance Per + { + get + { + _exponent = 1; + _reciproc = _reciproc * -1; + return this; + } + } + + /// <summary> + /// [-]. Defines radian. Only virtual. Has no real SI unit. + /// </summary> + public UnitInstance Radian + { + get { return this; } + } + + /// <summary> + /// [-]. Converts to/from Radiant. Internally everything is stored in radian. + /// </summary> + public UnitInstance Rounds + { + get + { + Factor *= Math.Pow(2 * Math.PI, _exponent * _reciproc); + return this; + } + } + + /// <summary> + /// [s] + /// </summary> + public UnitInstance Second + { + get + { + _units[2] += 1 * _reciproc * _exponent; + return this; + } + } + + /// <summary> + /// Takes all following terms as quadratic terms (=to the power of 2). + /// </summary> + public UnitInstance Square + { + get + { + _exponent = 2; + return this; + } + } + + /// <summary> + /// [t] (to basic unit: [kg]) + /// </summary> + public UnitInstance Ton + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[0] += 1 * reciprocAndExponent; + Factor *= Math.Pow(1000, reciprocAndExponent); + + return this; + } + } + + /// <summary> + /// [W] + /// </summary> + public UnitInstance Watt + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[0] += 1 * reciprocAndExponent; + _units[1] += 2 * reciprocAndExponent; + _units[2] -= 3 * reciprocAndExponent; + + return this; + } + } + + public UnitInstance Joule + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[0] += 1 * reciprocAndExponent; + _units[1] += 2 * reciprocAndExponent; + _units[2] -= 2 * reciprocAndExponent; + + return this; + } + } + + public UnitInstance Liter + { + get + { + var reciprocAndExponent = _reciproc * _exponent; + _units[1] += 3 * reciprocAndExponent; + Factor /= Math.Pow(1000, reciprocAndExponent); + + return this; + } + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index 3453cecea02487128f864c49de8e765afc24a850..bff31b09126e7a747289744894f02b9eb48de98b 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -213,15 +213,15 @@ namespace TUGraz.VectoCore.OutputData Tuple.Create(VIN_NUMBER, typeof(string)), Tuple.Create(VEHICLE_MODEL, typeof(string)), Tuple.Create(HDV_CO2_VEHICLE_CLASS, typeof(string)), - Tuple.Create(CURB_MASS, typeof(SI)), - Tuple.Create(LOADING, typeof(SI)), - Tuple.Create(TOTAL_VEHICLE_MASS, typeof(SI)), + Tuple.Create(CURB_MASS, typeof(ConvertedSI)), + Tuple.Create(LOADING, typeof(ConvertedSI)), + Tuple.Create(TOTAL_VEHICLE_MASS, typeof(ConvertedSI)), Tuple.Create(ENGINE_MANUFACTURER, typeof(string)), Tuple.Create(ENGINE_MODEL, typeof(string)), Tuple.Create(ENGINE_FUEL_TYPE, typeof(string)), Tuple.Create(ENGINE_RATED_POWER, typeof(ConvertedSI)), - Tuple.Create(ENGINE_IDLING_SPEED, typeof(SI)), - Tuple.Create(ENGINE_RATED_SPEED, typeof(SI)), + Tuple.Create(ENGINE_IDLING_SPEED, typeof(ConvertedSI)), + Tuple.Create(ENGINE_RATED_SPEED, typeof(ConvertedSI)), Tuple.Create(ENGINE_DISPLACEMENT, typeof(ConvertedSI)), Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)), Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)), @@ -229,19 +229,19 @@ namespace TUGraz.VectoCore.OutputData Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)), Tuple.Create(ENGINE_CF_REG_PER, typeof(double)), Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)), - Tuple.Create(CD_x_A_DECLARED, typeof(SI)), - Tuple.Create(CD_x_A, typeof(SI)), + Tuple.Create(CD_x_A_DECLARED, typeof(ConvertedSI)), + Tuple.Create(CD_x_A, typeof(ConvertedSI)), Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)), Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)), - Tuple.Create(R_DYN, typeof(SI)), + Tuple.Create(R_DYN, typeof(ConvertedSI)), Tuple.Create(NUM_AXLES_DRIVEN, typeof(int)), Tuple.Create(NUM_AXLES_NON_DRIVEN, typeof(int)), Tuple.Create(NUM_AXLES_TRAILER, typeof(int)), Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)), Tuple.Create(GEARBOX_MODEL, typeof(string)), Tuple.Create(GEARBOX_TYPE, typeof(string)), - Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(SI)), - Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(SI)), + Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(ConvertedSI)), + Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(ConvertedSI)), Tuple.Create(TORQUECONVERTER_MANUFACTURER, typeof(string)), Tuple.Create(TORQUECONVERTER_MODEL, typeof(string)), Tuple.Create(RETARDER_MANUFACTURER, typeof(string)), @@ -252,7 +252,7 @@ namespace TUGraz.VectoCore.OutputData Tuple.Create(ANGLEDRIVE_RATIO, typeof(string)), Tuple.Create(AXLE_MANUFACTURER, typeof(string)), Tuple.Create(AXLE_MODEL, typeof(string)), - Tuple.Create(AXLE_RATIO, typeof(SI)), + Tuple.Create(AXLE_RATIO, typeof(ConvertedSI)), Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.SteeringPump), typeof(string)), Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.Fan), typeof(string)), Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition), @@ -279,7 +279,7 @@ namespace TUGraz.VectoCore.OutputData ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS, STOP_TIMESHARE, ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE - }.Select(x => new DataColumn(x)).ToArray()); + }.Select(x => new DataColumn(x, typeof(ConvertedSI))).ToArray()); } /// <summary> @@ -328,7 +328,7 @@ namespace TUGraz.VectoCore.OutputData var totalTime = modData.Duration(); - row[TIME] = totalTime; + row[TIME] = (ConvertedSI)totalTime; var distance = modData.Distance(); if (distance != null) { @@ -340,7 +340,7 @@ namespace TUGraz.VectoCore.OutputData row[SPEED] = speed.ConvertToKiloMeterPerHour(); } - row[ALTITUDE_DELTA] = modData.AltitudeDelta(); + row[ALTITUDE_DELTA] = (ConvertedSI)modData.AltitudeDelta(); WriteFuelconsumptionEntries(modData, row, vehicleLoading, cargoVolume); @@ -365,9 +365,9 @@ namespace TUGraz.VectoCore.OutputData WritePerformanceEntries(modData, row); - row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare(); - row[COASTING_TIME_SHARE] = modData.CoastingTimeShare(); - row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare(); + row[ENGINE_FULL_LOAD_TIME_SHARE] = (ConvertedSI)modData.EngineMaxLoadTimeShare(); + row[COASTING_TIME_SHARE] = (ConvertedSI)modData.CoastingTimeShare(); + row[BRAKING_TIME_SHARE] = (ConvertedSI)modData.BrakingTimeShare(); if (gearCount <= 0) { return; @@ -379,7 +379,8 @@ namespace TUGraz.VectoCore.OutputData private static void WriteFuelconsumptionEntries(IModalDataContainer modData, DataRow row, Kilogram vehicleLoading, CubicMeter cargoVolume) { - row[FCMAP_H] = modData.FCMapPerSecond().ConvertToGrammPerHour(); + var tmp = modData.FCMapPerSecond(); + row[FCMAP_H] = tmp.ConvertToGrammPerHour(); var fcMapPerMeter = modData.FCMapPerMeter(); if (fcMapPerMeter != null) { row[FCMAP_KM] = fcMapPerMeter.ConvertToGrammPerKiloMeter(); @@ -434,37 +435,37 @@ namespace TUGraz.VectoCore.OutputData private void WriteGearshiftStats(IModalDataContainer modData, DataRow row, uint gearCount) { - row[NUM_GEARSHIFTS] = modData.GearshiftCount(); + row[NUM_GEARSHIFTS] = (ConvertedSI)modData.GearshiftCount(); var timeSharePerGear = modData.TimeSharePerGear(gearCount); for (uint i = 0; i <= gearCount; i++) { var colName = string.Format(TIME_SHARE_PER_GEAR_FORMAT, i); if (!Table.Columns.Contains(colName)) { - Table.Columns.Add(colName, typeof(SI)); + Table.Columns.Add(colName, typeof(ConvertedSI)); } - row[colName] = timeSharePerGear[i]; + row[colName] = (ConvertedSI)timeSharePerGear[i]; } } private void WritePerformanceEntries(IModalDataContainer modData, DataRow row) { - row[ACC] = modData.AccelerationAverage(); - row[ACC_POS] = modData.AccelerationsPositive(); - row[ACC_NEG] = modData.AccelerationsNegative(); + row[ACC] = (ConvertedSI)modData.AccelerationAverage(); + row[ACC_POS] = (ConvertedSI)modData.AccelerationsPositive(); + row[ACC_NEG] = (ConvertedSI)modData.AccelerationsNegative(); var accTimeShare = modData.AccelerationTimeShare(); - row[ACC_TIMESHARE] = accTimeShare; + row[ACC_TIMESHARE] = (ConvertedSI)accTimeShare; var decTimeShare = modData.DecelerationTimeShare(); - row[DEC_TIMESHARE] = decTimeShare; + row[DEC_TIMESHARE] = (ConvertedSI)decTimeShare; var cruiseTimeShare = modData.CruiseTimeShare(); - row[CRUISE_TIMESHARE] = cruiseTimeShare; + row[CRUISE_TIMESHARE] = (ConvertedSI)cruiseTimeShare; var stopTimeShare = modData.StopTimeShare(); - row[STOP_TIMESHARE] = stopTimeShare; + row[STOP_TIMESHARE] = (ConvertedSI)stopTimeShare; - row[MAX_SPEED] = modData.MaxSpeed().AsKmph.SI<Scalar>(); - row[MAX_ACCELERATION] = modData.MaxAcceleration(); - row[MAX_DECELERATION] = modData.MaxDeceleration(); - row[AVG_ENGINE_SPEED] = modData.AvgEngineSpeed().AsRPM.SI<Scalar>(); - row[MAX_ENGINE_SPEED] = modData.MaxEngineSpeed().AsRPM.SI<Scalar>(); + row[MAX_SPEED] = (ConvertedSI)modData.MaxSpeed().AsKmph.SI<Scalar>(); + row[MAX_ACCELERATION] = (ConvertedSI)modData.MaxAcceleration(); + row[MAX_DECELERATION] = (ConvertedSI)modData.MaxDeceleration(); + row[AVG_ENGINE_SPEED] = (ConvertedSI)modData.AvgEngineSpeed().AsRPM.SI<Scalar>(); + row[MAX_ENGINE_SPEED] = (ConvertedSI)modData.MaxEngineSpeed().AsRPM.SI<Scalar>(); if (accTimeShare != null && decTimeShare != null && cruiseTimeShare != null) { var shareSum = accTimeShare + decTimeShare + cruiseTimeShare + stopTimeShare; if (!shareSum.IsEqual(100)) { @@ -504,22 +505,22 @@ namespace TUGraz.VectoCore.OutputData row[VEHICLE_MODEL] = runData.VehicleData.ModelName; row[HDV_CO2_VEHICLE_CLASS] = runData.VehicleData.VehicleClass.GetClassNumber(); - row[CURB_MASS] = runData.VehicleData.CurbWeight; + row[CURB_MASS] = (ConvertedSI)runData.VehicleData.CurbWeight; // - (runData.VehicleData.BodyAndTrailerWeight ?? 0.SI<Kilogram>()); - row[LOADING] = runData.VehicleData.Loading; - row[CARGO_VOLUME] = runData.VehicleData.CargoVolume; + row[LOADING] = (ConvertedSI)runData.VehicleData.Loading; + row[CARGO_VOLUME] = (ConvertedSI)runData.VehicleData.CargoVolume; - row[TOTAL_VEHICLE_MASS] = runData.VehicleData.TotalVehicleWeight; + row[TOTAL_VEHICLE_MASS] = (ConvertedSI)runData.VehicleData.TotalVehicleWeight; row[ENGINE_MANUFACTURER] = runData.EngineData.Manufacturer; row[ENGINE_MODEL] = runData.EngineData.ModelName; row[ENGINE_FUEL_TYPE] = runData.EngineData.FuelType.GetLabel(); row[ENGINE_RATED_POWER] = runData.EngineData.RatedPowerDeclared != null && runData.EngineData.RatedPowerDeclared > 0 ? runData.EngineData.RatedPowerDeclared.ConvertToKiloWatt() : runData.EngineData.FullLoadCurves[0].MaxPower.ConvertToKiloWatt(); - row[ENGINE_IDLING_SPEED] = runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>(); + row[ENGINE_IDLING_SPEED] = (ConvertedSI)runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>(); row[ENGINE_RATED_SPEED] = runData.EngineData.RatedSpeedDeclared != null && runData.EngineData.RatedSpeedDeclared > 0 - ? runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>() - : runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>(); + ? (ConvertedSI)runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>() + : (ConvertedSI)runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>(); row[ENGINE_DISPLACEMENT] = runData.EngineData.Displacement.ConvertToCubicCentiMeter(); row[ENGINE_WHTC_URBAN] = runData.EngineData.WHTCUrban; @@ -529,15 +530,15 @@ namespace TUGraz.VectoCore.OutputData row[ENGINE_CF_REG_PER] = runData.EngineData.CorrectionFactorRegPer; row[ENGINE_ACTUAL_CORRECTION_FACTOR] = runData.EngineData.FuelConsumptionCorrectionFactor; - row[CD_x_A_DECLARED] = runData.AirdragData.DeclaredAirdragArea; - row[CD_x_A] = runData.AirdragData.CrossWindCorrectionCurve.AirDragArea; + row[CD_x_A_DECLARED] = (ConvertedSI)runData.AirdragData.DeclaredAirdragArea; + row[CD_x_A] = (ConvertedSI)runData.AirdragData.CrossWindCorrectionCurve.AirDragArea; row[ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER] = runData.VehicleData.RollResistanceCoefficientWithoutTrailer; row[ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER] = runData.VehicleData.TotalRollResistanceCoefficient; - row[R_DYN] = runData.VehicleData.DynamicTyreRadius; + row[R_DYN] = (ConvertedSI)runData.VehicleData.DynamicTyreRadius; row[NUM_AXLES_DRIVEN] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.VehicleDriven); row[NUM_AXLES_NON_DRIVEN] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.VehicleNonDriven); @@ -555,7 +556,7 @@ namespace TUGraz.VectoCore.OutputData row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer; row[AXLE_MODEL] = runData.AxleGearData.ModelName; - row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>(); + row[AXLE_RATIO] = (ConvertedSI)runData.AxleGearData.AxleGear.Ratio.SI<Scalar>(); WriteAuxTechnologies(runData, row); } @@ -607,21 +608,21 @@ namespace TUGraz.VectoCore.OutputData if (runData.GearboxData.Type.AutomaticTransmission()) { row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0 ? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio) - ? runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>() - : runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()) + ? (ConvertedSI)runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>() + : (ConvertedSI)runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()) : 0.SI<Scalar>(); row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() - : 0.SI<Scalar>(); + ? (ConvertedSI)runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() + : (ConvertedSI)0.SI<Scalar>(); row[TORQUECONVERTER_MANUFACTURER] = runData.GearboxData.TorqueConverterData.Manufacturer; row[TORQUECONVERTER_MODEL] = runData.GearboxData.TorqueConverterData.ModelName; } else { row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>() - : 0.SI<Scalar>(); + ? (ConvertedSI)runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>() + : (ConvertedSI)0.SI<Scalar>(); row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0 - ? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() - : 0.SI<Scalar>(); + ? (ConvertedSI)runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>() + : (ConvertedSI)0.SI<Scalar>(); row[TORQUECONVERTER_MANUFACTURER] = "n.a."; row[TORQUECONVERTER_MODEL] = "n.a."; } diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs index e4e0424d43247641cffe273f42187cd4a1e5aafa..3ada562901f4d4fd6c179d111a767eeb6009eae5 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -30,6 +30,7 @@ */ using System.Collections.Generic; +using System.IO; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; @@ -56,6 +57,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation [TestFixture] public class AuxTests { + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); + } + + [TestCase] public void AuxWriteModFileSumFile() diff --git a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs index ac977d06fe545c00dc27e69177aea85d9e315cd4..74e110abf6e45279baae1caad1593f22e302c185 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs @@ -54,6 +54,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation [TestFixture] public class PwheelModeTests { + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); + } + + /// <summary> /// Test if the cycle file can be read. /// </summary> diff --git a/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs index 196fdd87338c1e209576bc6d1e5406ef9bf6dddd..858bd32ff7172abdd7bc6e2e3ebb97f6c6ab75ee 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.IO; using System.Linq; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; @@ -47,6 +48,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation { private const string EngineOnlyJob = @"TestData\Jobs\EngineOnlyJob.vecto"; + + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory); + } + + [TestCase] public void TestSimulationEngineOnly() { diff --git a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs index 5b9852f05ce667107ffa6fd1cbecb57cd7f839e7..27ca18ea03da34607bfb867b28b66eb6b4537076 100644 --- a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs +++ b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs @@ -156,36 +156,36 @@ namespace TUGraz.VectoCore.Tests.Reports var inputFile = row[SummaryDataContainer.INPUTFILE].ToString(); var cycle = row[SummaryDataContainer.CYCLE].ToString(); var loading = row[SummaryDataContainer.LOADING].ToString(); - var eFcMapPos = ((SI)row[SummaryDataContainer.E_FCMAP_POS]).Value(); - var eFcMapNeg = ((SI)row[SummaryDataContainer.E_FCMAP_NEG]).Value(); - var ePowertrainInertia = ((SI)row[SummaryDataContainer.E_POWERTRAIN_INERTIA]).Value(); - var eAux = ((SI)row[SummaryDataContainer.E_AUX]).Value(); - var eClutchLoss = ((SI)row[SummaryDataContainer.E_CLUTCH_LOSS]).Value(); - var eTcLoss = ((SI)row[SummaryDataContainer.E_TC_LOSS]).Value(); - //var eShiftLoss = ((SI)row[SummaryDataContainer.E_SHIFT_LOSS]).Value(); - var eGbxLoss = ((SI)row[SummaryDataContainer.E_GBX_LOSS]).Value(); - var eRetLoss = ((SI)row[SummaryDataContainer.E_RET_LOSS]).Value(); - var eAngleLoss = ((SI)row[SummaryDataContainer.E_ANGLE_LOSS]).Value(); - var eAxlLoss = ((SI)row[SummaryDataContainer.E_AXL_LOSS]).Value(); - var eBrakeLoss = ((SI)row[SummaryDataContainer.E_BRAKE]).Value(); - var eVehInertia = ((SI)row[SummaryDataContainer.E_VEHICLE_INERTIA]).Value(); - var eAir = ((SI)row[SummaryDataContainer.E_AIR]).Value(); - var eRoll = ((SI)row[SummaryDataContainer.E_ROLL]).Value(); - var eGrad = ((SI)row[SummaryDataContainer.E_GRAD]).Value(); - var cargoVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CARGO_VOLUME]).Value(); - - var loadingValue = ((SI)row[SummaryDataContainer.LOADING]).Value() / 1000; - var fcPer100km = ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]).Value(); + var eFcMapPos = ((ConvertedSI)row[SummaryDataContainer.E_FCMAP_POS]); + var eFcMapNeg = ((ConvertedSI)row[SummaryDataContainer.E_FCMAP_NEG]); + var ePowertrainInertia = ((ConvertedSI)row[SummaryDataContainer.E_POWERTRAIN_INERTIA]); + var eAux = ((ConvertedSI)row[SummaryDataContainer.E_AUX]); + var eClutchLoss = ((ConvertedSI)row[SummaryDataContainer.E_CLUTCH_LOSS]); + var eTcLoss = ((ConvertedSI)row[SummaryDataContainer.E_TC_LOSS]); + //var eShiftLoss = ((SI)row[SummaryDataContainer.E_SHIFT_LOSS]); + var eGbxLoss = ((ConvertedSI)row[SummaryDataContainer.E_GBX_LOSS]); + var eRetLoss = ((ConvertedSI)row[SummaryDataContainer.E_RET_LOSS]); + var eAngleLoss = ((ConvertedSI)row[SummaryDataContainer.E_ANGLE_LOSS]); + var eAxlLoss = ((ConvertedSI)row[SummaryDataContainer.E_AXL_LOSS]); + var eBrakeLoss = ((ConvertedSI)row[SummaryDataContainer.E_BRAKE]); + var eVehInertia = ((ConvertedSI)row[SummaryDataContainer.E_VEHICLE_INERTIA]); + var eAir = ((ConvertedSI)row[SummaryDataContainer.E_AIR]); + var eRoll = ((ConvertedSI)row[SummaryDataContainer.E_ROLL]); + var eGrad = ((ConvertedSI)row[SummaryDataContainer.E_GRAD]); + var cargoVolume = mode == ExecutionMode.Engineering ? 0.0 : ((ConvertedSI)row[SummaryDataContainer.CARGO_VOLUME]); + + var loadingValue = ((ConvertedSI)row[SummaryDataContainer.LOADING]) / 1000; + var fcPer100km = ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]); var fcPerVolume = mode == ExecutionMode.Engineering - ? 0 - : ((SI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]).Value(); - var fcPerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]).Value() : 0; - var co2Per100km = ((SI)row[SummaryDataContainer.CO2_KM]).Value(); - var co2PerVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CO2_M3KM]).Value(); - var co2PerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.CO2_TKM]).Value() : 0; + ? 0.0 + : ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]); + var fcPerLoad = loadingValue > 0 ? ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]) : 0.0; + var co2PerKm = ((ConvertedSI)row[SummaryDataContainer.CO2_KM]); + var co2PerVolume = mode == ExecutionMode.Engineering ? 0.0 : ((ConvertedSI)row[SummaryDataContainer.CO2_M3KM]); + var co2PerLoad = loadingValue > 0 ? ((ConvertedSI)row[SummaryDataContainer.CO2_TKM]) : 0.0; - var ePTOtransm = ptoTransmissionColumn != null ? ((SI)row[ptoTransmissionColumn]).Value() : 0; - var ePTOconsumer = ptoConsumerColumn != null ? ((SI)row[ptoConsumerColumn]).Value() : 0; + var ePTOtransm = ptoTransmissionColumn != null ? ((ConvertedSI)row[ptoTransmissionColumn]) : 0.0; + var ePTOconsumer = ptoConsumerColumn != null ? ((ConvertedSI)row[ptoConsumerColumn]) : 0.0; // E_fcmap_pos = E_fcmap_neg + E_powertrain_inertia + E_aux_xxx + E_aux_sum + E_clutch_loss + E_tc_loss + E_gbx_loss + E_shift_loss + E_ret_loss + E_angle_loss + E_axl_loss + E_brake + E_vehicle_inertia + E_air + E_roll + E_grad + E_PTO_CONSUM + E_PTO_TRANSM Assert.AreEqual(eFcMapPos, @@ -194,8 +194,8 @@ namespace TUGraz.VectoCore.Tests.Reports "input file: {0} cycle: {1} loading: {2}", inputFile, cycle, loading); - var pFcmapPos = ((SI)row[SummaryDataContainer.P_FCMAP_POS]).Value(); - var time = ((SI)row[SummaryDataContainer.TIME]).Value(); + var pFcmapPos = ((ConvertedSI)row[SummaryDataContainer.P_FCMAP_POS]); + var time = ((ConvertedSI)row[SummaryDataContainer.TIME]); // E_fcmap_pos = P_fcmap_pos * t Assert.AreEqual(eFcMapPos, pFcmapPos * (time / 3600), 1e-3, "input file: {0} cycle: {1} loading: {2}", inputFile, @@ -205,30 +205,30 @@ namespace TUGraz.VectoCore.Tests.Reports Assert.AreEqual(fcPerVolume, fcPer100km / cargoVolume, 1e-3, "input file: {0} cycle: {1} loading: {2}", inputFile, cycle, loading); - Assert.AreEqual(co2PerVolume, co2Per100km / cargoVolume, 1e-3, "input file: {0} cycle: {1} loading: {2}", + Assert.AreEqual(co2PerVolume, co2PerKm / cargoVolume, 1e-3, "input file: {0} cycle: {1} loading: {2}", inputFile, cycle, loading); } if (loadingValue > 0) { - Assert.AreEqual(co2PerLoad, co2Per100km / loadingValue, 1e-3, "input file: {0} cycle: {1} loading: {2}", + Assert.AreEqual(co2PerLoad, co2PerKm / loadingValue, 1e-3, "input file: {0} cycle: {1} loading: {2}", inputFile, cycle, loading); Assert.AreEqual(fcPerLoad, fcPer100km / loadingValue, 1e-3, "input file: {0} cycle: {1} loading: {2}", inputFile, cycle, loading); } - var stopTimeShare = ((SI)row[SummaryDataContainer.STOP_TIMESHARE]).Value(); - var accTimeShare = ((SI)row[SummaryDataContainer.ACC_TIMESHARE]).Value(); - var decTimeShare = ((SI)row[SummaryDataContainer.DEC_TIMESHARE]).Value(); - var cruiseTimeShare = ((SI)row[SummaryDataContainer.CRUISE_TIMESHARE]).Value(); + var stopTimeShare = ((ConvertedSI)row[SummaryDataContainer.STOP_TIMESHARE]); + var accTimeShare = ((ConvertedSI)row[SummaryDataContainer.ACC_TIMESHARE]); + var decTimeShare = ((ConvertedSI)row[SummaryDataContainer.DEC_TIMESHARE]); + var cruiseTimeShare = ((ConvertedSI)row[SummaryDataContainer.CRUISE_TIMESHARE]); Assert.AreEqual(100, stopTimeShare + accTimeShare + decTimeShare + cruiseTimeShare, 1e-3, "input file: {0} cycle: {1} loading: {2}", inputFile, cycle, loading); - Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_POS]).Value() > 0); - Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_NEG]).Value() < 0); + Assert.IsTrue(((ConvertedSI)row[SummaryDataContainer.ACC_POS]) > 0); + Assert.IsTrue(((ConvertedSI)row[SummaryDataContainer.ACC_NEG]) < 0); - var gearshifts = ((SI)row[SummaryDataContainer.NUM_GEARSHIFTS]).Value(); + var gearshifts = ((ConvertedSI)row[SummaryDataContainer.NUM_GEARSHIFTS]); Assert.IsTrue(gearshifts > 0); //var acc = ((SI)row[SummaryDataContainer.ACC]).Value(); diff --git a/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs b/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs index 5730cb9139071d9026911e2a9463eebcfa9009a5..32689fe80a08e147ac45d5a66b4d9769ee8877cc 100644 --- a/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs +++ b/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs @@ -193,14 +193,14 @@ namespace TUGraz.VectoCore.Tests.Reports Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.Manufacturer, sumRow[SummaryDataContainer.ENGINE_MANUFACTURER]); Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.Model, sumRow[SummaryDataContainer.ENGINE_MODEL]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.RatedPowerDeclared.ConvertToKiloWatt(), + Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.FuelType.ToXMLFormat(), sumRow[SummaryDataContainer.ENGINE_FUEL_TYPE]); Assert.AreEqual((dataProvider.JobInputData.Vehicle.EngineInputData.RatedPowerDeclared.ConvertToKiloWatt()), - ((SI)sumRow[SummaryDataContainer.ENGINE_RATED_POWER]).Value()); + ((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_RATED_POWER])); Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.RatedSpeedDeclared.AsRPM, - ((SI)sumRow[SummaryDataContainer.ENGINE_RATED_SPEED]).Value()); + (double)((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_RATED_SPEED])); Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.Displacement.ConvertToCubicCentiMeter(), - ((SI)sumRow[SummaryDataContainer.ENGINE_DISPLACEMENT]).Value()); + ((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_DISPLACEMENT])); Assert.AreEqual(dataProvider.JobInputData.Vehicle.GearboxInputData.Manufacturer, sumRow[SummaryDataContainer.GEARBOX_MANUFACTURER]); Assert.AreEqual(dataProvider.JobInputData.Vehicle.GearboxInputData.Model, sumRow[SummaryDataContainer.GEARBOX_MODEL]); diff --git a/VectoCore/VectoCoreTest/Utils/SITest.cs b/VectoCore/VectoCoreTest/Utils/SITest.cs index 886ac427fe60626ce9cc1984c4d5518661559cc0..31c01ccfcfa0ba59844ac7a83a545a4b23aa598d 100644 --- a/VectoCore/VectoCoreTest/Utils/SITest.cs +++ b/VectoCore/VectoCoreTest/Utils/SITest.cs @@ -195,8 +195,8 @@ namespace TUGraz.VectoCore.Tests.Utils Assert.AreEqual(1, 0.SI().CompareTo(null)); Assert.AreEqual(1, 0.SI().CompareTo("not an SI")); - Assert.AreEqual(-1, new SI(Unit.SI.Meter).CompareTo(new SI(Unit.SI.Kilo.Meter.Per.Hour))); - Assert.AreEqual(1, new SI(Unit.SI.Newton.Meter).CompareTo(new SI(Unit.SI.Meter))); + Assert.AreEqual(-1, new SI(Unit.SI.Meter).CompareTo(new SI(Unit.SI.Kilo.Meter.Per.Hour))); + Assert.AreEqual(1, new SI(Unit.SI.Newton.Meter).CompareTo(new SI(Unit.SI.Meter))); Assert.AreEqual(0, 1.SI().CompareTo(1.SI())); Assert.AreEqual(-1, 1.SI().CompareTo(2.SI())); @@ -331,6 +331,11 @@ namespace TUGraz.VectoCore.Tests.Utils AssertHelper.AreRelativeEqual(perSecond, watt / newtonMeter); AssertHelper.AreRelativeEqual(second, newtonMeter / watt); + + + AssertHelper.AreRelativeEqual(2.SI<NormLiterPerSecond>(), 2.SI<NormLiterPerSecond>() / 1); + + AssertHelper.AreRelativeEqual(2.SI<NormLiterPerSecond>(), 2.SI<NormLiterPerSecond>() * 1); } [TestCase] @@ -352,7 +357,7 @@ namespace TUGraz.VectoCore.Tests.Utils AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Gramm.Square.Meter.Per.Cubic.Second), 3.SI<Watt>()); AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Gramm.Meter.Per.Square.Second), 3.SI<Newton>()); AssertHelper.AreRelativeEqual(3000.SI(Unit.SI.Kilo.Gramm), 3.SI(Unit.SI.Ton)); - AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Kilo.Gramm).ConvertToTon(), 3000.SI(Unit.SI.Kilo.Gramm).ConvertToTon()); + AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Kilo.Gramm).Cast<Kilogram>().ConvertToTon(), 3000.SI(Unit.SI.Kilo.Gramm).Cast<Kilogram>().ConvertToTon()); AssertHelper.AreRelativeEqual(3.SI<Meter>(), 3000.SI(Unit.SI.Milli.Meter)); @@ -550,31 +555,37 @@ namespace TUGraz.VectoCore.Tests.Utils Assert.AreEqual("m^3", 1.SI().GetUnitString(uni2.GetSIUnits())); AssertHelper.AreRelativeEqual(0.000001, uni2.Factor); - var val2 = 7.SI(Unit.SI.Cubic.Dezi.Meter).ConvertToCubicDeziMeter(); - AssertHelper.AreRelativeEqual(0.007, val2); - - var val3 = 5.SI(Unit.SI.Cubic.Dezi.Meter).ConvertToCubicCentiMeter(); - AssertHelper.AreRelativeEqual(0.005, val3); // 5000 cm^3 - - var val4 = 5.SI(Unit.SI.Cubic.Centi.Meter).ConvertToCubicDeziMeter(); - AssertHelper.AreRelativeEqual(0.000005, val4); // 0.005 dm^3 - - var uni1 = Unit.SI.Kilo.Meter.Per.Hour; + var uni1 = Unit.SI.Kilo.Meter.Per.Hour; Assert.AreEqual("m/s", 1.SI().GetUnitString(uni1.GetSIUnits())); AssertHelper.AreRelativeEqual(0.2777777777, uni1.Factor); NewtonMeter newtonMeter = 5.SI<NewtonMeter>(); AssertHelper.AreRelativeEqual(5.SI(Unit.SI.Newton.Meter), newtonMeter); AssertHelper.AreRelativeEqual(5.SI(Unit.SI.Meter.Newton), newtonMeter); - } - [TestCase] + AssertHelper.AreRelativeEqual(5.SI<Liter>(), 1.SI<Second>() * 5.SI<LiterPerSecond>()); + + AssertHelper.AreRelativeEqual((6.0/3600).SI<Liter>(), (2.SI<Second>() * 3.SI(Unit.SI.Liter.Per.Hour)).Cast<Liter>()); + + AssertHelper.AreRelativeEqual(2.13093, 2.13093.SI(Unit.SI.Liter).Cast<Liter>().Value()); + Assert.AreEqual("m^3", 2.13093.SI(Unit.SI.Liter).GetUnitString()); + } + + [TestCase] public void SI_ConvertValues() { var sig1 = 5.SI(Unit.SI.Gramm); Assert.AreEqual(0.005, sig1.Value()); - - } + + var val2 = 7.SI(Unit.SI.Cubic.Dezi.Meter).Cast<CubicMeter>().ConvertToCubicDeziMeter(); + AssertHelper.AreRelativeEqual(7, val2); + + var val3 = 5.SI(Unit.SI.Cubic.Dezi.Meter).Cast<CubicMeter>().ConvertToCubicCentiMeter(); + AssertHelper.AreRelativeEqual(5000, val3); // 5000 cm^3 + + var val4 = 5.SI(Unit.SI.Cubic.Centi.Meter).Cast<CubicMeter>().ConvertToCubicDeziMeter(); + AssertHelper.AreRelativeEqual(0.005, val4); // 0.005 dm^3 + } }