/// <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));
        }
        /// <summary>
        /// Validates a <see cref="BalancedFieldLengthCalculation"/>.
        /// </summary>
        /// <param name="calculation">The calculation to validate.</param>
        /// <returns>A collection of validation messages if the validation failed, empty otherwise.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="calculation"/>
        /// is <c>null</c>.</exception>
        public IEnumerable <string> Validate(BalancedFieldLengthCalculation calculation)
        {
            if (calculation == null)
            {
                throw new ArgumentNullException(nameof(calculation));
            }

            try
            {
                EngineData engineData = calculation.EngineData;
                GeneralSimulationSettingsData generalSimulationSettings = calculation.SimulationSettings;

                AircraftData          aircraftData     = AircraftDataFactory.Create(calculation.AircraftData, engineData);
                KernelValidationError validationResult = kernel.Validate(aircraftData,
                                                                         generalSimulationSettings.Density,
                                                                         generalSimulationSettings.GravitationalAcceleration,
                                                                         engineData.NrOfFailedEngines);

                var messages = new List <string>();
                if (generalSimulationSettings.EndFailureVelocity < 1)
                {
                    messages.Add(Resources.BalancedFieldLengthCalculationModule_ValidationMessage_End_failure_velocity_must_be_larger_than_Zero);
                }

                if (validationResult.HasFlag(KernelValidationError.InvalidDensity))
                {
                    messages.Add(Resources.BalancedFieldLengthCalculationModule_ValidationMessage_Invalid_Density);
                }

                if (validationResult.HasFlag(KernelValidationError.InvalidGravitationalAcceleration))
                {
                    messages.Add(Resources.BalancedFieldLengthCalculationModule_ValidationMessage_Invalid_GravitationalAcceleration);
                }

                if (validationResult.HasFlag(KernelValidationError.InvalidNrOfFailedEngines))
                {
                    messages.Add(Resources.BalancedFieldLengthCalculationModule_ValidationMessage_Invalid_NrOfFailedEngines);
                }

                return(messages);
            }
            catch (CreateKernelDataException e)
            {
                return(new[]
                {
                    e.Message
                });
            }
        }
 public CalculationInput(GeneralSimulationSettingsData generalSimulationSettings,
                         int failureVelocity,
                         AircraftData aircraftData,
                         IIntegrator integrator,
                         int nrOfFailedEngines,
                         double density,
                         double gravitationalAcceleration)
 {
     GeneralSimulationSettings = generalSimulationSettings;
     FailureVelocity           = failureVelocity;
     AircraftData              = aircraftData;
     Integrator                = integrator;
     NrOfFailedEngines         = nrOfFailedEngines;
     Density                   = density;
     GravitationalAcceleration = gravitationalAcceleration;
 }