From ea87381bae75d18d227d4f858b495ca31eb5e834 Mon Sep 17 00:00:00 2001 From: LFLaverty Date: Mon, 22 Apr 2024 15:10:24 +0100 Subject: [PATCH 1/2] adds support & unit tests for multiple fuel types --- .../CalculatorTests.cs | 164 +++++++++++++++++- .../Models/CalculationResult.cs | 37 +++- .../ShipCarbonIntensityCalculator.cs | 90 +++++++++- .../Program.cs | 58 +++++++ README.md | 13 +- 5 files changed, 348 insertions(+), 14 deletions(-) diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs index ae0666b..825bdfc 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs @@ -16,15 +16,15 @@ public class CalculatorTests /// Tests a known and pre-calculated set of inputs for a RoRoPassengerShip /// [TestMethod] - public void TestCalculator() + public void TestCalculatorSingleFuel() { var _calc = new ShipCarbonIntensityCalculator(); var result = _calc.CalculateAttainedCiiRating( - ShipType.RoRoPassengerShip, - grossTonnage: 25000, - deadweightTonnage: 0, - distanceTravelled: 150000, + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, TypeOfFuel.DIESEL_OR_GASOIL, fuelConsumption: 1.9e+10, 2019 @@ -42,6 +42,78 @@ public void TestCalculator() Assert.IsTrue(result.Results.Count(result => result.IsEstimatedYear) == 11); } + /// + /// Tests a known and pre-calculated set of inputs for a RoRoPassengerShip in the multi-fuel scenario + /// + [TestMethod] + public void TestCalculatorMultiFuel() + { + var _calc = new ShipCarbonIntensityCalculator(); + + var result = _calc.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, + new List { + new FuelTypeConsumption + { + FuelConsumption = 1.9e+10, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + } + }, + 2019 + ); + + System.Diagnostics.Debug.WriteLine("Basic result is:"); + + string json = JsonConvert.SerializeObject(result, Formatting.Indented); + System.Diagnostics.Debug.WriteLine(json); + + Assert.IsNotNull(result); + Assert.AreEqual(result.Results.Count(), 12); + + Assert.IsTrue(result.Results.Count(result => result.IsMeasuredYear) == 1); + Assert.IsTrue(result.Results.Count(result => result.IsEstimatedYear) == 11); + } + + + [TestMethod] + public void TestCalculatorMultiFuelSameResultAsSingleFuel() + { + var _calc = new ShipCarbonIntensityCalculator(); + + var resultMultiFuel = _calc.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, + new List { + new FuelTypeConsumption + { + FuelConsumption = 1.9e+10, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + } + }, + 2019 + ); + + var resultSingleFuel = _calc.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, + TypeOfFuel.DIESEL_OR_GASOIL, + fuelConsumption: 1.9e+10, + 2019 + ); + + var singleFuelAsJsonObj = JsonConvert.SerializeObject(resultSingleFuel); + var multiFuelAsJsonObj = JsonConvert.SerializeObject(resultMultiFuel); + + Assert.AreEqual(singleFuelAsJsonObj, multiFuelAsJsonObj); + } + /// @@ -141,7 +213,7 @@ public void TestRoRoPassengerShipReturnsExpectedValues( [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2029, ImoCiiRating.E, 7.240951252672751, 8.549333333333333)] [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2030, ImoCiiRating.E, 7.0664704995963, 8.549333333333333)] [TestMethod] - public void TestBulkCarrierReturnsExpectedValues( + public void TestMultiFuelBulkCarrierReturnsExpectedValues( ShipType shipType, double deadweightTonnage, double grossTonnage, @@ -184,5 +256,85 @@ public void TestBulkCarrierReturnsExpectedValues( Assert.AreEqual(result.Results.First(c => c.Year == year).Rating, expectedRating, $"{nameof(expectedRating)} value was incorrect"); Assert.AreNotEqual(result.Results.First(c => c.Year == year).IsMeasuredYear, result.Results.First(c => c.Year == year).IsEstimatedYear); } + + + + + + + /// + /// Tests a known and pre-calculated set of inputs for a RoRoPassengerShip in the multi-fuel scenario + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2019, ImoCiiRating.C, 8.724037653822592, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2020, ImoCiiRating.C, 8.636797277284366, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2021, ImoCiiRating.C, 8.54955690074614, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2022, ImoCiiRating.C, 8.462316524207914, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2023, ImoCiiRating.C, 8.287835771131462, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2024, ImoCiiRating.C, 8.11335501805501, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2025, ImoCiiRating.D, 7.938874264978558, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2026, ImoCiiRating.D, 7.764393511902107, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2027, ImoCiiRating.D, 7.589912758825655, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2028, ImoCiiRating.D, 7.415432005749203, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2029, ImoCiiRating.E, 7.240951252672751, 8.549333333333333)] + [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2030, ImoCiiRating.E, 7.0664704995963, 8.549333333333333)] + [TestMethod] + public void TestBulkCarrierReturnsExpectedValues( + ShipType shipType, + double deadweightTonnage, + double grossTonnage, + TypeOfFuel typeOfFuel, + double fuelConsumptionInGrams, + int year, + ImoCiiRating expectedRating, + double expectedRequiredCii, + double expectedAttainedCii) + { + double expectedArRatio = expectedAttainedCii / expectedRequiredCii; + + var _calc = new ShipCarbonIntensityCalculator(); + + var result = _calc.CalculateAttainedCiiRating( + shipType, + grossTonnage: grossTonnage, + deadweightTonnage: deadweightTonnage, + distanceTravelled: 150000, + new List { + new FuelTypeConsumption + { + FuelConsumption = fuelConsumptionInGrams, + FuelType = typeOfFuel + } + }, + year + ); + + + string json = JsonConvert.SerializeObject(result, Formatting.Indented); + System.Diagnostics.Debug.WriteLine(json); + + Assert.IsNotNull(result); + Assert.AreEqual(result.Results.Count(), 12); + + Assert.IsTrue(result.Results.Count(result => result.IsMeasuredYear) == 1); + Assert.IsTrue(result.Results.Count(result => result.IsEstimatedYear) == 11); + + Assert.AreEqual(result.Results.First(c => c.Year == year).Year, year, $"{nameof(year)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).VectorBoundariesForYear.ShipType, shipType, $"{nameof(shipType)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).RequiredCii, expectedRequiredCii, $"{nameof(expectedRequiredCii)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedRequiredRatio, expectedArRatio, $"{nameof(expectedArRatio)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedCii, expectedAttainedCii, $"{nameof(expectedAttainedCii)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).Rating, expectedRating, $"{nameof(expectedRating)} value was incorrect"); + Assert.AreNotEqual(result.Results.First(c => c.Year == year).IsMeasuredYear, result.Results.First(c => c.Year == year).IsEstimatedYear); + } } } diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Models/CalculationResult.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Models/CalculationResult.cs index cf311bb..6f5939a 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Models/CalculationResult.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Models/CalculationResult.cs @@ -14,10 +14,9 @@ public class CalculationResult public CalculationResult(IEnumerable results) { Results = results; + } - - /// /// Contains a collection of CII Ratings for each year /// between 2019 and 2030 @@ -35,6 +34,11 @@ public class ResultYear /// /// if true, the CII rating, and all other values are measured /// if false, the CII rating, and all other values are estimates + /// + /// If true, the , , and + /// will all be generated against this year. If false, these + /// properties are equivalent to the most recent year data was provided for (for example, if this year is + /// 2026, and data exists for 2020 and 2021, the properties will match the 2021 data). /// public bool IsMeasuredYear { get; set; } @@ -45,11 +49,40 @@ public class ResultYear /// if false, the CII rating, and all other values are measured /// public bool IsEstimatedYear { get { return !IsMeasuredYear; } } + + /// + /// The year this result references + /// public int Year { get; set; } + + /// + /// The ship's IMO CII Rating, from A to E + /// public ImoCiiRating Rating { get; set; } + + /// + /// The ship's required carbon intensity for this year + /// public double RequiredCii { get; set; } + + /// + /// The ship's attained Carbon Intensity Indicator for this year + /// public double AttainedCii { get; set; } + /// + /// The Co2e Emissions calculated for this year + /// + public double CalculatedCo2eEmissions { get; set; } + /// + /// The Ship Capacity calculated for this year + /// + public double CalculatedShipCapacity { get; set; } + /// + /// The Transport Work calculated for this year + /// + public double CalculatedTransportWork { get; set; } + /// /// This is the ratio of Attained:Required CII /// diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/ShipCarbonIntensityCalculator.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/ShipCarbonIntensityCalculator.cs index 8814b8e..ce02ccc 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/ShipCarbonIntensityCalculator.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/ShipCarbonIntensityCalculator.cs @@ -4,6 +4,8 @@ using EtiveMor.OpenImoCiiCalculator.Core.Models.MeasurementModels; using EtiveMor.OpenImoCiiCalculator.Core.Services; using EtiveMor.OpenImoCiiCalculator.Core.Services.Impl; +using System.Security.Cryptography.X509Certificates; +using Microsoft.VisualBasic.FileIO; namespace EtiveMor.OpenImoCiiCalculator.Core { @@ -26,15 +28,80 @@ public ShipCarbonIntensityCalculator() } /// + /// Calculate the attained CII rating for a ship for a given year /// + /// This method accepts multiple fuel types. /// - /// + /// The type of ship /// in long-tons /// in long-tons /// distance travelled in nautical miles - /// + /// The type of fuel /// quantity of fuel consumed in grams - /// + /// + /// A containing details of the ship's carbon intensity rating + /// + public CalculationResult CalculateAttainedCiiRating( + ShipType shipType, + double grossTonnage, + double deadweightTonnage, + double distanceTravelled, + IEnumerable fuelTypeConsumptions, + int targetYear) + { + if (fuelTypeConsumptions == null || fuelTypeConsumptions.Count() == 0) + { + throw new ArgumentException("FuelTypeConsumptions must be provided"); + } + double shipCo2Emissions = 0; + foreach (var consumption in fuelTypeConsumptions) + { + shipCo2Emissions += _shipMassOfCo2EmissionsService.GetMassOfCo2Emissions(consumption.FuelType, consumption.FuelConsumption); + } + var shipCapacity = _shipCapacityService.GetShipCapacity(shipType, deadweightTonnage, grossTonnage); + var transportWork = _shipTransportWorkService.GetShipTransportWork(shipCapacity, distanceTravelled); + + List results = new List(); + for (int year = 2019; year <= 2030; year++) + { + var attainedCiiInYear = _carbonIntensityIndicatorService.GetAttainedCarbonIntensity(shipCo2Emissions, transportWork); + var requiredCiiInYear = _carbonIntensityIndicatorService.GetRequiredCarbonIntensity(shipType, shipCapacity, year); + + var vectors = _ratingBoundariesService.GetBoundaries(new Ship(shipType, deadweightTonnage, grossTonnage), requiredCiiInYear, year); + var rating = GetImoCiiRatingFromVectors(vectors, attainedCiiInYear, year); + + results.Add(new ResultYear + { + IsMeasuredYear = targetYear == year, + Year = year, + AttainedCii = attainedCiiInYear, + RequiredCii = requiredCiiInYear, + Rating = rating, + VectorBoundariesForYear = vectors, + CalculatedCo2eEmissions = shipCo2Emissions, + CalculatedShipCapacity = shipCapacity, + CalculatedTransportWork = transportWork + }); + } + + return new CalculationResult(results); + } + + /// + /// Calculate the attained CII rating for a ship for a given year + /// + /// This method accepts exactly one fuel type. For multiple fuel + /// types, use the method + /// + /// The type of ship + /// in long-tons + /// in long-tons + /// distance travelled in nautical miles + /// The type of fuel + /// quantity of fuel consumed in grams + /// + /// A containing details of the ship's carbon intensity rating + /// public CalculationResult CalculateAttainedCiiRating( ShipType shipType, double grossTonnage, @@ -64,7 +131,10 @@ public CalculationResult CalculateAttainedCiiRating( AttainedCii = attainedCiiInYear, RequiredCii = requiredCiiInYear, Rating = rating, - VectorBoundariesForYear = vectors + VectorBoundariesForYear = vectors, + CalculatedCo2eEmissions = shipCo2Emissions, + CalculatedShipCapacity = shipCapacity, + CalculatedTransportWork = transportWork }); } @@ -102,5 +172,17 @@ private ImoCiiRating GetImoCiiRatingFromVectors(ShipDdVectorBoundaries boundarie } } + + public class AnnaulConsumption + { + public int TargetYear { get; set; } + public IEnumerable FuelConsumption { get; set; } + } + + public class FuelTypeConsumption + { + public TypeOfFuel FuelType { get; set; } + public double FuelConsumption { get; set; } + } } diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs index d22043b..b048e83 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs @@ -2,12 +2,41 @@ using EtiveMor.OpenImoCiiCalculator.Core.Models.Enums; using EtiveMor.OpenImoCiiCalculator.Core.Services.Impl; using Newtonsoft.Json; +using System.Net.Http.Headers; namespace EtiveMor.OpenImoCiiCalculator.DemoConsoleApp { internal class Program { static void Main(string[] args) + { + Console.WriteLine("---------------------"); + Console.WriteLine("Generating a multi-fuel ship report..."); + Console.WriteLine("---------------------"); + + MainMultiFuelCalculation(args); + + Console.WriteLine("---------------------"); + Console.WriteLine("Completed the multi-fuel ship report..."); + Console.WriteLine("---------------------"); + + + Console.WriteLine("---------------------"); + Console.WriteLine("Generating a single-fuel ship report..."); + Console.WriteLine("---------------------"); + + MainOneFuelCalculation(args); + + Console.WriteLine("---------------------"); + Console.WriteLine("Completed the single-fuel ship report..."); + Console.WriteLine("---------------------"); + } + + /// + /// Runs the single fuel calculation with sample data + /// + /// + static void MainOneFuelCalculation(string[] args) { Console.WriteLine("Generating a ship result now..."); @@ -28,5 +57,34 @@ static void Main(string[] args) Console.WriteLine("Press any key to finish"); Console.ReadKey(); } + + + /// + /// Runs the multi-fuel calculation with sample data + /// + /// + static void MainMultiFuelCalculation(string[] args) + { + var calculator = new ShipCarbonIntensityCalculator(); + + var result = calculator.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, + new List { + new FuelTypeConsumption + { + FuelConsumption = 1.9e+10, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + } + }, + 2019); + + string json = JsonConvert.SerializeObject(result, Formatting.Indented); + Console.WriteLine(json); + Console.WriteLine("Press any key to finish"); + Console.ReadKey(); + } } } \ No newline at end of file diff --git a/README.md b/README.md index e8e54fe..c656858 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ The specification for this software can be found in [IMO's resolution MEPC.353(7 The following features are on the roadmap for the application: -- Support for multiple engines & fuel types for ships. Currently the application only considers fuel consumption by a ship's main engine. - Support for Dependency Injection (DI). Currently the application does not - Support for IMO Resolution MEPC.355(78). Currently the application considers fuel consumption only. Support for MEPC355(78) will bring additional CII properties, for example the lighting in crew quarters. @@ -80,6 +79,10 @@ int targetYear - Fuel consumption is measured in grams, and accepts scientific notation like `1.9e+10` - Year must refer to the measured year. For example, if a ship's fuel consumption is known in 2022, all other results will be based from that point +**_Multiple Fuel Type calculations_** + +That there are two CalculateAttainedCiiRating methods. One for a ship which consumes a single fuel type, and another which consumes multiple fuel types. Both methods are available at `CalculateAttainedCiiRating`. + ### Calculator Result Format ```json @@ -93,6 +96,9 @@ int targetYear "requiredCii": 19.184190519387734, "attainedCii": 16.243733333333335, "attainedRequiredRatio": 0.8467249799733408, + "calculatedCo2eEmissions": 60914000000.0, + "calculatedShipCapacity": 25000.0, + "calculatedTransportWork": 3750000000.0, "vectorBoundariesForYear": { "year": 2019, "shipType": 110, @@ -123,6 +129,9 @@ int targetYear | `requiredCii` | The actual intensity required for the ship to be considered in-range of the IMO's regulations (note that from 2027 onwards, this is a projection) | | `attainedCii` | The estimated or actual intensity attained for the ship in the given year | | `attainedRequiredRatio` | The ratio between `requiredCii` and `attainedCii` | +| `calculatedCo2eEmissions` | The calculated CO2e emissions this result was based on | +| `calculatedShipCapacity` | The calculated ship capacity this result was based on | +| `calculatedTransportWork` | The calculated transport work this result was based on | | `vectorBoundariesForYear.year` | the year in question (repeats `.year`) | | `vectorBoundariesForYear.shipType` | the type of ship `EtiveMor.OpenImoCiiCalculator.Core.Models.Enums.ShipType` | | `vectorBoundariesForYear.weightClassification` | the weight classification the ship has been considered for (see MEPC.354(78)) | @@ -254,7 +263,7 @@ Returns the product of a ship's capacity and its distance sailed ## Ship CO2 Emissions Methodology -The sum of a ship's $CO_2$ emissions over a given year are calculated by multiplying the mass of consumed fuel by the fuel's emissions factor. +The sum of a ship's $CO_2$ emissions over a given year are calculated by multiplying the mass of consumed fuel by the fuel's emissions factor. If the ship consumes multiple fuel types, the calculation is repeated for each fuel type & consumption mass, then those results are summed together. **Method Accepts**: - `fuelType`, an enum derrived from [Table 2](#table-2-mepc36479-mass-conversion-between-fuel-consumption-and-co_2-emissions)'s *Fuel Type* column From f837676684975376c29cbc8c3b484dbe76c43703 Mon Sep 17 00:00:00 2001 From: LFLaverty Date: Mon, 22 Apr 2024 16:38:28 +0100 Subject: [PATCH 2/2] adds unit tests for the multi-fuel versions --- .../CalculatorTests.cs | 197 ++++++++++++++---- .../MassOfCo2EmissionsCalculatorTests.cs | 25 --- ...ShipMassOfCo2EmissionsCalculatorService.cs | 2 +- .../Program.cs | 56 ++++- 4 files changed, 203 insertions(+), 77 deletions(-) diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs index 825bdfc..d1512e4 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/CalculatorTests.cs @@ -115,6 +115,84 @@ public void TestCalculatorMultiFuelSameResultAsSingleFuel() } + /// + /// This tests that cumulative fuel consumption is the same as single fuel consumption when + /// using the multi-fuel mode of CalculatAttainedCiiRating + /// + [TestMethod] + public void TestCalculatorMultiFuelSameResultWithZeroFuelConsumption() + { + var _calc = new ShipCarbonIntensityCalculator(); + + double fuelConsumptionInMegaTons = 19_000; + + + var resultMultiFuel = _calc.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, + new List { + new FuelTypeConsumption + { + FuelConsumption = fuelConsumptionInMegaTons * 1_000_000, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + } + }, + 2019 + ); + + var resultWithZeroFuelConsumption = _calc.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, +new List { + new FuelTypeConsumption + { + FuelConsumption = fuelConsumptionInMegaTons * 1_000_000, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + }, + new FuelTypeConsumption + { + FuelConsumption = 0, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + } + }, + 2019 + ); + + + var resultWithMixedFuelConsumption = _calc.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25000, + deadweightTonnage: 0, + distanceTravelled: 150000, +new List { + new FuelTypeConsumption + { + FuelConsumption = (fuelConsumptionInMegaTons / 2) * 1_000_000, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + }, + new FuelTypeConsumption + { + FuelConsumption = (fuelConsumptionInMegaTons / 2) * 1_000_000, + FuelType = TypeOfFuel.DIESEL_OR_GASOIL + } + }, + 2019 + ); + + var resultWithZeroFuelConsumptionAsJsonObj = JsonConvert.SerializeObject(resultWithZeroFuelConsumption); + var multiFuelAsJsonObj = JsonConvert.SerializeObject(resultMultiFuel); + var multiFuelWithMixedConsumption = JsonConvert.SerializeObject(resultWithMixedFuelConsumption); + + Assert.AreEqual(resultWithZeroFuelConsumptionAsJsonObj, multiFuelAsJsonObj); + Assert.AreEqual(resultWithZeroFuelConsumptionAsJsonObj, multiFuelWithMixedConsumption); + Assert.AreEqual(multiFuelAsJsonObj, multiFuelWithMixedConsumption); + } + + /// /// Tests a known and pre-calculated set of inputs for a RoRoPassengerShip @@ -123,39 +201,53 @@ public void TestCalculatorMultiFuelSameResultAsSingleFuel() /// /// /// - /// + /// /// /// /// /// /// - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2019, ImoCiiRating.B, 19.184190519387734, 16.243733333333335, 0.8467249799733408)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2020, ImoCiiRating.B, 18.992348614193855, 16.243733333333335, 0.8552777575488293)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2021, ImoCiiRating.B, 18.80050670899998, 16.243733333333335, 0.8640050816054499)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2022, ImoCiiRating.B, 18.6086648038061, 16.243733333333335, 0.8729123504879803)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2023, ImoCiiRating.B, 18.224980993418345, 16.243733333333335, 0.8912894526035168)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2024, ImoCiiRating.B, 17.84129718303059, 16.243733333333335, 0.9104569677132699)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2025, ImoCiiRating.C, 17.45761337264284, 16.243733333333335, 0.9304670109597152)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2026, ImoCiiRating.C, 17.073929562255085, 16.243733333333335, 0.9513763819925177)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2027, ImoCiiRating.C, 16.690245751867327, 16.243733333333335, 0.9732471034176333)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2028, ImoCiiRating.C, 16.306561941479572, 16.243733333333335, 0.996147035262754)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2029, ImoCiiRating.C, 15.922878131091819, 16.243733333333335, 1.0201505782811335)] - [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 1.9e+10, 2030, ImoCiiRating.C, 15.539194320704066, 16.243733333333335, 1.0453394814485688)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2019, ImoCiiRating.B, 19.184190519387734, 16.243733333333335, 0.8467249799733408)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2020, ImoCiiRating.B, 18.992348614193855, 16.243733333333335, 0.8552777575488293)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2021, ImoCiiRating.B, 18.80050670899998, 16.243733333333335, 0.8640050816054499)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2022, ImoCiiRating.B, 18.6086648038061, 16.243733333333335, 0.8729123504879803)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2023, ImoCiiRating.B, 18.224980993418345, 16.243733333333335, 0.8912894526035168)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2024, ImoCiiRating.B, 17.84129718303059, 16.243733333333335, 0.9104569677132699)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2025, ImoCiiRating.C, 17.45761337264284, 16.243733333333335, 0.9304670109597152)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2026, ImoCiiRating.C, 17.073929562255085, 16.243733333333335, 0.9513763819925177)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2027, ImoCiiRating.C, 16.690245751867327, 16.243733333333335, 0.9732471034176333)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2028, ImoCiiRating.C, 16.306561941479572, 16.243733333333335, 0.996147035262754)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2029, ImoCiiRating.C, 15.922878131091819, 16.243733333333335, 1.0201505782811335)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 19_000, 2030, ImoCiiRating.C, 15.539194320704066, 16.243733333333335, 1.0453394814485688)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2019, ImoCiiRating.B, 19.184190519387734, 15.965066666666667, 0.8321991303480963)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2020, ImoCiiRating.B, 18.992348614193855, 15.965066666666667, 0.8406051821697944)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2021, ImoCiiRating.B, 18.80050670899998, 15.965066666666667, 0.849182786069486)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2022, ImoCiiRating.B, 18.6086648038061, 15.965066666666667, 0.8579372477815427)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2023, ImoCiiRating.B, 18.224980993418345, 15.965066666666667, 0.8759990845769436)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2024, ImoCiiRating.B, 17.84129718303059, 15.965066666666667, 0.8948377745678456)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2025, ImoCiiRating.B, 17.45761337264284, 15.965066666666667, 0.9145045388440618)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2026, ImoCiiRating.C, 17.073929562255085, 15.965066666666667, 0.9350552026383104)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2027, ImoCiiRating.C, 16.690245751867327, 15.965066666666667, 0.9565507245380419)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2028, ImoCiiRating.C, 16.306561941479572, 15.965066666666667, 0.9790578004095253)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2029, ImoCiiRating.C, 15.922878131091819, 15.965066666666667, 1.0026495546362606)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.LIGHTFUELOIL, 19_000, 2030, ImoCiiRating.C, 15.539194320704066, 15.965066666666667, 1.0274063337630819)] [TestMethod] public void TestRoRoPassengerShipReturnsExpectedValues( - ShipType shipType, + ShipType shipType, double deadweightTonnage, double grossTonnage, - TypeOfFuel typeOfFuel, - double fuelConsumptionInGrams, + TypeOfFuel typeOfFuel, + double fuelConsumptionInMt, int year, - ImoCiiRating expectedRating, - double expectedRequiredCii, + ImoCiiRating expectedRating, + double expectedRequiredCii, double expectedAttainedCii, double expectedArRatio) { var _calc = new ShipCarbonIntensityCalculator(); + var fuelConsumptionInGrams = fuelConsumptionInMt * 1_000_000; + var result = _calc.CalculateAttainedCiiRating( shipType, grossTonnage: grossTonnage, @@ -172,12 +264,12 @@ public void TestRoRoPassengerShipReturnsExpectedValues( Assert.IsTrue(result.Results.Count(result => result.IsMeasuredYear) == 1); Assert.IsTrue(result.Results.Count(result => result.IsEstimatedYear) == 11); - Assert.AreEqual(result.Results.First(c => c.Year == year).Year, year); - Assert.AreEqual(result.Results.First(c => c.Year == year).VectorBoundariesForYear.ShipType, shipType); - Assert.AreEqual(result.Results.First(c => c.Year == year).RequiredCii, expectedRequiredCii); - Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedRequiredRatio, expectedArRatio); - Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedCii, expectedAttainedCii); - Assert.AreEqual(result.Results.First(c => c.Year == year).Rating, expectedRating); + Assert.AreEqual(year, result.Results.First(c => c.Year == year).Year); + Assert.AreEqual(shipType, result.Results.First(c => c.Year == year).VectorBoundariesForYear.ShipType); + Assert.AreEqual(expectedRequiredCii, result.Results.First(c => c.Year == year).RequiredCii); + Assert.AreEqual(expectedArRatio, result.Results.First(c => c.Year == year).AttainedRequiredRatio); + Assert.AreEqual(expectedAttainedCii, result.Results.First(c => c.Year == year).AttainedCii); + Assert.AreEqual(expectedRating, result.Results.First(c => c.Year == year).Rating); Assert.AreNotEqual(result.Results.First(c => c.Year == year).IsMeasuredYear, result.Results.First(c => c.Year == year).IsEstimatedYear); } @@ -193,32 +285,36 @@ public void TestRoRoPassengerShipReturnsExpectedValues( /// /// /// - /// - /// + /// + /// + /// + /// /// /// /// /// /// - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2019, ImoCiiRating.C, 8.724037653822592, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2020, ImoCiiRating.C, 8.636797277284366, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2021, ImoCiiRating.C, 8.54955690074614, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2022, ImoCiiRating.C, 8.462316524207914, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2023, ImoCiiRating.C, 8.287835771131462, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2024, ImoCiiRating.C, 8.11335501805501, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2025, ImoCiiRating.D, 7.938874264978558, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2026, ImoCiiRating.D, 7.764393511902107, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2027, ImoCiiRating.D, 7.589912758825655, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2028, ImoCiiRating.D, 7.415432005749203, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2029, ImoCiiRating.E, 7.240951252672751, 8.549333333333333)] - [DataRow(ShipType.BulkCarrier, 25000, 0, TypeOfFuel.DIESEL_OR_GASOIL, 1e+10, 2030, ImoCiiRating.E, 7.0664704995963, 8.549333333333333)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2019, ImoCiiRating.C, 19.184190519387734, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2020, ImoCiiRating.C, 18.992348614193855, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2021, ImoCiiRating.C, 18.80050670899998, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2022, ImoCiiRating.C, 18.6086648038061, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2023, ImoCiiRating.C, 18.224980993418345, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2024, ImoCiiRating.C, 17.84129718303059, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2025, ImoCiiRating.C, 17.45761337264284, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2026, ImoCiiRating.C, 17.073929562255085, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2027, ImoCiiRating.D, 16.690245751867327, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2028, ImoCiiRating.D, 16.306561941479572, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2029, ImoCiiRating.D, 15.922878131091819, 19.089333333333332)] + [DataRow(ShipType.RoRoPassengerShip, 0, 25000, TypeOfFuel.DIESEL_OR_GASOIL, 12_500, TypeOfFuel.LIGHTFUELOIL, 10_000, 2030, ImoCiiRating.D, 15.539194320704066, 19.089333333333332)] [TestMethod] - public void TestMultiFuelBulkCarrierReturnsExpectedValues( + public void TestMultiFuelRoRoPassengerShipReturnsExpectedValues( ShipType shipType, double deadweightTonnage, double grossTonnage, - TypeOfFuel typeOfFuel, - double fuelConsumptionInGrams, + TypeOfFuel typeOfFuelOne, + double fuelConsumptionInMtOne, + TypeOfFuel typeOfFuelTwo, + double fuelConsumptionInMtTwo, int year, ImoCiiRating expectedRating, double expectedRequiredCii, @@ -232,9 +328,19 @@ public void TestMultiFuelBulkCarrierReturnsExpectedValues( shipType, grossTonnage: grossTonnage, deadweightTonnage: deadweightTonnage, - distanceTravelled: 150000, - fuelType: typeOfFuel, - fuelConsumption: fuelConsumptionInGrams, + distanceTravelled: 150_000, + new List { + new FuelTypeConsumption + { + FuelConsumption = fuelConsumptionInMtOne * 1_000_000, + FuelType = typeOfFuelOne + }, + new FuelTypeConsumption + { + FuelConsumption = fuelConsumptionInMtTwo * 1_000_000, + FuelType = typeOfFuelTwo + } + }, year ); @@ -251,8 +357,9 @@ public void TestMultiFuelBulkCarrierReturnsExpectedValues( Assert.AreEqual(result.Results.First(c => c.Year == year).Year, year, $"{nameof(year)} value was incorrect"); Assert.AreEqual(result.Results.First(c => c.Year == year).VectorBoundariesForYear.ShipType, shipType, $"{nameof(shipType)} value was incorrect"); Assert.AreEqual(result.Results.First(c => c.Year == year).RequiredCii, expectedRequiredCii, $"{nameof(expectedRequiredCii)} value was incorrect"); - Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedRequiredRatio, expectedArRatio, $"{nameof(expectedArRatio)} value was incorrect"); Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedCii, expectedAttainedCii, $"{nameof(expectedAttainedCii)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).AttainedRequiredRatio, expectedArRatio, $"{nameof(expectedArRatio)} value was incorrect"); + Assert.AreEqual(result.Results.First(c => c.Year == year).Rating, expectedRating, $"{nameof(expectedRating)} value was incorrect"); Assert.AreNotEqual(result.Results.First(c => c.Year == year).IsMeasuredYear, result.Results.First(c => c.Year == year).IsEstimatedYear); } diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/MassOfCo2EmissionsCalculatorTests.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/MassOfCo2EmissionsCalculatorTests.cs index e4b415f..01f272d 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/MassOfCo2EmissionsCalculatorTests.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core.Tests/MassOfCo2EmissionsCalculatorTests.cs @@ -62,31 +62,6 @@ public void TestGetMassOfCo2EmissionsThrowsExceptionOnInvalidFuel(TypeOfFuel fue Assert.ThrowsException(() => fuelCalculation.GetMassOfCo2Emissions(fuelType, fuelConsumption)); } - /// - /// Tests that, when passed a zero value for fuel consumption, an ArgumentOutOfRangeException is thrown. - /// - [TestMethod] - [DataRow(TypeOfFuel.DIESEL_OR_GASOIL)] - [DataRow(TypeOfFuel.LIGHTFUELOIL)] - [DataRow(TypeOfFuel.HEAVYFUELOIL)] - [DataRow(TypeOfFuel.LIQUIFIEDPETROLEUM_PROPANE)] - [DataRow(TypeOfFuel.LIQUIFIEDPETROLEUM_BUTANE)] - [DataRow(TypeOfFuel.ETHANE)] - [DataRow(TypeOfFuel.LIQUIFIEDNATURALGAS)] - [DataRow(TypeOfFuel.METHANOL)] - [DataRow(TypeOfFuel.ETHANOL)] - [DataRow(TypeOfFuel.UNKNOWN)] - [DataRow(TypeOfFuel.OTHER)] - public void TestGetMassOfCo2EmissionsThrowsExceptionOnZeroConsumptionValue(TypeOfFuel fuelType) - { - // Arrange, set the fuel consumption value to 0 grams (an invalid number) - var fuelConsumption = 0; - - var fuelCalculation = new ShipMassOfCo2EmissionsCalculatorService(); - - // Act & Assert - Assert.ThrowsException(() => fuelCalculation.GetMassOfCo2Emissions(fuelType, fuelConsumption)); - } /// /// Tests that, when passed a negative value for fuel consumption, an ArgumentOutOfRangeException is thrown. diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Services/Impl/ShipMassOfCo2EmissionsCalculatorService.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Services/Impl/ShipMassOfCo2EmissionsCalculatorService.cs index 11a1fd4..aabbc7f 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Services/Impl/ShipMassOfCo2EmissionsCalculatorService.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.Core/Services/Impl/ShipMassOfCo2EmissionsCalculatorService.cs @@ -24,7 +24,7 @@ internal class ShipMassOfCo2EmissionsCalculatorService : IShipMassOfCo2Emissions /// public double GetMassOfCo2Emissions(TypeOfFuel fuelType, double fuelConsumptionMassInGrams) { - if (fuelConsumptionMassInGrams <= 0) + if (fuelConsumptionMassInGrams < 0) { throw new ArgumentOutOfRangeException("Fuel consumption mass must be a positive value", nameof(fuelConsumptionMassInGrams)); diff --git a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs index b048e83..b7ba51f 100644 --- a/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs +++ b/EtiveMor.OpenImoCiiCalculator/EtiveMor.OpenImoCiiCalculator.DemoConsoleApp/Program.cs @@ -32,6 +32,38 @@ static void Main(string[] args) Console.WriteLine("---------------------"); } + + + /// + /// Runs the single fuel calculation with sample data + /// + /// + static void Old_MainOneFuelCalculation(string[] args) + { + Console.WriteLine("Generating a ship result now..."); + + var calculator = new ShipCarbonIntensityCalculator(); + + double fuelConsumptionInMegaTons = 19_000; + + var result = calculator.CalculateAttainedCiiRating( + ShipType.RoRoPassengerShip, + grossTonnage: 25_000, + deadweightTonnage: 0, + distanceTravelled: 150_000, + TypeOfFuel.DIESEL_OR_GASOIL, + fuelConsumption: fuelConsumptionInMegaTons * 1_000_000, + 2019); + + + string json = JsonConvert.SerializeObject(result, Formatting.Indented); + Console.WriteLine(json); + Console.WriteLine("Press any key to finish"); + Console.ReadKey(); + } + + + /// /// Runs the single fuel calculation with sample data /// @@ -42,13 +74,15 @@ static void MainOneFuelCalculation(string[] args) var calculator = new ShipCarbonIntensityCalculator(); + double fuelConsumptionInMegaTons = 19_000; + var result = calculator.CalculateAttainedCiiRating( ShipType.RoRoPassengerShip, - grossTonnage: 25000, + grossTonnage: 25_000, deadweightTonnage: 0, - distanceTravelled: 150000, + distanceTravelled: 150_000, TypeOfFuel.DIESEL_OR_GASOIL, - fuelConsumption: 1.9e+10, + fuelConsumption: fuelConsumptionInMegaTons * 1_000_000, 2019); @@ -59,6 +93,7 @@ static void MainOneFuelCalculation(string[] args) } + /// /// Runs the multi-fuel calculation with sample data /// @@ -67,16 +102,25 @@ static void MainMultiFuelCalculation(string[] args) { var calculator = new ShipCarbonIntensityCalculator(); + double fuelConsumptionDieselInMegaTons = 12_500; + double fuelConsumptionLightFuelInMegaTons = 10_000; // 35_000; + + var result = calculator.CalculateAttainedCiiRating( ShipType.RoRoPassengerShip, - grossTonnage: 25000, + grossTonnage: 25_000, deadweightTonnage: 0, - distanceTravelled: 150000, + distanceTravelled: 150_000, new List { new FuelTypeConsumption { - FuelConsumption = 1.9e+10, + FuelConsumption = fuelConsumptionDieselInMegaTons * 1_000_000, FuelType = TypeOfFuel.DIESEL_OR_GASOIL + }, + new FuelTypeConsumption + { + FuelConsumption = fuelConsumptionLightFuelInMegaTons * 1_000_000, + FuelType = TypeOfFuel.LIGHTFUELOIL } }, 2019);