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,139 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_module_C_rates.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 Module C Rates
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_module_C_rates(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Battery_Module_C_Rates",
19
+ file_type =".png",
20
+ width = 8,
21
+ height = 6):
22
+ """
23
+ Creates a two-panel plot showing instantaneous and nominal C-rates of battery modules during operation.
24
+
25
+ Parameters
26
+ ----------
27
+ results : Results
28
+ RCAIDE results structure containing segment data and battery conditions
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
+ Base name of file for saved figure (default: "Battery_Module_C_Rates")
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: 8)
44
+
45
+ height : float, optional
46
+ Figure height in inches (default: 6)
47
+
48
+ Returns
49
+ -------
50
+ fig : matplotlib.figure.Figure
51
+
52
+ Notes
53
+ -----
54
+ The function creates a 1x2 subplot showing:
55
+ 1. Instantaneous C-rate vs time
56
+ 2. Nominal C-rate vs time
57
+
58
+ Different segments are plotted with different colors using the inferno colormap.
59
+ For multiple battery modules, only non-identical modules are plotted.
60
+
61
+ **Major Assumptions**
62
+
63
+ * For identical battery modules, only the first module's data is plotted
64
+ * Time is converted from seconds to minutes for plotting
65
+ * Battery energy is converted to Watt-hours for calculations
66
+
67
+ **Definitions**
68
+
69
+ 'C-rate'
70
+ A measure of the rate at which a battery is discharged relative to its capacity
71
+ 'Instantaneous C-rate'
72
+ C-rate calculated using the current battery capacity
73
+ 'Nominal C-rate'
74
+ C-rate calculated using the maximum battery capacity
75
+ """
76
+
77
+ # get plotting style
78
+ ps = plot_style()
79
+
80
+ parameters = {'axes.labelsize': ps.axis_font_size,
81
+ 'xtick.labelsize': ps.axis_font_size,
82
+ 'ytick.labelsize': ps.axis_font_size,
83
+ 'axes.titlesize': ps.title_font_size}
84
+ plt.rcParams.update(parameters)
85
+
86
+
87
+ fig = plt.figure(save_filename)
88
+ fig.set_size_inches(width,height)
89
+ # get line colors for plots
90
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
91
+ axis_1 = plt.subplot(1,2,1)
92
+ axis_2 = plt.subplot(1,2,2)
93
+
94
+ for network in results.segments[0].analyses.vehicle.networks:
95
+ busses = network.busses
96
+ for bus in 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
+ module_energy = battery_conditions.energy[:,0]
103
+ module_volts = battery_conditions.voltage_under_load[:,0]
104
+ module_current = battery_conditions.current[:,0]
105
+ module_battery_amp_hr = (module_energy/ Units.Wh )/module_volts
106
+ module_C_instant = module_current/module_battery_amp_hr
107
+ module_C_nominal = module_current/np.max(module_battery_amp_hr)
108
+
109
+ if i == 0 and i ==0:
110
+ axis_1.plot(time, module_C_instant, color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width, label = battery.tag)
111
+ else:
112
+ axis_1.plot(time, module_C_instant, color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width)
113
+ axis_1.set_ylabel(r'Inst. C-Rate (C)')
114
+ axis_1.set_xlabel('Time (mins)')
115
+ set_axes(axis_1)
116
+
117
+ axis_2.plot(time, module_C_nominal, color = line_colors[i], marker = ps.markers[0], linewidth = ps.line_width)
118
+ axis_2.set_ylabel(r'Nom. C-Rate (C)')
119
+ axis_2.set_xlabel('Time (mins)')
120
+ set_axes(axis_2)
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 = 'Battery Cell Conditions'
130
+ fig.suptitle(title_text)
131
+
132
+ if save_figure:
133
+ plt.savefig(save_filename + battery.tag + file_type)
134
+ return fig
135
+
136
+
137
+ return
138
+
139
+
@@ -0,0 +1,157 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_module_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 Module Conditions
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_module_conditions(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Battery_Module_Conditions_",
19
+ file_type = ".png",
20
+ width = 11, height = 7):
21
+ """
22
+ Creates a six-panel plot showing various battery module-level conditions throughout flight.
23
+
24
+ Parameters
25
+ ----------
26
+ results : Results
27
+ RCAIDE results structure containing segment data and battery module 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_Module_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
+
51
+ Notes
52
+ -----
53
+ The function creates a 3x2 subplot containing:
54
+ 1. State of Charge (SOC) vs time
55
+ 2. Module energy vs time
56
+ 3. Module current vs time
57
+ 4. Module power vs time
58
+ 5. Module voltage vs time
59
+ 6. Module temperature vs time
60
+
61
+ Each segment is plotted with a different color from the inferno colormap.
62
+ Different battery modules are distinguished by different markers.
63
+
64
+ **Major Assumptions**
65
+
66
+ * For identical battery modules, only the first module's data is plotted
67
+ * Time is converted from seconds to minutes for plotting
68
+ * Energy is converted to Watt-hours for display
69
+
70
+ **Definitions**
71
+
72
+ 'SOC'
73
+ State of Charge - the level of charge of the battery module relative to its capacity
74
+ 'Module Power'
75
+ Total electrical power of the battery module
76
+ 'Module Energy'
77
+ Cumulative energy stored/discharged by the battery module
78
+ """
79
+
80
+ # get plotting style
81
+ ps = plot_style()
82
+
83
+ parameters = {'axes.labelsize': ps.axis_font_size,
84
+ 'xtick.labelsize': ps.axis_font_size,
85
+ 'ytick.labelsize': ps.axis_font_size,
86
+ 'axes.titlesize': ps.title_font_size}
87
+ plt.rcParams.update(parameters)
88
+
89
+
90
+ fig = plt.figure(save_filename)
91
+ fig.set_size_inches(width,height)
92
+ # get line colors for plots
93
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
94
+ axis_1 = plt.subplot(3,2,1)
95
+ axis_2 = plt.subplot(3,2,2)
96
+ axis_3 = plt.subplot(3,2,3)
97
+ axis_4 = plt.subplot(3,2,4)
98
+ axis_5 = plt.subplot(3,2,5)
99
+ axis_6 = plt.subplot(3,2,6)
100
+
101
+ for network in results.segments[0].analyses.vehicle.networks:
102
+ busses = network.busses
103
+ for bus in busses:
104
+ for b_i, battery in enumerate(bus.battery_modules):
105
+ if b_i == 0 or bus.identical_battery_modules == False:
106
+ for i in range(len(results.segments)):
107
+ time = results.segments[i].conditions.frames.inertial.time[:,0] / Units.min
108
+ battery_conditions = results.segments[i].conditions.energy.busses[bus.tag].battery_modules[battery.tag]
109
+ module_power = battery_conditions.power[:,0]
110
+ module_energy = battery_conditions.energy[:,0]
111
+ module_volts = battery_conditions.voltage_under_load[:,0]
112
+ module_current = battery_conditions.current[:,0]
113
+ module_SOC = battery_conditions.cell.state_of_charge[:,0]
114
+ module_temperature = battery_conditions.temperature[:,0]
115
+
116
+ if b_i == 0 and i ==0:
117
+ axis_1.plot(time, module_SOC, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width, label = battery.tag)
118
+ else:
119
+ axis_1.plot(time, module_SOC, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
120
+ axis_1.set_ylabel(r'SOC')
121
+ axis_1.set_ylim([0,1.1])
122
+ set_axes(axis_1)
123
+
124
+ axis_2.plot(time, module_energy/Units.Wh, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
125
+ axis_2.set_ylabel(r'Energy (W-hr)')
126
+ set_axes(axis_2)
127
+
128
+ axis_3.plot(time, module_current, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
129
+ axis_3.set_ylabel(r'Current (A)')
130
+ set_axes(axis_3)
131
+
132
+ axis_4.plot(time, module_power, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
133
+ axis_4.set_ylabel(r'Power (W)')
134
+ set_axes(axis_4)
135
+
136
+ axis_5.plot(time, module_volts, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
137
+ axis_5.set_ylabel(r'Voltage (V)')
138
+ set_axes(axis_5)
139
+
140
+ axis_6.plot(time, module_temperature, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
141
+ axis_6.set_ylabel(r'Temperature, $\degree$C')
142
+ set_axes(axis_6)
143
+
144
+ if show_legend:
145
+ leg = fig.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4)
146
+
147
+ # Adjusting the sub-plots for legend
148
+ fig.tight_layout()
149
+ fig.subplots_adjust(top=0.8)
150
+
151
+ # set title of plot
152
+ title_text = 'Battery Module Conditions'
153
+ fig.suptitle(title_text)
154
+
155
+ if save_figure:
156
+ plt.savefig(save_filename + battery.tag + file_type)
157
+ return fig
@@ -0,0 +1,164 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_pack_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 Pack Conditions
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_pack_conditions(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Battery_Pack_Conditions_",
19
+ file_type = ".png",
20
+ width = 11, height = 7):
21
+ """
22
+ Creates a six-panel plot showing various battery pack-level conditions throughout flight.
23
+
24
+ Parameters
25
+ ----------
26
+ results : Results
27
+ RCAIDE results structure containing segment data and battery pack 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_Pack_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
+
51
+ Notes
52
+ -----
53
+ The function creates a 3x2 subplot containing:
54
+ 1. State of Charge (SOC) vs time
55
+ 2. Pack energy vs time
56
+ 3. Pack current vs time
57
+ 4. Pack power vs time
58
+ 5. Pack voltage vs time
59
+ 6. Pack temperature vs time
60
+
61
+ Each segment is plotted with a different color from the inferno colormap.
62
+ Different battery modules are distinguished by different markers.
63
+
64
+ **Major Assumptions**
65
+
66
+ * Time is converted from seconds to minutes for plotting
67
+ * Energy is converted to Watt-hours for display
68
+
69
+ **Definitions**
70
+
71
+ 'SOC'
72
+ State of Charge - the level of charge of the battery pack relative to its capacity
73
+ 'Module Power'
74
+ Total electrical power of the battery pack
75
+ 'Module Energy'
76
+ Cumulative energy stored/discharged by the battery pack
77
+ """
78
+
79
+ # get plotting style
80
+ ps = plot_style()
81
+
82
+ parameters = {'axes.labelsize': ps.axis_font_size,
83
+ 'xtick.labelsize': ps.axis_font_size,
84
+ 'ytick.labelsize': ps.axis_font_size,
85
+ 'axes.titlesize': ps.title_font_size}
86
+ plt.rcParams.update(parameters)
87
+
88
+
89
+ fig = plt.figure(save_filename)
90
+ fig.set_size_inches(width,height)
91
+ # get line colors for plots
92
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
93
+ axis_1 = plt.subplot(3,2,1)
94
+ axis_2 = plt.subplot(3,2,2)
95
+ axis_3 = plt.subplot(3,2,3)
96
+ axis_4 = plt.subplot(3,2,4)
97
+ axis_5 = plt.subplot(3,2,5)
98
+ axis_6 = plt.subplot(3,2,6)
99
+
100
+ for network in results.segments[0].analyses.vehicle.networks:
101
+ busses = network.busses
102
+ for b_i , bus in enumerate(busses):
103
+ for i in range(len(results.segments)):
104
+ no_modules = len(bus.battery_modules)
105
+ bus_config = bus.battery_module_electric_configuration
106
+ battery_module_tag = list(bus.battery_modules.keys())[0]
107
+
108
+ time = results.segments[i].conditions.frames.inertial.time[:,0] / Units.min
109
+ battery_conditions = results.segments[i].conditions.energy.busses[bus.tag].battery_modules[battery_module_tag]
110
+
111
+ if bus_config == 'Series':
112
+ pack_current = battery_conditions.current[:,0]
113
+ pack_volts = battery_conditions.voltage_under_load[:,0] * no_modules
114
+ elif bus_config == 'Parallel':
115
+ pack_current = battery_conditions.current[:,0] * no_modules
116
+ pack_volts = battery_conditions.voltage_under_load[:,0]
117
+
118
+ pack_power = battery_conditions.power[:,0] * no_modules
119
+ pack_energy = battery_conditions.energy[:,0] * no_modules
120
+ pack_SOC = battery_conditions.cell.state_of_charge[:,0]
121
+ pack_temperature = battery_conditions.temperature[:,0]
122
+
123
+ if b_i == 0 and i ==0:
124
+ axis_1.plot(time, pack_SOC, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width, label = bus.tag)
125
+ else:
126
+ axis_1.plot(time, pack_SOC, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
127
+ axis_1.set_ylabel(r'SOC')
128
+ axis_1.set_ylim([0,1.1])
129
+ set_axes(axis_1)
130
+
131
+ axis_2.plot(time, pack_energy/1000/Units.Wh, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
132
+ axis_2.set_ylabel(r'Energy (kW-hr)')
133
+ set_axes(axis_2)
134
+
135
+ axis_3.plot(time, pack_current/1000, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
136
+ axis_3.set_ylabel(r'Current (kA)')
137
+ set_axes(axis_3)
138
+
139
+ axis_4.plot(time, pack_power/1000, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
140
+ axis_4.set_ylabel(r'Power (kW)')
141
+ set_axes(axis_4)
142
+
143
+ axis_5.plot(time, pack_volts/1000, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
144
+ axis_5.set_ylabel(r'Voltage (kV)')
145
+ set_axes(axis_5)
146
+
147
+ axis_6.plot(time, pack_temperature, color = line_colors[i], marker = ps.markers[b_i], linewidth = ps.line_width)
148
+ axis_6.set_ylabel(r'Temperature, $\degree$C')
149
+ set_axes(axis_6)
150
+
151
+ if show_legend:
152
+ leg = fig.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4)
153
+
154
+ # Adjusting the sub-plots for legend
155
+ fig.tight_layout()
156
+ fig.subplots_adjust(top=0.8)
157
+
158
+ # set title of plot
159
+ title_text = 'Battery Pack Conditions'
160
+ fig.suptitle(title_text)
161
+
162
+ if save_figure:
163
+ plt.savefig(save_filename + file_type)
164
+ return fig
@@ -0,0 +1,97 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_ragone_diagram.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 Ragone Diagram
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_ragone_diagram(battery,
16
+ save_figure = False,
17
+ save_filename = "Ragone_Plot",
18
+ file_type = ".png",
19
+ width = 11, height = 7):
20
+ """
21
+ Creates a Ragone plot showing the relationship between specific power and specific energy of a battery.
22
+
23
+ Parameters
24
+ ----------
25
+ battery : Battery
26
+ RCAIDE battery object containing Ragone characteristics
27
+
28
+ save_figure : bool, optional
29
+ Flag for saving the figure (default: False)
30
+
31
+ save_filename : str, optional
32
+ Name of file for saved figure (default: "Ragone_Plot")
33
+
34
+ file_type : str, optional
35
+ File extension for saved figure (default: ".png")
36
+
37
+ width : float, optional
38
+ Figure width in inches (default: 11)
39
+
40
+ height : float, optional
41
+ Figure height in inches (default: 7)
42
+
43
+ Returns
44
+ -------
45
+ fig : matplotlib.figure.Figure
46
+ Figure handle containing the generated Ragone plot
47
+
48
+ Notes
49
+ -----
50
+ The Ragone plot is a performance map showing the tradeoff between specific power
51
+ and specific energy in energy storage devices. The plot uses logarithmic scales
52
+ to display the wide range of values.
53
+
54
+ **Major Assumptions**
55
+
56
+ * Battery characteristics follow the Ragone relationship:
57
+ P = const_1 * 10^(E * const_2)
58
+ * Specific energy range is defined by upper and lower bounds
59
+ * Values are converted to standard units (kW/kg and Wh/kg)
60
+
61
+ **Definitions**
62
+
63
+ 'Specific Power'
64
+ Power output per unit mass (kW/kg)
65
+ 'Specific Energy'
66
+ Energy storage capacity per unit mass (Wh/kg)
67
+ 'Ragone Plot'
68
+ Performance visualization showing the tradeoff between power and energy density
69
+ """
70
+
71
+ # get plotting style
72
+ ps = plot_style()
73
+
74
+ parameters = {'axes.labelsize': ps.axis_font_size,
75
+ 'xtick.labelsize': ps.axis_font_size,
76
+ 'ytick.labelsize': ps.axis_font_size,
77
+ 'axes.titlesize': ps.title_font_size}
78
+ plt.rcParams.update(parameters)
79
+
80
+ fig = plt.figure(save_filename)
81
+ fig.set_size_inches(width,height)
82
+
83
+ axis_1 = plt.subplot(1,1,1)
84
+ esp_plot = np.linspace(battery.cell.ragone.lower_bound, battery.cell.ragone.upper_bound,50)
85
+ psp_plot = battery.cell.ragone.const_1*10**(esp_plot*battery.cell.ragone.const_2)
86
+ axis_1.plot(esp_plot/(Units.Wh/Units.kg),psp_plot/(Units.kW/Units.kg), color = 'black', marker = ps.markers[0], linewidth = ps.line_width, label= battery.tag)
87
+ axis_1.set_ylabel('Specific Power (kW/kg)')
88
+ axis_1.set_xlabel('Specific Energy (W-h/kg)')
89
+ set_axes(axis_1)
90
+
91
+ # set title of plot
92
+ title_text = 'Battery Ragone Plot'
93
+ fig.suptitle(title_text)
94
+
95
+ if save_figure:
96
+ plt.savefig(save_filename + file_type)
97
+ return fig
@@ -0,0 +1,136 @@
1
+ # RCAIDE_GUI/tabs/solve/plots/energy/plot_battery_temperature.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 Temperature
14
+ # ------------------------------------------------------------------------------
15
+ def plot_battery_temperature(results,
16
+ save_figure = False,
17
+ show_legend = True,
18
+ save_filename = "Battery_Temperature",
19
+ file_type = ".png",
20
+ width = 11, height = 7):
21
+ """
22
+ Creates a three-panel plot showing battery thermal conditions and related parameters throughout flight.
23
+
24
+ Parameters
25
+ ----------
26
+ results : Results
27
+ RCAIDE results structure containing segment data and battery thermal 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
+ Name of file for saved figure (default: "Battery_Temperature")
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
+
51
+ Notes
52
+ -----
53
+ The function creates a 2x2 subplot containing:
54
+ 1. Cell temperature vs time
55
+ 2. Charge throughput vs time
56
+ 3. Heat generation rate vs time
57
+
58
+ Each segment is plotted with a different color from the inferno colormap.
59
+ Different battery modules are distinguished by different markers.
60
+
61
+ **Major Assumptions**
62
+
63
+ * For identical battery modules, only the first module's data is plotted
64
+ * Time is converted from seconds to minutes for plotting
65
+ * Heat generation rate is converted to kilowatts for display
66
+
67
+ **Definitions**
68
+
69
+ 'Charge Throughput'
70
+ Cumulative amount of charge that has passed through the battery (Ah)
71
+ 'Heat Generation Rate'
72
+ Rate of thermal energy production in the battery (kW)
73
+ """
74
+
75
+ # get plotting style
76
+ ps = plot_style()
77
+
78
+ parameters = {'axes.labelsize': ps.axis_font_size,
79
+ 'xtick.labelsize': ps.axis_font_size,
80
+ 'ytick.labelsize': ps.axis_font_size,
81
+ 'axes.titlesize': ps.title_font_size}
82
+ plt.rcParams.update(parameters)
83
+
84
+ # get line colors for plots
85
+ line_colors = cm.inferno(np.linspace(0,0.9,len(results.segments)))
86
+
87
+ fig = plt.figure(save_filename)
88
+ fig.set_size_inches(width,height)
89
+ axis_1 = plt.subplot(2,2,1)
90
+ axis_2 = plt.subplot(2,2,2)
91
+ axis_3 = plt.subplot(2,2,3)
92
+
93
+ for network in results.segments[0].analyses.vehicle.networks:
94
+ busses = network.busses
95
+ for bus_i, bus in enumerate(busses):
96
+ for b_i, battery in enumerate(bus.battery_modules):
97
+ if b_i == 0 or bus.identical_battery_modules == False:
98
+ for i in range(len(results.segments)):
99
+ bus_results = results.segments[i].conditions.energy.busses[bus.tag]
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_temp = battery_conditions.cell.temperature[:,0]
103
+ cell_charge = battery_conditions.cell.charge_throughput[:,0]
104
+ pack_Q = bus_results.heat_energy_generated[:,0]
105
+
106
+ if b_i == 0 and i == 0:
107
+ axis_1.plot(time,cell_temp, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width, label = battery.tag)
108
+ else:
109
+ axis_1.plot(time,cell_temp, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
110
+ axis_1.set_ylabel(r'Temperature (K)')
111
+ set_axes(axis_1)
112
+
113
+ axis_2.plot(time, cell_charge, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
114
+ axis_2.set_xlabel('Time (mins)')
115
+ axis_2.set_ylabel(r'Charge Throughput (Ah)')
116
+ set_axes(axis_2)
117
+
118
+ axis_3.plot(time, pack_Q/1000, color = line_colors[i], marker = ps.markers[bus_i], linewidth = ps.line_width)
119
+ axis_3.set_xlabel('Time (mins)')
120
+ axis_3.set_ylabel(r'$\dot{Q}_{heat}$ (kW)')
121
+ set_axes(axis_3)
122
+
123
+ if show_legend:
124
+ leg = fig.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4)
125
+
126
+ # Adjusting the sub-plots for legend
127
+ fig.tight_layout()
128
+ fig.subplots_adjust(top=0.8)
129
+
130
+ # set title of plot
131
+ title_text = 'Battery Temperature'
132
+ fig.suptitle(title_text)
133
+
134
+ if save_figure:
135
+ plt.savefig(save_filename + file_type)
136
+ return fig