From ee52ba82e14a4d28ca6bc82221ade7f477390ebd Mon Sep 17 00:00:00 2001
From: stefan meyer <stefan.meyer@student.tugraz.at>
Date: Tue, 29 Aug 2017 20:21:38 +0200
Subject: [PATCH] bug fixed the refactored SI units

---
 .../VectoCommon/Utils/IntExtensionMethods.cs  |  18 ++-
 VectoCommon/VectoCommon/Utils/SI.cs           |  87 +++++--------
 VectoCommon/VectoCommon/Utils/SIUtils.cs      | 114 ++++++------------
 .../OutputData/IModalDataContainer.cs         |   3 +-
 VectoCore/VectoCoreTest/Utils/SITest.cs       |  33 +++--
 5 files changed, 105 insertions(+), 150 deletions(-)

diff --git a/VectoCommon/VectoCommon/Utils/IntExtensionMethods.cs b/VectoCommon/VectoCommon/Utils/IntExtensionMethods.cs
index 512b4b9fb6..ef260fb7b5 100644
--- a/VectoCommon/VectoCommon/Utils/IntExtensionMethods.cs
+++ b/VectoCommon/VectoCommon/Utils/IntExtensionMethods.cs
@@ -45,12 +45,18 @@ namespace TUGraz.VectoCommon.Utils
 			return new SI(value);
 		}
 
-		/// <summary>
-		/// Gets the special SI class of the number.
-		/// </summary>
-		/// <param name="d"></param>
-		/// <returns></returns>
-		[DebuggerHidden]
+
+        public static SI SI(this int value, UnitInstance si)
+        {
+            return new SI(value, si);
+        }
+
+        /// <summary>
+        /// Gets the special SI class of the number.
+        /// </summary>
+        /// <param name="d"></param>
+        /// <returns></returns>
+        [DebuggerHidden]
 		public static T SI<T>(this int d) where T : SIBase<T>
 		{
 			return SIBase<T>.Create(d);
diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs
index aebe68b69e..4e4aedc637 100644
--- a/VectoCommon/VectoCommon/Utils/SI.cs
+++ b/VectoCommon/VectoCommon/Utils/SI.cs
@@ -1150,6 +1150,8 @@ namespace TUGraz.VectoCommon.Utils
             }
         }
 
+	    public SI(double val, UnitInstance si) : this(val, si.GetSIUnits()){}
+
         /// <summary>
         /// Initializes a new instance of the <see cref="SI"/> class which copies the units from an already existing SI.
         /// </summary>
@@ -1159,7 +1161,7 @@ namespace TUGraz.VectoCommon.Utils
         private SI(double val, SI unit) : this(val, unit.SIUnits){}
 
         //[DebuggerHidden]
-        protected SI(SI si, double? factor = null, int[] siUnitsParm = null,
+        protected SI(SI si, double? factor = null, int[] siUnitsParam = null,
             bool? reciproc = null, bool? reverse = null, int? exponent = null)
         {
 
@@ -1169,46 +1171,39 @@ namespace TUGraz.VectoCommon.Utils
             _exponent = exponent ?? si._exponent;
 
 
-            if (siUnitsParm == null) //////////////????
+            if (siUnitsParam == null) //////////////????
             {
-                siUnitsParm = new int[] { 0, 0, 0, 0, 0, 0, 0 };
+                siUnitsParam = new int[] { 0, 0, 0, 0, 0, 0, 0 };
             }
 
             if (_reciproc)
             {
-                siUnitsParm = SIUtils.SIUnitsMultFactor(siUnitsParm, -1); 
+                siUnitsParam = SIUtils.SIUnitsMultFactor(siUnitsParam, -1); 
             }
 
             if (_reverse)
             {
-                if (_reciproc)
-                {
-                    //factor = 1 / factor;
-                    factor = 1 / factor;
-                }
-
-                if (!SIUtils.CompareSIUnits(siUnitsParm, si.SIUnits))
+                // compare the si Units
+                if (!SIUtils.CompareSIUnits(siUnitsParam, si.SIUnits))
                 {
                     throw new VectoException(
                         "Unit missing. Conversion not possible. [{0}] does not contain a [{1}].",
-                        "gg1", "gg2");
+                        GetUnitString(siUnitsParam), si.GetUnitString());
                 }
 
                 SIUnits = si.SIUnits;
 
-                //throw new VectoException(
-                //    "Unit missing. Conversion not possible. [{0}] does not contain a [{1}].",
-                // string.Join(", ", units),
-                // fromUnit);
+                factor = 1 / factor;
 
-                _reverse = false;
+                //_reverse = false;
 
             }
             else
             {
-                SIUnits = SIUtils.AdditionTheSIUnits(si.SIUnits, SIUtils.SIUnitsMultFactor(siUnitsParm, _exponent));
+                SIUnits = SIUtils.AdditionTheSIUnits(si.SIUnits, SIUtils.SIUnitsMultFactor(siUnitsParam, _exponent));
             }
 
+
             if (_reciproc)
             {
                 if (factor.HasValue)
@@ -1223,11 +1218,15 @@ namespace TUGraz.VectoCommon.Utils
                 if (factor.HasValue)
                 {
                     //Val *= (factor.Value * _exponent);
-                    Val *= Math.Pow(factor.Value,_exponent);
+                    Val *= Math.Pow(factor.Value, _exponent);
                 }
             }
 
-
+            if (_reverse)
+            {
+                Val /= factor.Value;
+                _reverse = false;
+            }
 
             if (double.IsNaN(Val))
             {
@@ -1240,31 +1239,6 @@ namespace TUGraz.VectoCommon.Utils
             }
         }
 
-        /// <summary>
-        /// Adds the new toUnit to the units collection and removes the fromUnit.
-        /// </summary>
-        /// <param name="fromUnit">From unit.</param>
-        /// <param name="toUnit">To unit.</param>
-        /// 
-        /// <param name="units">The units.</param>
-        /// <exception cref="VectoException"></exception>
-        [DebuggerHidden]
-		private void UpdateUnit(Unit? fromUnit, Unit? toUnit, ICollection<Unit> units)
-		{
-			if (_reverse && fromUnit.HasValue) {
-				if (units.Contains(fromUnit.Value)) {
-					units.Remove(fromUnit.Value);
-				} else {
-					throw new VectoException("Unit missing. Conversion not possible. [{0}] does not contain a [{1}].",
-						string.Join(", ", units),
-						fromUnit);
-				}
-			}
-
-			if (toUnit.HasValue) {
-				units.Add(toUnit.Value);
-			}
-		}
 
 
 
@@ -1289,7 +1263,7 @@ namespace TUGraz.VectoCommon.Utils
 	        {
 	            factorValue *= 1000.0;
 	        }
-	        return new SI(this, siUnitsParm: si.GetSIUnits(), factor: factorValue,
+	        return new SI(this, siUnitsParam: si.GetSIUnits(), factor: factorValue,
 	            exponent: 1, reciproc: false, reverse: true);
 	    }
 
@@ -1449,7 +1423,7 @@ namespace TUGraz.VectoCommon.Utils
             [DebuggerHidden]
 		    get
             {
-                return new SI(this, siUnitsParm: new int[] { 1, 1, -2, 0, 0, 0, 0 });
+                return new SI(this, siUnitsParam: new int[] { 1, 1, -2, 0, 0, 0, 0 });
             }
 		}
 
@@ -1462,7 +1436,7 @@ namespace TUGraz.VectoCommon.Utils
             [DebuggerHidden]
             get
             {
-                return new SI(this, siUnitsParm: new int[] { 1, 2, -3, 0, 0, 0, 0 });
+                return new SI(this, siUnitsParam: new int[] { 1, 2, -3, 0, 0, 0, 0 });
             }
         }
 		/// <summary>
@@ -1474,7 +1448,7 @@ namespace TUGraz.VectoCommon.Utils
             //[DebuggerHidden]
             get
             {
-                return new SI(this, siUnitsParm: new int[] { 0, 1, 0, 0, 0, 0, 0 });
+                return new SI(this, siUnitsParam: new int[] { 0, 1, 0, 0, 0, 0, 0 });
             }
         }
 		/// <summary>
@@ -1486,7 +1460,7 @@ namespace TUGraz.VectoCommon.Utils
             [DebuggerHidden]
             get
             {
-                return new SI(this, siUnitsParm: new int[] { 0, 0, 1, 0, 0, 0, 0 });
+                return new SI(this, siUnitsParam: new int[] { 0, 0, 1, 0, 0, 0, 0 });
             }
         }
 		/// <summary>
@@ -1568,7 +1542,7 @@ namespace TUGraz.VectoCommon.Utils
             [DebuggerHidden]
 		    get
 		    {
-                return new SI(this, siUnitsParm: new int[] { 0, 0, 0, 1, 0, 0, 0 });
+                return new SI(this, siUnitsParam: new int[] { 0, 0, 0, 1, 0, 0, 0 });
             }
 		}
 
@@ -2009,16 +1983,21 @@ namespace TUGraz.VectoCommon.Utils
 		/// <summary>
 		///     Returns the Unit Part of the SI Unit Expression.
 		/// </summary>
-	    public string GetUnitString()
+	    public string GetUnitString(int[] SIUnitParam = null)
 	    {
 	        Array unitnames = Enum.GetNames(typeof(Unit));
 	        string numerator = "";
 	        string denominator = "";
 	        int potent = 0;
 	        string potentStr = "";
-	        for (var i = 0; i < SIUnits.Length; i++)
+
+            if (SIUnitParam == null)
+            {
+                SIUnitParam = SIUnits;
+            }
+	        for (var i = 0; i < SIUnitParam.Length; i++)
 	        {
-	            int currentValue = SIUnits[i];
+	            int currentValue = SIUnitParam[i];
 	            potent = Math.Abs(currentValue);
 	            potentStr = "";
 	            if (currentValue != 0)
diff --git a/VectoCommon/VectoCommon/Utils/SIUtils.cs b/VectoCommon/VectoCommon/Utils/SIUtils.cs
index 72226eeb62..47bdc67b65 100644
--- a/VectoCommon/VectoCommon/Utils/SIUtils.cs
+++ b/VectoCommon/VectoCommon/Utils/SIUtils.cs
@@ -43,6 +43,7 @@ namespace TUGraz.VectoCommon.Utils
             return resultarray;
         }
 
+        //new method
         public static int GetnumberofSIUnits(int[] array)
         {
             int resultCount = 0;
@@ -73,8 +74,8 @@ namespace TUGraz.VectoCommon.Utils
         private int[] units;
         private double factorValue;
 
-        private short exponent;
-        private short reciproc;
+        private int exponent;
+        private int reciproc;
 
         public enum GrammMode
         {
@@ -86,7 +87,7 @@ namespace TUGraz.VectoCommon.Utils
         private GrammMode grammMode;
 
         public UnitInstance(int[] param_units,
-            double param_factor, short param_exponent, short param_reciproc,
+            double param_factor, int param_exponent, int param_reciproc,
             GrammMode param_grammMode)
         {
             units = param_units;
@@ -110,42 +111,6 @@ namespace TUGraz.VectoCommon.Utils
             return factorValue;
         }
 
-        private enum Op
-        {
-            Div,
-            Mult
-        }
-
-
-        private void CalcFactorValue(Op workop, double factor)
-        {
-            if (reciproc == -1)
-            {
-                if (workop == Op.Div)
-                {
-                    factorValue *= factor;
-                }
-                else if (workop == Op.Mult)
-                {
-                    factorValue /= factor;
-                }
-            }
-            else if (reciproc == 1)
-            {
-                if (workop == Op.Div)
-                {
-                    factorValue /= factor;
-                }
-                else if (workop == Op.Mult)
-                {
-                    factorValue *= factor;
-                }
-            }
-
-        }
-
-
-
 
         public UnitInstance Gramm
         {
@@ -160,8 +125,8 @@ namespace TUGraz.VectoCommon.Utils
                     grammMode = GrammMode.KiloGramm;
                 }
                 units[0] += 1 * reciproc * exponent;
-                CalcFactorValue(Op.Div, 1000);
-                //factorValue /= 1000;
+
+                factorValue /= Math.Pow(1000, exponent * reciproc);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
                 //return this; // not work
             }
@@ -178,9 +143,10 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                units[2] += 1 * reciproc * exponent;
-                CalcFactorValue(Op.Mult, 3600);
-                //factorValue *= 3600;
+                int ReciprocAndExponent = reciproc * exponent;
+                units[2] += 1 * ReciprocAndExponent;
+
+                factorValue *= Math.Pow(3600, ReciprocAndExponent);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -196,8 +162,8 @@ namespace TUGraz.VectoCommon.Utils
                 {
                     grammMode = GrammMode.KiloGramm;
                 }
-                CalcFactorValue(Op.Mult, 1000);
-                //factorValue *= 1000;
+
+                factorValue *= Math.Pow(1000, exponent * reciproc);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -213,7 +179,6 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                //units[1] += 1 * reciproc;
                 units[1] += 1 * reciproc * exponent;
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
@@ -222,9 +187,8 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                //CalcFactorValue(Op.Div, 1000);
-                //factorValue /= 1000;
-                CalcFactorValue(Op.Mult, Math.Pow(factorValue / 1000, exponent));
+
+                factorValue /= Math.Pow(1000, exponent * reciproc);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -232,10 +196,7 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                //CalcFactorValue(Op.Div, 100);
-                //Val *= Math.Pow(factor.Value, (double)_exponent);
-                CalcFactorValue(Op.Mult, Math.Pow(factorValue/100, exponent));
-                //factorValue /= 100;
+                factorValue /= Math.Pow(100, exponent * reciproc);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -243,9 +204,7 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                //CalcFactorValue(Op.Div, 10);
-                //factorValue /= 10;
-                CalcFactorValue(Op.Mult, Math.Pow(factorValue / 10, exponent));
+                factorValue /= Math.Pow(10, exponent * reciproc);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -253,9 +212,10 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                units[2] += 1 * reciproc * exponent;
-                CalcFactorValue(Op.Mult, 60);
-                //factorValue *= 60;
+                int ReciprocAndExponent = reciproc * exponent;
+                units[2] += 1 * ReciprocAndExponent;
+
+                factorValue *= Math.Pow(60, ReciprocAndExponent);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -263,9 +223,10 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                units[0] += 1 * reciproc * exponent;
-                units[1] += 1 * reciproc * exponent;
-                units[2] -= 2 * reciproc * exponent;
+                int ReciprocAndExponent = reciproc * exponent;
+                units[0] += 1 * ReciprocAndExponent;
+                units[1] += 1 * ReciprocAndExponent;
+                units[2] -= 2 * ReciprocAndExponent;
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -273,15 +234,8 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                //this = Linear;
-                //Linear;
-
                 exponent = 1;
-
-
-                reciproc = (short)(reciproc * (-1));
-
-                //units = SIUtils.SIUnitsMultFactor(units, -1);
+                reciproc = reciproc * (-1);
 
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
                 //return this;
@@ -298,8 +252,7 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                CalcFactorValue(Op.Mult, 2 * Math.PI);
-                //factorValue *= 2 * Math.PI;
+                factorValue *= Math.Pow(2 * Math.PI, exponent * reciproc);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -315,7 +268,7 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                exponent = (short)(2 * reciproc);
+                exponent = 2 * reciproc;
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -323,8 +276,9 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                units[0] += 1 * reciproc * exponent;
-                CalcFactorValue(Op.Mult, 1000);
+                int ReciprocAndExponent = reciproc * exponent;
+                units[0] += 1 * ReciprocAndExponent;
+                factorValue *= Math.Pow(1000, ReciprocAndExponent);
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -332,9 +286,10 @@ namespace TUGraz.VectoCommon.Utils
         {
             get
             {
-                units[0] += 1 * reciproc * exponent;
-                units[1] += 2 * reciproc * exponent;
-                units[2] -= 3 * reciproc * exponent;
+                int ReciprocAndExponent = reciproc * exponent;
+                units[0] += 1 * ReciprocAndExponent;
+                units[1] += 2 * ReciprocAndExponent;
+                units[2] -= 3 * ReciprocAndExponent;
                 return new UnitInstance(units, factorValue, exponent, reciproc, grammMode);
             }
         }
@@ -342,5 +297,4 @@ namespace TUGraz.VectoCommon.Utils
 
     }
 
-
 }
diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
index de04515e88..2015599aa8 100644
--- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
@@ -373,8 +373,9 @@ namespace TUGraz.VectoCore.OutputData
 			}
 
 			var fcVolumePerMeter = fuelConsumptionFinal / data.FuelData.FuelDensity;
+            // fcVolumePerMeter = [m^2]
             //return fcVolumePerMeter.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter;
-		    return fcVolumePerMeter.ConvertTo(Unit.SI.Cubic.Dezi.Meter) * 100.SI().Kilo.Meter;
+            return fcVolumePerMeter.ConvertTo(Unit.SI.Square.Dezi.Meter) * 100.SI().Kilo.Meter;
         }
 
 		public static KilogramPerMeter CO2PerMeter(this IModalDataContainer data)
diff --git a/VectoCore/VectoCoreTest/Utils/SITest.cs b/VectoCore/VectoCoreTest/Utils/SITest.cs
index bd802fbabf..3b24ad01f9 100644
--- a/VectoCore/VectoCoreTest/Utils/SITest.cs
+++ b/VectoCore/VectoCoreTest/Utils/SITest.cs
@@ -81,7 +81,7 @@ namespace TUGraz.VectoCore.Tests.Utils
             //add
             PerSecond angVeloSum = 600.RPMtoRad() + 400.SI<PerSecond>();
             AssertHelper.AreRelativeEqual(600 * 2 * Math.PI / 60 + 400, angVeloSum);
-            AssertHelper.Exception<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; });
+            AssertHelper.Exception<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton;});
 
             //subtract
             PerSecond angVeloDiff = 600.RPMtoRad() - 400.SI<PerSecond>();
@@ -109,7 +109,9 @@ namespace TUGraz.VectoCore.Tests.Utils
 
             // ConvertTo only allows conversion if the units are correct.
             //AssertHelper.Exception<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo().Watt; });
-            AssertHelper.Exception<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo(Unit.SI.Watt); });
+            AssertHelper.Exception<VectoException>(() => {
+                var x = 40.SI<Newton>().ConvertTo(Unit.SI.Watt);
+            });
             //var res1 = 40.SI<Newton>().ConvertTo().Newton;
             var res1 = 40.SI<Newton>().ConvertTo(Unit.SI.Newton);
 
@@ -576,19 +578,32 @@ namespace TUGraz.VectoCore.Tests.Utils
         public void SI_NewTests()
         {
             var val1 = 5.SI().Cubic.Dezi.Meter;
-            Assert.AreEqual("m^3", val1.GetUnitString());
-            AssertHelper.AreRelativeEqual(0.005, val1);
-
+            Assert.AreEqual("0.0050 [m^3]", val1.ToOutputFormat(showUnit: true));
 
             var uni = Unit.SI.Cubic.Dezi.Meter;
-            Assert.AreEqual(3, uni.GetSIUnits()[1]); //cubic meter
+            Assert.AreEqual("m^3", 1.SI().GetUnitString(uni.GetSIUnits())); 
             AssertHelper.AreRelativeEqual(0.001, uni.Getfactor());
 
+            var val2 = 7.SI().Cubic.Dezi.Meter.ConvertTo(Unit.SI.Cubic.Dezi.Meter);
+            Assert.AreEqual("0.0070 [m^3]", val2.ToOutputFormat(showUnit: true));
+
+            var val3 = 5.SI().Cubic.Dezi.Meter.ConvertTo(Unit.SI.Cubic.Centi.Meter);
+            Assert.AreEqual("0.0050 [m^3]", val3.ToOutputFormat(showUnit: true));
+
+            var val4 = 5.SI().Cubic.Centi.Meter.ConvertTo(Unit.SI.Cubic.Dezi.Meter);
+            Assert.AreEqual("0.000005 [m^3]", val4.ToOutputFormat(6,showUnit: true));
+
+
+            var uni1 = Unit.SI.Kilo.Meter.Per.Hour;
+            Assert.AreEqual("m/s", 1.SI().GetUnitString(uni1.GetSIUnits()));
+            AssertHelper.AreRelativeEqual(0.2777777777, uni1.Getfactor());
+
+
+            NewtonMeter newtonMeter = 5.SI<NewtonMeter>();
+            AssertHelper.AreRelativeEqual(5.SI(Unit.SI.Newton.Meter), newtonMeter);
+            AssertHelper.AreRelativeEqual(5.SI(Unit.SI.Meter.Newton), newtonMeter);
 
 
-            var val2 = 7.SI().Cubic.Dezi.Meter.ConvertTo(Unit.SI.Cubic.Dezi.Meter);
-            Assert.AreEqual("m^3", val2.GetUnitString());
-            Assert.AreEqual(0.0007, val2.Value());
         }
     }
 
-- 
GitLab