From 00df046e7a8a3a63c810200edfb0c3ccda3db19a Mon Sep 17 00:00:00 2001
From: Gerrit Pauls <gerrit.pauls@tuhh.de>
Date: Wed, 11 Dec 2024 17:08:33 +0100
Subject: [PATCH 1/2] LoD added to CSV

---
 mission_analysis/mission_analysis_conf.xml    |  2 +-
 .../condition_methods/flight_conditions.cpp   |  1 +
 .../condition_methods/flight_conditions.h     |  7 +-
 .../condition_methods/operating_conditions.h  |  6 +-
 .../flight_segments/flight_segments.cpp       | 88 +++++++++++++------
 .../output/standard_mission_output.cpp        |  8 +-
 .../standard_mission/standard_mission.cpp     | 40 +++++----
 .../standard_mission/standard_mission.h       | 37 ++++++--
 8 files changed, 127 insertions(+), 62 deletions(-)

diff --git a/mission_analysis/mission_analysis_conf.xml b/mission_analysis/mission_analysis_conf.xml
index 7978e1d8..f26e4b04 100644
--- a/mission_analysis/mission_analysis_conf.xml
+++ b/mission_analysis/mission_analysis_conf.xml
@@ -34,7 +34,7 @@
 			<value>true</value>
 		</tex_report>
         <write_info_files description="Switch to generate info files. Switch: true (On) / false (Off)">
-			<value>true</value>
+			<value>false</value>
 		</write_info_files>
         <log_file description="Specify the name of the log file">
 			<value>mission_analysis.log</value>
diff --git a/mission_analysis/src/libs/condition_methods/flight_conditions.cpp b/mission_analysis/src/libs/condition_methods/flight_conditions.cpp
index 56f5b01a..d7fd5acd 100644
--- a/mission_analysis/src/libs/condition_methods/flight_conditions.cpp
+++ b/mission_analysis/src/libs/condition_methods/flight_conditions.cpp
@@ -68,6 +68,7 @@ Flight_conditions::Flight_conditions(std::vector<mission_file_data_handler::miss
     /* Initialization of parameters at the end of the segment */
     end_angle_of_attack(0.),
     end_CL(0.),
+    end_L_over_D(0.),
     end_specific_air_range(0.),
     /* Initialization of parameters for engine parameter calculation */
     rel_engine_availability(1.),
diff --git a/mission_analysis/src/libs/condition_methods/flight_conditions.h b/mission_analysis/src/libs/condition_methods/flight_conditions.h
index 15ee5cd1..8226aa04 100644
--- a/mission_analysis/src/libs/condition_methods/flight_conditions.h
+++ b/mission_analysis/src/libs/condition_methods/flight_conditions.h
@@ -9,8 +9,8 @@
  *
  */
 
-#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Flight_conditions_H_
-#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Flight_conditions_H_
+#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_FLIGHT_CONDITIONS_H_
+#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_FLIGHT_CONDITIONS_H_
 
 #include <map>
 #include <memory>
@@ -90,6 +90,7 @@ class Flight_conditions {
 
     double end_angle_of_attack;    /**< Angle of attack AOA at the end of the segment [deg] */
     double end_CL;                 /**< Lift coefficient at the end of the segment [-] */
+    double end_L_over_D;           /**< Lift over drag coefficient at the end of the segment [-] */
     double end_specific_air_range; /**< Specific air range at the end of the segment [m/kg] */
 
     double rel_engine_availability; /**< Percentage of available engines; default 1 (AEO), OEI: (numberOfEngines-1)/numberOfEngines [-] */
@@ -186,4 +187,4 @@ class Flight_conditions {
     void update_end_mass(const bool& use_breguet = false);
 };
 
-#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Flight_conditions_H_
+#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_FLIGHT_CONDITIONS_H_
diff --git a/mission_analysis/src/libs/condition_methods/operating_conditions.h b/mission_analysis/src/libs/condition_methods/operating_conditions.h
index c10562de..c17893ec 100644
--- a/mission_analysis/src/libs/condition_methods/operating_conditions.h
+++ b/mission_analysis/src/libs/condition_methods/operating_conditions.h
@@ -12,8 +12,8 @@
 /* List of references
     [1] Airbus customer services, Flight Operations Support & Line Assistance: Getting to grips with the cost index, Issue II, May 1998, p.7
 */
-#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Operating_conditions_H_
-#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Operating_conditions_H_
+#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_OPERATING_CONDITIONS_H_
+#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_OPERATING_CONDITIONS_H_
 
 #include <string>
 #include <vector>
@@ -58,4 +58,4 @@ class Operating_conditions {
     void delete_used_bleed_and_shaft_power_offtakes(const double& time_step);
 };
 
-#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Operating_conditions_H_
+#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_OPERATING_CONDITIONS_H_
diff --git a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp
index e0000899..395ca07c 100644
--- a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp
+++ b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp
@@ -29,6 +29,7 @@ standard_mission::mission_segment::mission_segment(const std::map<int, double>&
                                                     double an_end_altitude,
                                                     double an_end_total_mass,
                                                     double an_end_CL,
+                                                    double an_end_L_over_D,
                                                     double an_end_specific_air_range,
                                                     const std::string& an_end_aero_config,
                                                     double an_end_glidepath_angle,
@@ -58,6 +59,7 @@ standard_mission::mission_segment::mission_segment(const std::map<int, double>&
     end_altitude(an_end_altitude),
     end_total_mass(an_end_total_mass),
     end_CL(an_end_CL),
+    end_L_over_D(an_end_L_over_D),
     end_specific_air_range(an_end_specific_air_range),
     end_aero_config(an_end_aero_config),
     end_glidepath_angle(an_end_glidepath_angle),
@@ -207,12 +209,12 @@ void standard_mission::climb_to_service_ceiling(Operating_conditions* oc, Flight
         fc->delta_h = (steps <= 0.) ? 0. : fc->delta_h / steps;
         try {
             myRuntimeInfo->out << std::endl << "Flying maximum operating altitude ..." << std::endl;
-            myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft."
-                               << "Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl;
-            myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
-            myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl;
+            myRuntimeInfo->out << "Climb Step:          " << convertUnit(METER, FOOT, fc->delta_h) << " ft."
+                               << "Total:               " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl;
+            myRuntimeInfo->out << "Start altitude:      " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
+            myRuntimeInfo->out << "End altitude:        " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl;
             myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl;
-            myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl;
+            myRuntimeInfo->out << "Engine Rating:       " << oc->rating << std::endl;
             for (uint16_t step_number(0); step_number < steps; ++step_number) {
                 /* Set the initial conditions of the segment */
                 this->set_segment_initial_conditions(fc);
@@ -238,12 +240,12 @@ void standard_mission::climb_to_service_ceiling(Operating_conditions* oc, Flight
         fc->delta_h = (steps <= 0.) ? 0. : fc->delta_h / steps;
         try {
             myRuntimeInfo->out << std::endl << "Flying absolute ceiling altitude ..." << std::endl;
-            myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft."
-                               << "Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl;
-            myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
-            myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl;
+            myRuntimeInfo->out << "Climb Step:         " << convertUnit(METER, FOOT, fc->delta_h) << " ft."
+                               << "Total:               " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl;
+            myRuntimeInfo->out << "Start altitude:      " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
+            myRuntimeInfo->out << "End altitude:        " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl;
             myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl;
-            myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl;
+            myRuntimeInfo->out << "Engine Rating:       " << oc->rating << std::endl;
             for (uint16_t step_number(0); step_number < steps; ++step_number) {
                 this->set_segment_initial_conditions(fc);
                 if (fc->altitude < get_transition_altitude(CAS, transition_mach, this->atm)) {
@@ -274,12 +276,12 @@ void standard_mission::climb_to_service_ceiling(Operating_conditions* oc, Flight
         fc->delta_h = (steps <= 0.) ? 0. : fc->delta_h / steps;
         try {
             myRuntimeInfo->out << std::endl << "Flying maximum altitude with one engine inoperative ..." << std::endl;
-            myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft."
-                               << " Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl;
-            myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
-            myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl;
+            myRuntimeInfo->out << "Climb Step:          " << convertUnit(METER, FOOT, fc->delta_h) << " ft."
+                               << " Total:              " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl;
+            myRuntimeInfo->out << "Start altitude:      " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
+            myRuntimeInfo->out << "End altitude:        " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl;
             myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl;
-            myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl;
+            myRuntimeInfo->out << "Engine Rating:       " << oc->rating << std::endl;
             for (uint16_t step_number(0); step_number < steps; ++step_number) {
                 this->set_segment_initial_conditions(fc);
                 if (fc->altitude < get_transition_altitude(CAS, transition_mach, this->atm)) {
@@ -430,12 +432,12 @@ double standard_mission::calculate_climb_or_descent(Operating_conditions* oc, Fl
     Flight_conditions fc_tmp(*fc);
     fc_tmp.delta_h /= steps;
     if (!simulation_mode) {
-        myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step: " : "Descent step: ")
+        myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step:    " : "Descent step:    ")
                             << convertUnit(METER, FOOT, fc_tmp.delta_h) << " ft." << std::endl;
         myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc_tmp.altitude) << " ft." << std::endl;
-        myRuntimeInfo->out << "End altitude" << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ")
+        myRuntimeInfo->out << "End altitude    " << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ")
                            << convertUnit(METER, FOOT, (fc_tmp.delta_h * steps + fc_tmp.altitude)) << " ft." << std::endl;
-        if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl;
+        if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude:    " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl;
     }
     for (uint16_t step_number(0); step_number < steps; ++step_number) {
         this->set_segment_initial_conditions(&fc_tmp, !simulation_mode);
@@ -706,6 +708,7 @@ double standard_mission::landing(Operating_conditions* oc, Flight_conditions* fc
             residuum = fabs(oldTAS - fc->end_TAS) / fabs(oldTAS);
         } while (residuum > ACCURACY_LOW);
         fc->end_CL = this->aero.CLgroundRoll;
+        fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config);
         fc->end_angle_of_attack = 0.;
         fc->end_specific_air_range = 0.;
         this->mission_file->mission_data.at(a_mission_step).mode = Flight_conditions::LANDING;
@@ -1073,9 +1076,9 @@ void standard_mission::free_flight(Operating_conditions* oc, Flight_conditions*
         static_cast<uint16_t>(ceil(fabs(fc->delta_h / EndnodeReadOnly<double>(
         "program_settings/precision/altitude_increment").read(this->rtIO->moduleConfig).value())));
     fc->delta_h = fc->delta_h / flightLevelSteps;
-    myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." << std::endl;
-    myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
-    myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * flightLevelSteps + fc->altitude)) << " ft." << std::endl;
+    myRuntimeInfo->out << "Climb Step:          " << convertUnit(METER, FOOT, fc->delta_h) << " ft." << std::endl;
+    myRuntimeInfo->out << "Start altitude:      " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl;
+    myRuntimeInfo->out << "End altitude:        " << convertUnit(METER, FOOT, (fc->delta_h * flightLevelSteps + fc->altitude)) << " ft." << std::endl;
     myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl;
     for (uint16_t step_number(0); step_number < flightLevelSteps; ++step_number) {
         /* Set the initial conditions of the segment */
@@ -1429,10 +1432,28 @@ void standard_mission::free_flight_iteration(Operating_conditions* oc, Flight_co
                         convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
                         0., fc->aircraft_mass - fc->step_fuel_mass, this->atm));
     }
-    fc->end_specific_air_range =
-            this->static_flight_specific_air_range(energy_carrier_id, convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
-            fc->end_altitude, fc->aircraft_mass -
-            fc->step_fuel_mass, oc->config, oc->rating);
+
+    fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config);
+    if (sophistication_level != UNSOPHISTICATED) {
+        double current_cg(get_current_cg());
+        fc->end_L_over_D = this->interpolateViaCoG(current_cg, fc->end_L_over_D,
+            getAlternativeAero(current_cg)->getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
+                                                        fc->end_CL, fc->operating_condition->config));
+    }
+
+    double sar_tmp;
+    try {
+            sar_tmp =
+                this->static_flight_specific_air_range(energy_carrier_id, convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
+                    fc->end_altitude, fc->aircraft_mass -
+                    fc->step_fuel_mass, oc->config, oc->rating);
+        } catch (const int& engine_status) {
+            throwError(__FILE__, __func__, __LINE__,
+                    ("Required thrust (" + num2Str(this->aero.getCruiseDrag(mach, fc->end_altitude, 0., fc->aircraft_mass -
+                    fc->step_fuel_mass, oc->config, this->atm)) + " kN) cannot be delivered by engines in current status."));
+        }
+    fc->end_specific_air_range = sar_tmp;
+
     fc->end_angle_of_attack =
             this->aero.getAlphaAtFlightCondition(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
             oc->config, fc->end_CL);
@@ -1576,6 +1597,13 @@ void standard_mission::set_iteration_start_values(Flight_conditions* fc, const d
     } else {
         fc->end_CL = an_end_CL;
     }
+    fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config);
+    if (sophistication_level != UNSOPHISTICATED) {
+        double current_cg(get_current_cg());
+        fc->end_L_over_D = this->interpolateViaCoG(current_cg, fc->end_L_over_D,
+            getAlternativeAero(current_cg)->getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
+                                                        fc->end_CL, fc->operating_condition->config));
+    }
     fc->end_drag = this->aero.getCLDrag(mach, fc->end_altitude, fc->end_CL, fc->operating_condition->config, atm);
     if (sophistication_level != UNSOPHISTICATED) {
         double current_cg(get_current_cg());
@@ -1621,6 +1649,15 @@ void standard_mission::set_aerodynamic_values(Flight_conditions* fc, const doubl
         }
     }
 
+    // L over D
+    fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config);
+    if (sophistication_level != UNSOPHISTICATED) {
+        double current_cg(get_current_cg());
+        fc->end_L_over_D = this->interpolateViaCoG(current_cg, fc->end_L_over_D,
+            getAlternativeAero(current_cg)->getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS),
+                                                        fc->end_CL, fc->operating_condition->config));
+    }
+
     // Drag
     fc->end_drag = this->aero.getCLDrag(mach, fc->end_altitude, fc->end_CL,
                                                             fc->operating_condition->config, this->atm);
@@ -1821,6 +1858,7 @@ void standard_mission::save_segment_data(Flight_conditions* fc, const Operating_
                                    this->mission_profile.back().end_altitude + fc->delta_h,
                                    this->mission_profile.back().end_total_mass - fc->step_fuel_mass,
                                    fc->end_CL,
+                                   fc->end_L_over_D,
                                    fc->end_specific_air_range,
                                    oc.config,
                                    fc->mean_glidepath_angle,
diff --git a/mission_analysis/src/standard_mission/output/standard_mission_output.cpp b/mission_analysis/src/standard_mission/output/standard_mission_output.cpp
index 8cf1df72..5c02063c 100644
--- a/mission_analysis/src/standard_mission/output/standard_mission_output.cpp
+++ b/mission_analysis/src/standard_mission/output/standard_mission_output.cpp
@@ -147,7 +147,7 @@ void standard_mission_output::generate_mission_profile_data() {
                     << (std::format("Energy consumed ({}, ID = {}) [J]; ", rtIO->get_fuel_type(energy_carrier.first), energy_carrier.first));
     }
     csvStream << "Mach [-]; " << "CAS [m/s]; " << "TAS [m/s]; " << "TAS [kts]; " << "ROC [fpm]; " << "SAR [m/kg]; " << "Aero Config [-]; " << "C_L [-]; "
-                << "Spoiler Factor [-]; " << "Reynolds Number [-]; " <<  "Engine Rating [-]; ";
+                 << "L over D [-]; " << "Spoiler Factor [-]; " << "Reynolds Number [-]; " <<  "Engine Rating [-]; ";
     for (node* propulsor : rtIO->acxml.at("component_design/propulsion/specific").getVector("propulsion")) {
         csvStream << "Engine N1 (" << propulsor->at("engine/model/value") << ", ID = " << propulsor->getIntAttrib("ID") << ") [-]; ";
     }
@@ -198,6 +198,7 @@ void standard_mission_output::generate_mission_profile_data() {
         csvStream << my_mission_ptr->mission_profile.at(i).end_specific_air_range << "; "
         << my_mission_ptr->mission_profile.at(i).end_aero_config << "; "
         << my_mission_ptr->mission_profile.at(i).end_CL << "; "
+        << my_mission_ptr->mission_profile.at(i).end_L_over_D << "; "
         << my_mission_ptr->mission_profile.at(i).end_spoiler_factor << "; "
         << my_mission_ptr->mission_profile.at(i).end_reynolds_number << "; "
         << my_mission_ptr->mission_profile.at(i).end_engine_rating << "; ";
@@ -289,8 +290,9 @@ void standard_mission_output::generate_SAR_plot_data() {
                     try {
                         SAR_tmp = my_mission_ptr->static_flight_specific_air_range(energy_carrier_id, Ma, convertUnit(HECTO, FOOT, NOPREFIX, METER, Alt),
                                                                                         aircraft_mass, Config_set, Rating_set);
-                    } catch (const char * text) {
-                    } catch (const std::string& text) {
+                    } catch (const std::string& text)  {
+                        myRuntimeInfo->out << "... but this was intended: SAR limit for plotting reached!" << std::endl;
+                    } catch (...) {
                     }
                     plot << std::setprecision(7) << Ma << "; ";
                     plot << std::setprecision(7) << Alt << "; "; // in meters
diff --git a/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp b/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp
index 41ddcf37..0a56d150 100644
--- a/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp
+++ b/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp
@@ -357,6 +357,7 @@ void standard_mission::run() {
                                                     this->takeoff_mass.value(),
                                                     0.,
                                                     0.,
+                                                    0.,
                                                     oc.config,
                                                     0.,
                                                     0.,
@@ -385,11 +386,12 @@ void standard_mission::run() {
     for (size_t i(0); i < this->mission_file->mission_data.size(); i++) {
         /* Output: calculation mode and current parameters */
         myRuntimeInfo->out << "*********************************************************" << std::endl;
-        myRuntimeInfo->out << "Calculation mode: " << this->mission_file->mission_data.at(i).mode << " in mission segment: " << i + 1 << std::endl;
-        myRuntimeInfo->out << "Current altitude: " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl;
-        myRuntimeInfo->out << "Current range:     " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl;
+        myRuntimeInfo->out << "Calculation mode:     " << this->mission_file->mission_data.at(i).mode << " in mission segment: " << i + 1 << std::endl;
+        myRuntimeInfo->out << "Current altitude:     " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl;
+        myRuntimeInfo->out << "Current range:        " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl;
         myRuntimeInfo->out << "Current Mach number:  " << this->mission_profile.back().end_mach << std::endl;
-        myRuntimeInfo->out << "Current CL:       " << this->mission_profile.back().end_CL << std::endl;
+        myRuntimeInfo->out << "Current CL:           " << this->mission_profile.back().end_CL << std::endl;
+        myRuntimeInfo->out << "Current L/D:          " << this->mission_profile.back().end_L_over_D << std::endl;
         switch (this->mission_file->mission_data.at(i).mode) {
             /* Mode: take off */
             case Flight_conditions::TAKEOFF:
@@ -493,7 +495,7 @@ void standard_mission::update() {
     Endnode<double> flight_time("flight_time", "Flight time for the whole mission", this->mission_profile.back().end_time, "s", 0, 44500);
     Endnode<double> total_range("range", "Traveled range from break release to end of taxi at destination", this->mission_profile.back().end_range, "m", 0, 5000000);
     Endnode<int> energy_carrier_id("energy_carrier_ID", "See energy carrier specification node", 0, "1", 0, 5); // TODO(GErrit): Auf Multifuel anpassen hier und drunter
-    Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e12);
+    Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e13);
 
     /* Aircraft parameters */
     // Since takeoff_mass can be put into mission node for study mission and into masses_cg_inertia node for design mission,
@@ -635,9 +637,9 @@ void standard_mission::analyze_cruise_profile() {
     step.mass = this->mission_profile.at(this->cruise_profile_end).end_total_mass;
     this->cruise_profile.push_back(step);
     /* Output: current parameters */
-    myRuntimeInfo->out << "Current altitude: " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl;
-    myRuntimeInfo->out << "Current range:     " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl;
-    myRuntimeInfo->out << "Cruise Step Profile:" << std::endl;
+    myRuntimeInfo->out << "Current altitude:    " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl;
+    myRuntimeInfo->out << "Current range:       " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl;
+    myRuntimeInfo->out << "Cruise Step Profile: " << std::endl;
     myRuntimeInfo->out << "  FL   | rel. Step Length | End Mass [kg]" << std::endl;
     for (size_t i(0); i < this->cruise_profile.size(); ++i) {
         myRuntimeInfo->out  << std::setprecision(2) << std::fixed  << this->cruise_profile.at(i).FL << " |        "
@@ -740,36 +742,36 @@ void standard_mission::throw_mission_error(int error_code, const uint16_t &missi
     switch (error_code) {
         /* Error: negative flight route leading to an insufficient thrust */
         case 1:
-            error_message << "Error: Negative flight distance! -> Thrust not sufficient." << std::endl;
+            error_message << "Error: Negative flight distance! -> Thrust not sufficient.";
             break;
         /* Error: insufficient acceleration potential */
         case 2:
-            error_message << "Error: Acceleration not sufficient!" << std::endl;
+            error_message << "Error: Acceleration not sufficient!";
             break;
         /* Error: resistance too low to maintain the glide path */
         case 3:
-            error_message << "Error: Drag too low to maintain the glide path!" << std::endl;
+            error_message << "Error: Drag too low to maintain the glide path!";
             break;
         /* Error: insufficient thrust to maintain trajectory */
         case 4:
-            error_message << "Error: Thrust not sufficient to maintain trajectory!" << std::endl;
+            error_message << "Error: Thrust not sufficient to maintain trajectory!";
             break;
         /* Error: divergence too low */
         case 5:
-            error_message << "Error: Divergence too large!" << std::endl;
+            error_message << "Error: Divergence too large!";
             break;
         /* Error: climb angle for iteration too small leading to a too large or too small thrust */
         case 6:
-            error_message << "Climb angle for Iteration too small - Thrust too high or too low!" << std::endl;
+            error_message << "Climb angle for Iteration too small - Thrust too high or too low!";
             break;
         /* Unknown error */
         default:
-            error_message << "Unkown Error" << std::endl;
+            error_message << "Unkown Error";
             break;
     }
-    error_message << "Occured in mode step " << mission_step + 1 << std::endl;
-    error_message << "Mode: " << this->mission_file->mission_data.at(mission_step).mode_name << ", ";
-    error_message << "Index in mission file: " << this->mission_file->mission_data.at(mission_step).mission_file_index << std::endl;
+    error_message << " Occured in mode step " << mission_step + 1;
+    error_message << " Mode: " << this->mission_file->mission_data.at(mission_step).mode_name << ", ";
+    error_message << " Index in mission file: " << this->mission_file->mission_data.at(mission_step).mission_file_index << std::endl;
     throw error_message.str();
 }
 
@@ -924,7 +926,7 @@ void  standard_mission::first_loop_update() {/* Create path to mission and build
     Endnode<double> total_range("range", "Traveled range from break release to end of taxi at destination", // take required range for 1st assumption
         EndnodeReadOnly<double>("requirements_and_specifications/requirements/top_level_aircraft_requirements/design_mission/range").read(rtIO->acxml).value(), "m", 0, 5000000);
     Endnode<int> energy_carrier_id("energy_carrier_ID", "See energy carrier specification node", 0, "1", 0, 5); // TODO(GErrit): Auf Multifuel anpassen hier und drunter
-    Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e12);
+    Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e13);
 
     /* Aircraft parameters */
     // Since takeoff_mass can be put into mission node for study mission and into masses_cg_inertia node for design mission,
diff --git a/mission_analysis/src/standard_mission/standard_mission/standard_mission.h b/mission_analysis/src/standard_mission/standard_mission/standard_mission.h
index a350e629..19726a6d 100644
--- a/mission_analysis/src/standard_mission/standard_mission/standard_mission.h
+++ b/mission_analysis/src/standard_mission/standard_mission/standard_mission.h
@@ -229,6 +229,7 @@ class standard_mission : public Strategy {
         double end_altitude;            /**< Altitude at the end of the segment [m] */
         double end_total_mass;          /**< Aircraft mass at the end of the segment [kg] */
         double end_CL;                  /**< Lift coefficient at the end of the segment [-] */
+        double end_L_over_D;            /**< Lift over drag coefficient at the end of the segment [-] */
         double end_specific_air_range;  /**< Specific air range at the end of the segment [m/kg] */
         std::string end_aero_config;    /**< Aerodynamic configuration at the end of the segment */
         double end_glidepath_angle;     /**< Path angle at the end of the segment [deg] */
@@ -249,7 +250,7 @@ class standard_mission : public Strategy {
         double end_fuel_cg;             /**< Fuel center of gravity at the end of the segment [m] */
         double end_stabilizer_incidence;              /**< incidence angle of stabilizer at the end of the segment [deg] */
         std::vector<std::vector<double>> end_origin_polar; /**< Origin polar with variable camber infos at the end of the segment */
-        int energy_carrier_id;
+        int energy_carrier_id;          /* Energy carrier used for the profile step */
         /* Constructor and destructor */
         /** \brief Constructor for the class mission_segment
          * \param an_end_total_fuel_mass: cumulative consumption at the end of the segment [kg]
@@ -259,6 +260,7 @@ class standard_mission : public Strategy {
          * \param an_end_altitude: altitude at the end of the segment [m]
          * \param an_end_total_mass: weight at the end of the segment [kg]
          * \param an_end_CL: lift coefficient at the end of the segment [-]
+         * \param an_end_L_over_D: lift over drag coefficient at the end of the segment [-]
          * \param an_end_specific_air_range: specific air range at the end of the segment [m/kg]
          * \param an_end_aero_config: aerodynamic configuration at the end of the segment
          * \param an_end_glidepath_angle: glidepath angle at the end of the segment [deg]
@@ -279,6 +281,7 @@ class standard_mission : public Strategy {
          * \param an_end_fuel_cg: Fuel center of gravity at the end of the segment [m]
          * \param an_end_stabilizer_incidence: incidence angle of stabilizer at the end of the segment [deg]
          * \param an_end_origin_polar: Origin polar with variable camber infos at the end of the segment
+         * \param an_energy_carrier_id: Energy carrier used for the profile step
          */
         mission_segment(const std::map<int, double>& an_end_total_fuel_mass,
                     double an_end_fuel_flow,
@@ -287,6 +290,7 @@ class standard_mission : public Strategy {
                     double an_end_altitude,
                     double an_end_total_mass,
                     double an_end_CL,
+                    double an_end_L_over_D,
                     double an_end_specific_air_range,
                     const std::string& an_end_aero_config,
                     double an_end_glidepath_angle,
@@ -314,10 +318,32 @@ class standard_mission : public Strategy {
     };
     std::vector<mission_segment> mission_profile; /**< Profile of the mission */
 
-    /* Methods */
+    /* Auxillary functions */
+    /** \brief Function checks if the needed node is existing. If not, it's created
+     * \param nodepath: path leading to the wanted node
+     * \param description: description of the new node
+     * \param id: if multiple same nodes are set, given ID for it
+     * \param tool_level: if a tool level is needed, given tool level
+     */
     void check_and_add_nodes(std::string nodepath, const std::string& description, const int& id = -1, const int& tool_level = -1);
+    /** \brief Function returns the whole fuel mass within the map
+     * \param fuel_map: A fuel map with int keys corresponding to the energy carrier IDs <[-], [kg]>
+     * \return double value of the fuel mass [kg]
+     */
     double get_fuel_sum(std::map<int, double> fuel_map);
+    /** \brief Function checks if the needed node is existing. If not, it's created
+     * \param subpath: Path to energy node
+     * \param energy_nodes: Name of the final energy node itself
+     * \return A fuel map with int keys corresponding to the energy carrier IDs <[-], [kg]>  
+     */
     std::map<int, double> fuel_map_setup(const std::string& subpath, const std::string& energy_nodes);
+    /** \brief Function checks if the needed node is existing. If not, it's created
+     * \param fuel_map: A fuel map with int keys corresponding to the energy carrier IDs <[-], [kg]>
+     * \param subpath: Path to energy node
+     * \param description: description of the new node
+     * \param energy_carrier_id: Energy carrier ID of the used fuel
+     * \param consumed_energy: Energy which was consumed during the respective fligth segment
+     */
     void update_energy_nodes(const std::map<int, double>& fuel_map, const std::string& subpath,
                                 const std::string& description, Endnode<int>* energy_carrier_id, Endnode<double>* consumed_energy);
     /* Inline auxillary functions */
@@ -334,12 +360,7 @@ class standard_mission : public Strategy {
     inline double static_flight_specific_air_range(const int& energy_carrier_id, const double &mach, const double &altitude, const double &aircraft_mass, const std::string &config,
                                             const std::string &rating, const double &bleed = 0., const double &shaft_power = 0.) {
         const double& required_thrust(this->aero.getCruiseDrag(mach, altitude, 0., aircraft_mass, config, this->atm));
-        try {
-            this->engine.calculate_N1_with_thrustlimit(energy_carrier_id, altitude, mach, atm, 1., rating, bleed, shaft_power, required_thrust);
-        } catch (const int& engine_status) {
-            throwError(__FILE__, __func__, __LINE__,
-                    ("Required thrust (" + num2Str(required_thrust) + " kN) cannot be delivered by engines in current status."));
-        }
+        this->engine.calculate_N1_with_thrustlimit(energy_carrier_id, altitude, mach, atm, 1., rating, bleed, shaft_power, required_thrust);
         return this->aero.getCruiseLoverD(mach, altitude, 0., aircraft_mass, config, atm) * convertUnit(MACH, TRUEAIRSPEED, altitude, this->atm,
                 mach) / this->engine.get_aircraft_fuelflow(energy_carrier_id) * this->engine.get_thrust_aircraft(energy_carrier_id) / aircraft_mass / G_FORCE;
     }
-- 
GitLab


From f50c35fb0bedb89cca813f093e0c87ae18fe6638 Mon Sep 17 00:00:00 2001
From: Gerrit Pauls <gerrit.pauls@tuhh.de>
Date: Thu, 12 Dec 2024 07:55:09 +0100
Subject: [PATCH 2/2] Minor shell output change

---
 .../standard_mission/flight_segments/flight_segments.cpp  | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp
index 395ca07c..8d8b5b50 100644
--- a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp
+++ b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp
@@ -432,12 +432,12 @@ double standard_mission::calculate_climb_or_descent(Operating_conditions* oc, Fl
     Flight_conditions fc_tmp(*fc);
     fc_tmp.delta_h /= steps;
     if (!simulation_mode) {
-        myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step:    " : "Descent step:    ")
+        myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step:           " : "Descent step:         ")
                             << convertUnit(METER, FOOT, fc_tmp.delta_h) << " ft." << std::endl;
-        myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc_tmp.altitude) << " ft." << std::endl;
-        myRuntimeInfo->out << "End altitude    " << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ")
+        myRuntimeInfo->out << "Start altitude:       " << convertUnit(METER, FOOT, fc_tmp.altitude) << " ft." << std::endl;
+        myRuntimeInfo->out << "End altitude" << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ":         ")
                            << convertUnit(METER, FOOT, (fc_tmp.delta_h * steps + fc_tmp.altitude)) << " ft." << std::endl;
-        if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude:    " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl;
+        if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude:  " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl;
     }
     for (uint16_t step_number(0); step_number < steps; ++step_number) {
         this->set_segment_initial_conditions(&fc_tmp, !simulation_mode);
-- 
GitLab