/// <summary>
        /// Calculates the <see cref="BalancedFieldLengthOutput"/> based on <paramref name="calculation"/>.
        /// </summary>
        /// <param name="calculation">The <see cref="BalancedFieldLengthCalculation"/> to calculate for.</param>
        /// <returns>A <see cref="BalancedFieldLengthOutput"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="calculation"/> is <c>null</c>.</exception>
        /// <exception cref="CreateKernelDataException">Thrown when the calculation input
        /// could not be created for the kernel.</exception>
        /// <exception cref="KernelCalculationException">Thrown when <see cref="AggregatedDistanceOutput"/>
        /// could not be calculated.</exception>
        public BalancedFieldLengthOutput Calculate(BalancedFieldLengthCalculation calculation)
        {
            if (calculation == null)
            {
                throw new ArgumentNullException(nameof(calculation));
            }

            GeneralSimulationSettingsData generalSimulationSettings = calculation.SimulationSettings;
            double density     = generalSimulationSettings.Density;
            int    endVelocity = generalSimulationSettings.EndFailureVelocity;
            double gravitationalAcceleration = generalSimulationSettings.GravitationalAcceleration;

            EngineData   engineData        = calculation.EngineData;
            int          nrOfFailedEngines = engineData.NrOfFailedEngines;
            AircraftData aircraftData      = AircraftDataFactory.Create(calculation.AircraftData, engineData);

            var integrator = new EulerIntegrator();

            var outputs = new List <AggregatedDistanceOutput>();

            for (int i = 0; i < endVelocity; i++)
            {
                var calculationInput = new CalculationInput(generalSimulationSettings,
                                                            i,
                                                            aircraftData,
                                                            integrator,
                                                            nrOfFailedEngines,
                                                            density,
                                                            gravitationalAcceleration);
                AggregatedDistanceOutput output = CalculateDistances(calculationInput);
                outputs.Add(output);
            }

            return(BalancedFieldLengthOutputFactory.Create(outputs));
        }
        public void Create_OutputsNull_ThrowsArgumentNullException()
        {
            // Call
            TestDelegate call = () => BalancedFieldLengthOutputFactory.Create(null);

            // Assert
            Assert.That(call, Throws.TypeOf <ArgumentNullException>()
                        .With.Property(nameof(ArgumentNullException.ParamName))
                        .EqualTo("outputs"));
        }
        public void Create_InputArgumentCausesException_ThrowsKernelCalculationException()
        {
            // Setup
            IEnumerable <AggregatedDistanceOutput> outputs = Enumerable.Empty <AggregatedDistanceOutput>();

            // Call
            TestDelegate call = () => BalancedFieldLengthOutputFactory.Create(outputs);

            // Assert
            var       exception      = Assert.Throws <KernelCalculationException>(call);
            Exception innerException = exception.InnerException;

            Assert.That(innerException, Is.Not.Null);
            Assert.That(exception.Message, Is.EqualTo(innerException.Message));
        }
        public void Create_WithValidCollection_ReturnsExpectedBalancedFieldLengthOutput()
        {
            // Setup
            const double expectedVelocity = 11;
            const double expectedDistance = 20;
            var          outputs          = new[]
            {
                new AggregatedDistanceOutput(10, 10, 30),
                new AggregatedDistanceOutput(expectedVelocity, expectedDistance, 20),
                new AggregatedDistanceOutput(12, 30, 10)
            };

            // Call
            BalancedFieldLengthOutput output = BalancedFieldLengthOutputFactory.Create(outputs);

            // Assert
            Assert.That(output.Distance, Is.EqualTo(expectedDistance));
            Assert.That(output.Velocity, Is.EqualTo(expectedVelocity));
        }