RCAIDE-GUI 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. common_widgets/__init__.py +6 -0
  2. common_widgets/animated_toggle.py +141 -0
  3. common_widgets/color.py +17 -0
  4. common_widgets/data_entry_widget.py +337 -0
  5. common_widgets/image_widget.py +21 -0
  6. common_widgets/unit_picker_widget.py +48 -0
  7. main.py +168 -0
  8. rcaide_gui-1.0.0.dist-info/METADATA +96 -0
  9. rcaide_gui-1.0.0.dist-info/RECORD +170 -0
  10. rcaide_gui-1.0.0.dist-info/WHEEL +5 -0
  11. rcaide_gui-1.0.0.dist-info/entry_points.txt +2 -0
  12. rcaide_gui-1.0.0.dist-info/top_level.txt +5 -0
  13. rcaide_io.py +818 -0
  14. tabs/__init__.py +10 -0
  15. tabs/aircraft_configs/__init__.py +3 -0
  16. tabs/aircraft_configs/aircraft_configs.py +301 -0
  17. tabs/analysis/__init__.py +4 -0
  18. tabs/analysis/analysis.py +92 -0
  19. tabs/analysis/widgets/__init__.py +13 -0
  20. tabs/analysis/widgets/aeroacoustics_widget.py +158 -0
  21. tabs/analysis/widgets/aerodynamics_widget.py +108 -0
  22. tabs/analysis/widgets/analysis_data_widget.py +29 -0
  23. tabs/analysis/widgets/atmosphere_widget.py +49 -0
  24. tabs/analysis/widgets/costs_widget.py +35 -0
  25. tabs/analysis/widgets/energy_widget.py +32 -0
  26. tabs/analysis/widgets/geometry_widget.py +55 -0
  27. tabs/analysis/widgets/planets_widget.py +34 -0
  28. tabs/analysis/widgets/propulsion_widget.py +53 -0
  29. tabs/analysis/widgets/stability_widget.py +34 -0
  30. tabs/analysis/widgets/weights_widget.py +94 -0
  31. tabs/geometry/__init__.py +6 -0
  32. tabs/geometry/aircraft_configs.py +232 -0
  33. tabs/geometry/frames/__init__.py +15 -0
  34. tabs/geometry/frames/booms/__init__.py +5 -0
  35. tabs/geometry/frames/booms/boom_frame.py +238 -0
  36. tabs/geometry/frames/cargo_bays/__init__.py +5 -0
  37. tabs/geometry/frames/cargo_bays/cargo_bay_frame.py +159 -0
  38. tabs/geometry/frames/default_frame.py +23 -0
  39. tabs/geometry/frames/energy_network/__init__.py +2 -0
  40. tabs/geometry/frames/energy_network/turbofan_network/__init__.py +3 -0
  41. tabs/geometry/frames/energy_network/turbofan_network/frames/__init__.py +1 -0
  42. tabs/geometry/frames/energy_network/turbofan_network/widgets/__init__.py +1 -0
  43. tabs/geometry/frames/fuselages/__init__.py +5 -0
  44. tabs/geometry/frames/fuselages/fuselage_frame.py +294 -0
  45. tabs/geometry/frames/geometry_frame.py +91 -0
  46. tabs/geometry/frames/landing_gears/__init__.py +5 -0
  47. tabs/geometry/frames/landing_gears/landing_gear_frame.py +189 -0
  48. tabs/geometry/frames/nacelles/__init__.py +1 -0
  49. tabs/geometry/frames/powertrain/__init__.py +6 -0
  50. tabs/geometry/frames/powertrain/converters/__init__.py +5 -0
  51. tabs/geometry/frames/powertrain/converters/converter_frame.py +137 -0
  52. tabs/geometry/frames/powertrain/distributors/__init__.py +5 -0
  53. tabs/geometry/frames/powertrain/distributors/distributor_frame.py +143 -0
  54. tabs/geometry/frames/powertrain/nacelles/__init__.py +5 -0
  55. tabs/geometry/frames/powertrain/nacelles/nacelle_frame.py +283 -0
  56. tabs/geometry/frames/powertrain/powertrain_frame.py +259 -0
  57. tabs/geometry/frames/powertrain/propulsors/__init__.py +5 -0
  58. tabs/geometry/frames/powertrain/propulsors/propulsor_frame.py +146 -0
  59. tabs/geometry/frames/powertrain/sources/__init__.py +6 -0
  60. tabs/geometry/frames/powertrain/sources/energy_source_frame.py +147 -0
  61. tabs/geometry/frames/vehicle_frame.py +171 -0
  62. tabs/geometry/frames/wings/__init__.py +5 -0
  63. tabs/geometry/frames/wings/wings_frame.py +457 -0
  64. tabs/geometry/geometry.py +513 -0
  65. tabs/geometry/widgets/__init__.py +12 -0
  66. tabs/geometry/widgets/booms/__init__.py +6 -0
  67. tabs/geometry/widgets/booms/boom_section_widget.py +109 -0
  68. tabs/geometry/widgets/cargo_bays/__init__.py +1 -0
  69. tabs/geometry/widgets/fuselages/__init__.py +8 -0
  70. tabs/geometry/widgets/fuselages/cabin_class_widget.py +188 -0
  71. tabs/geometry/widgets/fuselages/cabin_widget.py +217 -0
  72. tabs/geometry/widgets/fuselages/fuselage_section_widget.py +190 -0
  73. tabs/geometry/widgets/geometry_data_widget.py +25 -0
  74. tabs/geometry/widgets/landing_gears/__init__.py +6 -0
  75. tabs/geometry/widgets/nacelles/__init__.py +1 -0
  76. tabs/geometry/widgets/powertrain/__init__.py +9 -0
  77. tabs/geometry/widgets/powertrain/converters/__init__.py +5 -0
  78. tabs/geometry/widgets/powertrain/converters/turboelectric_generator_widget.py +74 -0
  79. tabs/geometry/widgets/powertrain/distributors/__init__.py +5 -0
  80. tabs/geometry/widgets/powertrain/distributors/fuel_line_widget.py +81 -0
  81. tabs/geometry/widgets/powertrain/modulators/__init__.py +5 -0
  82. tabs/geometry/widgets/powertrain/modulators/esc_widget.py +58 -0
  83. tabs/geometry/widgets/powertrain/nacelles/__init__.py +5 -0
  84. tabs/geometry/widgets/powertrain/nacelles/nacelle_section_widget.py +115 -0
  85. tabs/geometry/widgets/powertrain/powertrain_connector_widget.py +136 -0
  86. tabs/geometry/widgets/powertrain/powertrain_widget.py +206 -0
  87. tabs/geometry/widgets/powertrain/propulsors/__init__.py +5 -0
  88. tabs/geometry/widgets/powertrain/propulsors/turbofan_widget.py +462 -0
  89. tabs/geometry/widgets/powertrain/sources/__init__.py +6 -0
  90. tabs/geometry/widgets/powertrain/sources/fuel_tank_widget.py +103 -0
  91. tabs/geometry/widgets/powertrain/sources/source_selector_widget.py +35 -0
  92. tabs/geometry/widgets/wings/__init__.py +7 -0
  93. tabs/geometry/widgets/wings/wing_cs_widget.py +198 -0
  94. tabs/geometry/widgets/wings/wing_section_widget.py +298 -0
  95. tabs/home/__init__.py +3 -0
  96. tabs/home/home.py +585 -0
  97. tabs/mission/__init__.py +4 -0
  98. tabs/mission/mission.py +1124 -0
  99. tabs/mission/widgets/__init__.py +3 -0
  100. tabs/mission/widgets/flight_controls_widget.py +186 -0
  101. tabs/mission/widgets/mission_analysis_widget.py +166 -0
  102. tabs/mission/widgets/mission_segment_helper.py +358 -0
  103. tabs/mission/widgets/mission_segment_widget.py +358 -0
  104. tabs/solve/__init__.py +4 -0
  105. tabs/solve/plots/__init__.py +12 -0
  106. tabs/solve/plots/aeroacoustics/__init__.py +6 -0
  107. tabs/solve/plots/aeroacoustics/plot_2D_noise_contour.py +184 -0
  108. tabs/solve/plots/aeroacoustics/plot_3D_noise_contour.py +219 -0
  109. tabs/solve/plots/aeroacoustics/plot_noise_certification_contour.py +115 -0
  110. tabs/solve/plots/aeroacoustics/plot_noise_level.py +118 -0
  111. tabs/solve/plots/aerodynamics/__init__.py +10 -0
  112. tabs/solve/plots/aerodynamics/plot_aerodynamic_coefficients.py +156 -0
  113. tabs/solve/plots/aerodynamics/plot_aerodynamic_forces.py +155 -0
  114. tabs/solve/plots/aerodynamics/plot_aircraft_aerodynamics.py +136 -0
  115. tabs/solve/plots/aerodynamics/plot_drag_components.py +157 -0
  116. tabs/solve/plots/aerodynamics/plot_lift_distribution.py +107 -0
  117. tabs/solve/plots/aerodynamics/plot_rotor_conditions.py +255 -0
  118. tabs/solve/plots/aerodynamics/plot_rotor_disc_performance.py +144 -0
  119. tabs/solve/plots/aerodynamics/plot_rotor_performance.py +124 -0
  120. tabs/solve/plots/common/__init__.py +4 -0
  121. tabs/solve/plots/common/plot_style.py +71 -0
  122. tabs/solve/plots/common/set_axes.py +55 -0
  123. tabs/solve/plots/create_plot_widgets.py +34 -0
  124. tabs/solve/plots/emissions/__init__.py +3 -0
  125. tabs/solve/plots/emissions/plot_emissions.py +167 -0
  126. tabs/solve/plots/energy/__init__.py +12 -0
  127. tabs/solve/plots/energy/plot_altitude_sfc_weight.py +134 -0
  128. tabs/solve/plots/energy/plot_battery_cell_conditions.py +154 -0
  129. tabs/solve/plots/energy/plot_battery_degradation.py +157 -0
  130. tabs/solve/plots/energy/plot_battery_module_C_rates.py +139 -0
  131. tabs/solve/plots/energy/plot_battery_module_conditions.py +157 -0
  132. tabs/solve/plots/energy/plot_battery_pack_conditions.py +164 -0
  133. tabs/solve/plots/energy/plot_battery_ragone_diagram.py +97 -0
  134. tabs/solve/plots/energy/plot_battery_temperature.py +136 -0
  135. tabs/solve/plots/energy/plot_electric_propulsor_efficiencies.py +136 -0
  136. tabs/solve/plots/energy/plot_propulsor_throttles.py +119 -0
  137. tabs/solve/plots/mission/__init__.py +5 -0
  138. tabs/solve/plots/mission/plot_aircraft_velocities.py +145 -0
  139. tabs/solve/plots/mission/plot_flight_conditions.py +236 -0
  140. tabs/solve/plots/mission/plot_flight_trajectory.py +172 -0
  141. tabs/solve/plots/stability/__init__.py +5 -0
  142. tabs/solve/plots/stability/plot_flight_forces_and_moments.py +163 -0
  143. tabs/solve/plots/stability/plot_lateral_stability.py +151 -0
  144. tabs/solve/plots/stability/plot_longitudinal_stability.py +173 -0
  145. tabs/solve/plots/thermal_management/__init__.py +7 -0
  146. tabs/solve/plots/thermal_management/plot_air_cooled_conditions.py +152 -0
  147. tabs/solve/plots/thermal_management/plot_cross_flow_heat_exchanger_conditions.py +185 -0
  148. tabs/solve/plots/thermal_management/plot_reservoir_conditions.py +141 -0
  149. tabs/solve/plots/thermal_management/plot_thermal_management_performance.py +105 -0
  150. tabs/solve/plots/thermal_management/plot_wavy_channel_conditions.py +161 -0
  151. tabs/solve/plots/weights/__init__.py +4 -0
  152. tabs/solve/plots/weights/plot_load_diagram.py +163 -0
  153. tabs/solve/plots/weights/plot_weight_breakdown.py +164 -0
  154. tabs/solve/solve.py +1498 -0
  155. tabs/style_sheet.py +114 -0
  156. tabs/tab_widget.py +14 -0
  157. tabs/visualize_geometry/__init__.py +4 -0
  158. tabs/visualize_geometry/core_3d_viewer.py +253 -0
  159. tabs/visualize_geometry/features/__init__.py +10 -0
  160. tabs/visualize_geometry/features/axes_gizmo.py +173 -0
  161. tabs/visualize_geometry/features/background.py +161 -0
  162. tabs/visualize_geometry/features/blueprint.py +685 -0
  163. tabs/visualize_geometry/features/camera.py +364 -0
  164. tabs/visualize_geometry/features/drag_aircraft.py +219 -0
  165. tabs/visualize_geometry/features/grid.py +194 -0
  166. tabs/visualize_geometry/features/measurement.py +367 -0
  167. tabs/visualize_geometry/features/screenshot.py +91 -0
  168. tabs/visualize_geometry/geometry_helper_functions.py +3 -0
  169. tabs/visualize_geometry/visualize_geometry.py +731 -0
  170. utilities.py +257 -0
@@ -0,0 +1,167 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/emissions/plot_emissions.py
2
+
3
+ # RCAIDE imports
4
+ from RCAIDE.Framework.Core import Units
5
+ from RCAIDE.Library.Plots.Common import set_axes, plot_style
6
+
7
+ # Python imports
8
+ import matplotlib.pyplot as plt
9
+ import matplotlib.cm as cm
10
+ import numpy as np
11
+
12
+ # ------------------------------------------------------------------------------
13
+ # Plot Emissions
14
+ # ------------------------------------------------------------------------------
15
+ def plot_emissions(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Emissions" ,
19
+ file_type = ".png",
20
+ width = 11, height = 5):
21
+ """
22
+ Generate plots showing CO2-equivalent emissions and emission indexes for various fuel species over mission segments.
23
+
24
+ Parameters
25
+ ----------
26
+ results : Data
27
+ Mission results data structure containing:
28
+ results.segments[i].conditions.emissions.total with fields:
29
+ - CO2 : array
30
+ Carbon dioxide emissions [kg]
31
+ - NOx : array
32
+ Nitrogen oxide emissions [kg]
33
+ - H2O : array
34
+ Water vapor emissions [kg]
35
+ - Contrails : array
36
+ Contrail formation impact [kg CO2e]
37
+ - Soot : array
38
+ Particulate emissions [kg]
39
+ - SO2 : array
40
+ Sulfur dioxide emissions [kg]
41
+
42
+ save_figure : bool, optional
43
+ Save figure to file if True, default False
44
+
45
+ show_legend : bool, optional
46
+ Display segment legend if True, default True
47
+
48
+ save_filename : str, optional
49
+ Name for saved figure file, default "CO2e_Emissions"
50
+
51
+ file_type : str, optional
52
+ File extension for saved figure, default ".png"
53
+
54
+ width : float, optional
55
+ Figure width in inches, default 11
56
+
57
+ height : float, optional
58
+ Figure height in inches, default 7
59
+
60
+ Returns
61
+ -------
62
+ fig : matplotlib.figure.Figure
63
+ Figure showing stacked emissions contributions
64
+
65
+ Notes
66
+ -----
67
+ Creates a stacked area plot showing:
68
+ - Individual contributions from each emission type
69
+ - Cumulative total CO2-equivalent impact
70
+ - Breakdown by mission segment
71
+ - Time history of emissions
72
+
73
+ Different emission types are distinguished by fill colors
74
+ and segments use different shades from the inferno colormap.
75
+
76
+ **Definitions**
77
+
78
+ 'CO2-equivalent (CO2e)'
79
+ Combined climate impact normalized to CO2
80
+
81
+ 'Global Warming Potential (GWP)'
82
+ Relative impact factor for different emissions
83
+
84
+ 'Contrail Impact'
85
+ Climate forcing from aviation-induced cloudiness
86
+ """
87
+
88
+ # get plotting style
89
+ ps = plot_style()
90
+
91
+ parameters = {'axes.labelsize': ps.axis_font_size,
92
+ 'xtick.labelsize': ps.axis_font_size,
93
+ 'ytick.labelsize': ps.axis_font_size,
94
+ 'axes.titlesize': ps.title_font_size}
95
+ plt.rcParams.update(parameters)
96
+
97
+ fig = plt.figure(save_filename)
98
+ fig.set_size_inches(width,height)
99
+
100
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
101
+
102
+ cum_y0 = 0
103
+ cum_y1 = 0
104
+ cum_y1_0 = 0
105
+
106
+ for i in range(len(results.segments)):
107
+ time = results.segments[i].conditions.frames.inertial.time[:, 0] / Units.min
108
+ emissions_CO2 = results.segments[i].conditions.emissions.mass.CO2[:, 0] /1E3
109
+ emissions_CO = results.segments[i].conditions.emissions.mass.CO[:, 0] /1E3
110
+ emissions_NOx = results.segments[i].conditions.emissions.mass.NOx[:, 0] /1E3
111
+ emissions_H2O = results.segments[i].conditions.emissions.mass.H2O[:, 0] /1E3
112
+ EI_CO2 = results.segments[i].conditions.emissions.index.CO2[:, 0]
113
+ EI_CO = results.segments[i].conditions.emissions.index.CO[:, 0]
114
+ EI_NOx = results.segments[i].conditions.emissions.index.NOx[:, 0]
115
+ EI_H2O = results.segments[i].conditions.emissions.index.H2O[:, 0]
116
+ EI_SO2 = results.segments[i].conditions.emissions.index.SO2[:, 0]
117
+
118
+ cum_y0 = np.zeros_like(emissions_CO2)
119
+ cum_y1 = cum_y1_0 + emissions_CO2 + emissions_NOx + emissions_CO + emissions_H2O #+ emissions_Contrails + emissions_Soot + emissions_SO2
120
+
121
+ segment_tag = results.segments[i].tag
122
+ segment_name = segment_tag.replace('_', ' ')
123
+ axis_1 = plt.subplot(1,2,1)
124
+ axis_1.fill_between(time, cum_y0, cum_y1, where=(cum_y0 < cum_y1), color= line_colors[i], interpolate=True, label = segment_name)
125
+ cum_y1_0 = cum_y1[-1]
126
+ axis_1.set_ylabel(r'CO2e Emissions (Metric Tons)')
127
+ axis_1.set_xlabel(r'Time (mins)')
128
+ set_axes(axis_1)
129
+
130
+ axis_2 = plt.subplot(1,2,2)
131
+ if i == 0:
132
+ axis_2.plot(time, EI_CO2, color = line_colors[i], marker = ps.markers[0],markersize = ps.marker_size, linewidth = ps.line_width, label = r"$CO_2$")
133
+ axis_2.plot(time, EI_CO , color = line_colors[i], marker = ps.markers[1],markersize = ps.marker_size, linewidth = ps.line_width, label = r"$CO$" )
134
+ axis_2.plot(time, EI_NOx, color = line_colors[i], marker = ps.markers[2],markersize = ps.marker_size, linewidth = ps.line_width, label = r"$NO_x$")
135
+ axis_2.plot(time, EI_H2O, color = line_colors[i], marker = ps.markers[3],markersize = ps.marker_size, linewidth = ps.line_width, label = r"$H_2O$")
136
+ axis_2.plot(time, EI_SO2, color = line_colors[i], marker = ps.markers[4],markersize = ps.marker_size, linewidth = ps.line_width, label = r"$SO_2$")
137
+ else:
138
+
139
+ axis_2.semilogy(time, EI_CO2, color = line_colors[i], marker = ps.markers[0],markersize = ps.marker_size, linewidth = ps.line_width)
140
+ axis_2.semilogy(time, EI_CO , color = line_colors[i], marker = ps.markers[1],markersize = ps.marker_size, linewidth = ps.line_width)
141
+ axis_2.semilogy(time, EI_NOx, color = line_colors[i], marker = ps.markers[2],markersize = ps.marker_size, linewidth = ps.line_width)
142
+ axis_2.semilogy(time, EI_H2O, color = line_colors[i], marker = ps.markers[3],markersize = ps.marker_size, linewidth = ps.line_width)
143
+ axis_2.semilogy(time, EI_SO2, color = line_colors[i], marker = ps.markers[4],markersize = ps.marker_size, linewidth = ps.line_width)
144
+
145
+ axis_2.set_ylabel(r'Emission Index')
146
+ axis_2.set_xlabel(r'Time (mins)')
147
+ axis_2.minorticks_on()
148
+ axis_2.grid(which='major', linestyle='-', linewidth=0.5, color='grey')
149
+ axis_2.grid(which='minor', linestyle=':', linewidth=0.5, color='grey')
150
+ axis_2.grid(True)
151
+
152
+ if show_legend:
153
+ leg = fig.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 6)
154
+ leg.set_title('Flight Segment', prop={'size': ps.legend_font_size, 'weight': 'heavy'})
155
+
156
+ # Adjusting the sub-plots for legend
157
+
158
+ # set title of plot
159
+ title_text = 'Emissions'
160
+ fig.tight_layout()
161
+ fig.suptitle(title_text)
162
+
163
+ fig.subplots_adjust(top=0.7)
164
+
165
+ if save_figure:
166
+ plt.savefig(save_filename + file_type)
167
+ return fig
@@ -0,0 +1,12 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/__init__.py
2
+
3
+ from .plot_battery_module_conditions import plot_battery_module_conditions
4
+ from .plot_battery_cell_conditions import plot_battery_cell_conditions
5
+ from .plot_battery_degradation import plot_battery_degradation
6
+ from .plot_battery_temperature import plot_battery_temperature
7
+ from .plot_battery_module_C_rates import plot_battery_module_C_rates
8
+ from .plot_battery_pack_conditions import plot_battery_pack_conditions
9
+ from .plot_battery_ragone_diagram import plot_battery_ragone_diagram
10
+ from .plot_electric_propulsor_efficiencies import plot_electric_propulsor_efficiencies
11
+ from .plot_altitude_sfc_weight import plot_altitude_sfc_weight
12
+ from .plot_propulsor_throttles import plot_propulsor_throttles
@@ -0,0 +1,134 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_altitude_sfc_weight.py
2
+
3
+ # RCAIDE imports
4
+ from RCAIDE.Framework.Core import Units
5
+ from RCAIDE.Library.Plots.Common import set_axes, plot_style
6
+
7
+ # Python imports
8
+ import matplotlib.pyplot as plt
9
+ import matplotlib.cm as cm
10
+ import numpy as np
11
+
12
+ # ------------------------------------------------------------------------------
13
+ # Plot Altitude SFC Weight
14
+ # ------------------------------------------------------------------------------
15
+ def plot_altitude_sfc_weight(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Weight_Fuel_Consumption" ,
19
+ file_type = ".png",
20
+ width = 11, height = 7):
21
+ """
22
+ Creates a four-panel plot showing throttle settings, vehicle weight, specific fuel consumption (SFC),
23
+ and fuel consumption rate over time.
24
+
25
+ Parameters
26
+ ----------
27
+ results : Results
28
+ RCAIDE results structure containing segment data
29
+
30
+ save_figure : bool, optional
31
+ Flag for saving the figure (default: False)
32
+
33
+ show_legend : bool, optional
34
+ Flag for displaying plot legend (default: True)
35
+
36
+ save_filename : str, optional
37
+ Name of file for saved figure (default: "Altitude_SFC_Weight")
38
+
39
+ file_type : str, optional
40
+ File extension for saved figure (default: ".png")
41
+
42
+ width : float, optional
43
+ Figure width in inches (default: 11)
44
+
45
+ height : float, optional
46
+ Figure height in inches (default: 7)
47
+
48
+ Returns
49
+ -------
50
+ fig : matplotlib.figure.Figure
51
+ Figure handle containing the generated plots
52
+
53
+ Notes
54
+ -----
55
+ The function creates a 2x2 subplot containing:
56
+ 2. Vehicle weight vs time
57
+ 1. Fuel consumption vs time
58
+ 3. Specific fuel consumption vs time
59
+ 4. Fuel consumption rate vs time
60
+
61
+ Each segment is plotted with a different color from the inferno colormap.
62
+
63
+ **Definitions**
64
+
65
+ 'SFC'
66
+ Specific Fuel Consumption - measure of the fuel efficiency of an engine design
67
+ with respect to thrust output
68
+ """
69
+
70
+ # get plotting style
71
+ ps = plot_style()
72
+
73
+ parameters = {'axes.labelsize': ps.axis_font_size,
74
+ 'xtick.labelsize': ps.axis_font_size,
75
+ 'ytick.labelsize': ps.axis_font_size,
76
+ 'axes.titlesize': ps.title_font_size}
77
+ plt.rcParams.update(parameters)
78
+
79
+ # get line colors for plots
80
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
81
+
82
+ fig = plt.figure(save_filename)
83
+ fig.set_size_inches(width,height)
84
+ axis_1 = plt.subplot(2,2,1)
85
+ axis_2 = plt.subplot(2,2,2)
86
+ axis_3 = plt.subplot(2,2,3)
87
+ axis_4 = plt.subplot(2,2,4)
88
+
89
+ for i in range(len(results.segments)):
90
+ time = results.segments[i].conditions.frames.inertial.time[:, 0] / Units.min
91
+ Weight = (results.segments[i].conditions.weights.total_mass[:, 0] * 9.81) / Units.lbf
92
+ mdot = results.segments[i].conditions.weights.vehicle_mass_rate[:, 0]/ Units.lb
93
+ thrust = abs(results.segments[i].conditions.frames.body.thrust_force_vector[:, 0])/ Units.lbf
94
+ fuel_mass = results.segments[i].conditions.energy.cumulative_fuel_consumption[:, 0]/ Units.lb
95
+
96
+ axis_1.set_ylabel(r'Weight (lbf)')
97
+ axis_2.set_ylabel(r'Fuel Consumption (lb)')
98
+ axis_3.set_ylabel(r'SFC (lb/lbf-hr)')
99
+ axis_4.set_ylabel(r'Fuel Rate (lb/s)')
100
+
101
+ sfc = (mdot ) / (thrust ) * Units.hr
102
+
103
+ segment_tag = results.segments[i].tag
104
+ segment_name = segment_tag.replace('_', ' ')
105
+ axis_1.plot(time, Weight , color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width, label = segment_name )
106
+ set_axes(axis_1)
107
+
108
+ axis_2.plot(time, fuel_mass, color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width)
109
+ axis_2.set_xlabel('Time (mins)')
110
+ set_axes(axis_2)
111
+
112
+ axis_3.plot(time, sfc, color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width)
113
+ axis_3.set_xlabel('Time (mins)')
114
+ set_axes(axis_3)
115
+
116
+ axis_4.plot(time, mdot, color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width)
117
+ axis_4.set_xlabel('Time (mins)')
118
+ set_axes(axis_4)
119
+
120
+
121
+ if show_legend:
122
+ leg = fig.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4)
123
+
124
+ # Adjusting the sub-plots for legend
125
+ fig.tight_layout()
126
+ fig.subplots_adjust(top=0.8)
127
+
128
+ # set title of plot
129
+ title_text = 'Weight and Fuel Consumption'
130
+ fig.suptitle(title_text)
131
+
132
+ if save_figure:
133
+ plt.savefig(save_filename + file_type)
134
+ return fig
@@ -0,0 +1,154 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_cell_conditions.py
2
+
3
+ # RCAIDE imports
4
+ from RCAIDE.Framework.Core import Units
5
+ from RCAIDE.Library.Plots.Common import set_axes, plot_style
6
+
7
+ # Python imports
8
+ import matplotlib.pyplot as plt
9
+ import matplotlib.cm as cm
10
+ import numpy as np
11
+
12
+ # ------------------------------------------------------------------------------
13
+ # Plot Battery Cell Conditions
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_cell_conditions(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Battery_Cell_Conditions_",
19
+ file_type = ".png",
20
+ width = 11, height = 7):
21
+ """
22
+ Creates a six-panel plot showing various battery cell-level conditions throughout flight.
23
+
24
+ Parameters
25
+ ----------
26
+ results : Results
27
+ RCAIDE results structure containing segment data and battery conditions
28
+
29
+ save_figure : bool, optional
30
+ Flag for saving the figure (default: False)
31
+
32
+ show_legend : bool, optional
33
+ Flag for displaying plot legend (default: True)
34
+
35
+ save_filename : str, optional
36
+ Base name of file for saved figure (default: "Battery_Cell_Conditions_")
37
+
38
+ file_type : str, optional
39
+ File extension for saved figure (default: ".png")
40
+
41
+ width : float, optional
42
+ Figure width in inches (default: 11)
43
+
44
+ height : float, optional
45
+ Figure height in inches (default: 7)
46
+
47
+ Returns
48
+ -------
49
+ fig : matplotlib.figure.Figure
50
+ Figure handle containing the generated plots
51
+
52
+ Notes
53
+ -----
54
+ The function creates a 3x2 subplot containing:
55
+ 1. State of Charge (SOC) vs time
56
+ 2. Cell energy vs time
57
+ 3. Cell current vs time
58
+ 4. Cell power vs time
59
+ 5. Cell voltage vs time
60
+ 6. Cell temperature vs time
61
+
62
+ Each segment is plotted with a different color from the inferno colormap.
63
+ For multiple battery modules, each module is distinguished by different markers.
64
+
65
+ **Definitions**
66
+
67
+ 'SOC'
68
+ State of Charge - the level of charge of a battery relative to its capacity
69
+ 'Open Circuit Voltage'
70
+ The voltage across the battery terminals with no load applied
71
+ """
72
+
73
+ # get plotting style
74
+ ps = plot_style()
75
+
76
+ parameters = {'axes.labelsize': ps.axis_font_size,
77
+ 'xtick.labelsize': ps.axis_font_size,
78
+ 'ytick.labelsize': ps.axis_font_size,
79
+ 'axes.titlesize': ps.title_font_size}
80
+ plt.rcParams.update(parameters)
81
+
82
+
83
+ fig = plt.figure(save_filename)
84
+ fig.set_size_inches(width,height)
85
+ # get line colors for plots
86
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
87
+ axis_1 = plt.subplot(3,2,1)
88
+ axis_2 = plt.subplot(3,2,2)
89
+ axis_3 = plt.subplot(3,2,3)
90
+ axis_4 = plt.subplot(3,2,4)
91
+ axis_5 = plt.subplot(3,2,5)
92
+ axis_6 = plt.subplot(3,2,6)
93
+
94
+ for network in results.segments[0].analyses.vehicle.networks:
95
+ busses = network.busses
96
+ for bus_i, bus in enumerate(busses):
97
+ for b_i, battery in enumerate(bus.battery_modules):
98
+ if b_i == 0 or bus.identical_battery_modules == False:
99
+ for i in range(len(results.segments)):
100
+ time = results.segments[i].conditions.frames.inertial.time[:,0] / Units.min
101
+ battery_conditions = results.segments[i].conditions.energy.busses[bus.tag].battery_modules[battery.tag]
102
+ cell_power = battery_conditions.cell.power[:,0]
103
+ cell_energy = battery_conditions.cell.energy[:,0]
104
+ cell_volts = battery_conditions.cell.voltage_under_load[:,0]
105
+ cell_volts_oc = battery_conditions.cell.voltage_open_circuit[:,0]
106
+ cell_current = battery_conditions.cell.current[:,0]
107
+ cell_SOC = battery_conditions.cell.state_of_charge[:,0]
108
+ cell_temperature = battery_conditions.cell.temperature[:,0]
109
+
110
+ segment_tag = results.segments[i].tag
111
+ segment_name = segment_tag.replace('_', ' ')
112
+
113
+ if b_i == 0 and i ==0:
114
+ axis_1.plot(time, cell_SOC, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width, label = battery.tag)
115
+ else:
116
+ axis_1.plot(time, cell_SOC, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
117
+ axis_1.set_ylabel(r'SOC')
118
+ axis_1.set_ylim([0,1.1])
119
+ set_axes(axis_1)
120
+
121
+ axis_2.plot(time, cell_energy/Units.Wh, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
122
+ axis_2.set_ylabel(r'Energy (W-hr)')
123
+ set_axes(axis_2)
124
+
125
+ axis_3.plot(time, cell_current, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
126
+ axis_3.set_ylabel(r'Current (A)')
127
+ set_axes(axis_3)
128
+
129
+ axis_4.plot(time, cell_power, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
130
+ axis_4.set_ylabel(r'Power (W)')
131
+ set_axes(axis_4)
132
+
133
+ axis_5.plot(time, cell_volts, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
134
+ axis_5.set_ylabel(r'Voltage (V)')
135
+ set_axes(axis_5)
136
+
137
+ axis_6.plot(time, cell_temperature, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
138
+ axis_6.set_ylabel(r'Temperature, $\degree$C')
139
+ set_axes(axis_6)
140
+
141
+ if show_legend:
142
+ leg = fig.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4)
143
+
144
+ # Adjusting the sub-plots for legend
145
+ fig.tight_layout()
146
+ fig.subplots_adjust(top=0.8)
147
+
148
+ # set title of plot
149
+ title_text = 'Battery Cell Conditions'
150
+ fig.suptitle(title_text)
151
+
152
+ if save_figure:
153
+ plt.savefig(save_filename + battery.tag + file_type)
154
+ return fig
@@ -0,0 +1,157 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_degradation.py
2
+
3
+ # RCAIDE imports
4
+ from RCAIDE.Framework.Core import Units
5
+ from RCAIDE.Library.Plots.Common import set_axes, plot_style
6
+
7
+ # Python imports
8
+ import matplotlib.pyplot as plt
9
+ import matplotlib.cm as cm
10
+ import numpy as np
11
+
12
+ # ------------------------------------------------------------------------------
13
+ # Plot Battery Degradation
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_degradation(results,
16
+ save_figure = False,
17
+ line_color = 'bo-',
18
+ line_color2 = 'rs--',
19
+ save_filename = "Battery_Degradation",
20
+ file_type = ".png",
21
+ width = 11, height = 7):
22
+ """
23
+ Creates a six-panel plot showing battery degradation metrics against various parameters.
24
+
25
+ Parameters
26
+ ----------
27
+ results : Results
28
+ RCAIDE results structure containing segment data and battery degradation metrics
29
+
30
+ save_figure : bool, optional
31
+ Flag for saving the figure (default: False)
32
+
33
+ line_color : str, optional
34
+ Matplotlib format string for first line style (default: 'bo-')
35
+
36
+ line_color2 : str, optional
37
+ Matplotlib format string for second line style (default: 'rs--')
38
+
39
+ save_filename : str, optional
40
+ Base name of file for saved figure (default: "Battery_Degradation")
41
+
42
+ file_type : str, optional
43
+ File extension for saved figure (default: ".png")
44
+
45
+ width : float, optional
46
+ Figure width in inches (default: 11)
47
+
48
+ height : float, optional
49
+ Figure height in inches (default: 7)
50
+
51
+ Returns
52
+ -------
53
+ fig : matplotlib.figure.Figure
54
+ Figure handle containing the generated plots
55
+
56
+ Notes
57
+ -----
58
+ The function creates a 3x2 subplot showing:
59
+ Left column (Capacity fade vs):
60
+ 1. Charge throughput (Ah)
61
+ 2. Time (hours)
62
+ 3. Time (days)
63
+
64
+ Right column (Resistance growth vs):
65
+ 1. Charge throughput (Ah)
66
+ 2. Time (hours)
67
+ 3. Time (days)
68
+
69
+ **Definitions**
70
+
71
+ 'Capacity Fade'
72
+ The loss of energy storage capacity over time/usage
73
+ 'Resistance Growth'
74
+ The increase in internal resistance over time/usage
75
+ 'Charge Throughput'
76
+ The cumulative amount of charge that has passed through the battery
77
+ """
78
+ # get plotting style
79
+ ps = plot_style()
80
+
81
+ parameters = {'axes.labelsize': ps.axis_font_size,
82
+ 'xtick.labelsize': ps.axis_font_size,
83
+ 'ytick.labelsize': ps.axis_font_size,
84
+ 'axes.titlesize': ps.title_font_size}
85
+ plt.rcParams.update(parameters)
86
+
87
+
88
+ for network in results.segments[0].analyses.vehicle.networks:
89
+ busses = network.busses
90
+ for bus in busses:
91
+ if bus.identical_battery_modules:
92
+ for i, battery in enumerate(bus.battery_modules):
93
+ if i == 0:
94
+ fig = plt.figure(save_filename + '_' + battery.tag)
95
+ fig.set_size_inches(width,height)
96
+ num_segs = len(results.segments)
97
+ time_hrs = np.zeros(num_segs)
98
+ capacity_fade = np.zeros_like(time_hrs)
99
+ resistance_growth = np.zeros_like(time_hrs)
100
+ cycle_day = np.zeros_like(time_hrs)
101
+ charge_throughput = np.zeros_like(time_hrs)
102
+
103
+ for i in range(len(results.segments)):
104
+ time_hrs[i] = results.segments[i].conditions.frames.inertial.time[-1,0] / Units.hour
105
+ battery_conditions = results.segments[i].conditions.energy.busses[bus.tag].battery_modules[battery.tag]
106
+ cycle_day[i] = battery_conditions.cell.cycle_in_day
107
+ capacity_fade[i] = battery_conditions.cell.capacity_fade_factor
108
+ resistance_growth[i] = battery_conditions.cell.resistance_growth_factor
109
+ charge_throughput[i] = battery_conditions.cell.charge_throughput[-1,0]
110
+
111
+ axis_1 = plt.subplot(3,2,1)
112
+ axis_1.plot(charge_throughput, capacity_fade, color = ps.color , marker = ps.markers[0], linewidth = ps.line_width )
113
+ axis_1.set_ylabel('$E/E_0$')
114
+ axis_1.set_xlabel('Ah')
115
+ set_axes(axis_1)
116
+
117
+ axis_2 = plt.subplot(3,2,3)
118
+ axis_2.plot(time_hrs, capacity_fade, color = ps.color, marker = ps.markers[0], linewidth = ps.line_width )
119
+ axis_2.set_ylabel('$E/E_0$')
120
+ axis_2.set_xlabel('Time (hrs)')
121
+ set_axes(axis_2)
122
+
123
+ axis_3 = plt.subplot(3,2,5)
124
+ axis_3.plot(cycle_day, capacity_fade, color = ps.color, marker = ps.markers[0], linewidth = ps.line_width )
125
+ axis_3.set_ylabel('$E/E_0$')
126
+ axis_3.set_xlabel('Time (days)')
127
+ set_axes(axis_3)
128
+
129
+ axis_4 = plt.subplot(3,2,2)
130
+ axis_4.plot(charge_throughput, resistance_growth, color = ps.color, marker = ps.markers[0], linewidth = ps.line_width )
131
+ axis_4.set_ylabel('$R/R_0$')
132
+ axis_4.set_xlabel('Ah')
133
+ set_axes(axis_4)
134
+
135
+ axis_5 = plt.subplot(3,2,4)
136
+ axis_5.plot(time_hrs, resistance_growth, color = ps.color, marker = ps.markers[0], linewidth = ps.line_width )
137
+ axis_5.set_ylabel('$R/R_0$')
138
+ axis_5.set_xlabel('Time (hrs)')
139
+ set_axes(axis_5)
140
+
141
+ axis_6 = plt.subplot(3,2,6)
142
+ axis_6.plot(cycle_day, resistance_growth, color = ps.color, marker = ps.markers[0], linewidth = ps.line_width )
143
+ axis_6.set_ylabel('$R/R_0$')
144
+ axis_6.set_xlabel('Time (days)')
145
+ set_axes(axis_6)
146
+
147
+
148
+ # set title of plot
149
+ title_text = 'Battery Cell Degradation: ' + battery.tag
150
+ fig.suptitle(title_text)
151
+
152
+ plt.tight_layout()
153
+ if save_figure:
154
+ fig.savefig(save_filename + '_'+ battery.tag + file_type)
155
+
156
+ return fig
157
+