RCAIDE-GUI 1.0.4__tar.gz → 1.0.5__tar.gz

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 (191) hide show
  1. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/PKG-INFO +1 -1
  2. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/RCAIDE_GUI.egg-info/PKG-INFO +1 -1
  3. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/RCAIDE_GUI.egg-info/SOURCES.txt +16 -0
  4. rcaide_gui-1.0.5/VERSION +1 -0
  5. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/common_widgets/data_entry_widget.py +108 -106
  6. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/main.py +5 -6
  7. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/rcaide_io.py +139 -27
  8. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/__init__.py +6 -5
  9. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/fuselages/fuselage_frame.py +1 -0
  10. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/distributors/distributor_frame.py +11 -0
  11. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/powertrain_frame.py +28 -63
  12. rcaide_gui-1.0.5/tabs/geometry/frames/powertrain/systems/__init__.py +1 -0
  13. rcaide_gui-1.0.5/tabs/geometry/frames/powertrain/systems/system_frame.py +85 -0
  14. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/geometry.py +77 -17
  15. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/__init__.py +1 -0
  16. rcaide_gui-1.0.5/tabs/geometry/widgets/powertrain/distributors/fuel_line_widget.py +130 -0
  17. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/powertrain_connector_widget.py +13 -10
  18. rcaide_gui-1.0.5/tabs/geometry/widgets/powertrain/powertrain_widget.py +186 -0
  19. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/propulsors/turbofan_widget.py +3 -1
  20. rcaide_gui-1.0.5/tabs/geometry/widgets/powertrain/systems/__init__.py +1 -0
  21. rcaide_gui-1.0.5/tabs/geometry/widgets/powertrain/systems/system_widget.py +124 -0
  22. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/home/home.py +1 -1
  23. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/mission.py +15 -1
  24. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/widgets/flight_controls_widget.py +9 -9
  25. rcaide_gui-1.0.5/tabs/performance/__init__.py +3 -0
  26. rcaide_gui-1.0.5/tabs/performance/analysis_registry.py +563 -0
  27. rcaide_gui-1.0.5/tabs/performance/performance.py +885 -0
  28. rcaide_gui-1.0.5/tabs/performance/results_tracker.py +89 -0
  29. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/results_viewer/results_viewer.py +237 -39
  30. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/solve.py +12 -29
  31. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/visualize_geometry.py +34 -17
  32. rcaide_gui-1.0.4/VERSION +0 -1
  33. rcaide_gui-1.0.4/tabs/geometry/widgets/powertrain/distributors/fuel_line_widget.py +0 -81
  34. rcaide_gui-1.0.4/tabs/geometry/widgets/powertrain/powertrain_widget.py +0 -206
  35. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/LICENSE +0 -0
  36. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/RCAIDE_GUI.egg-info/dependency_links.txt +0 -0
  37. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/RCAIDE_GUI.egg-info/entry_points.txt +0 -0
  38. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/RCAIDE_GUI.egg-info/requires.txt +0 -0
  39. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/RCAIDE_GUI.egg-info/top_level.txt +0 -0
  40. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/README.md +0 -0
  41. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/README_PyPI.md +0 -0
  42. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/common_widgets/__init__.py +0 -0
  43. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/common_widgets/animated_toggle.py +0 -0
  44. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/common_widgets/color.py +0 -0
  45. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/common_widgets/image_widget.py +0 -0
  46. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/common_widgets/unit_picker_widget.py +0 -0
  47. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/pyproject.toml +0 -0
  48. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/setup.cfg +0 -0
  49. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/setup.py +0 -0
  50. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/aircraft_configs/__init__.py +0 -0
  51. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/aircraft_configs/aircraft_configs.py +0 -0
  52. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/__init__.py +0 -0
  53. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/analysis.py +0 -0
  54. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/__init__.py +0 -0
  55. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/aeroacoustics_widget.py +0 -0
  56. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/aerodynamics_widget.py +0 -0
  57. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/analysis_data_widget.py +0 -0
  58. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/atmosphere_widget.py +0 -0
  59. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/costs_widget.py +0 -0
  60. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/energy_widget.py +0 -0
  61. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/geometry_widget.py +0 -0
  62. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/planets_widget.py +0 -0
  63. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/propulsion_widget.py +0 -0
  64. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/stability_widget.py +0 -0
  65. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/analysis/widgets/weights_widget.py +0 -0
  66. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/__init__.py +0 -0
  67. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/aircraft_configs.py +0 -0
  68. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/__init__.py +0 -0
  69. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/booms/__init__.py +0 -0
  70. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/booms/boom_frame.py +0 -0
  71. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/cargo_bays/__init__.py +0 -0
  72. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/cargo_bays/cargo_bay_frame.py +0 -0
  73. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/default_frame.py +0 -0
  74. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/energy_network/__init__.py +0 -0
  75. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/energy_network/turbofan_network/__init__.py +0 -0
  76. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/energy_network/turbofan_network/frames/__init__.py +0 -0
  77. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/energy_network/turbofan_network/widgets/__init__.py +0 -0
  78. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/fuselages/__init__.py +0 -0
  79. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/geometry_frame.py +0 -0
  80. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/landing_gears/__init__.py +0 -0
  81. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/landing_gears/landing_gear_frame.py +0 -0
  82. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/nacelles/__init__.py +0 -0
  83. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/__init__.py +0 -0
  84. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/converters/__init__.py +0 -0
  85. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/converters/converter_frame.py +0 -0
  86. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/distributors/__init__.py +0 -0
  87. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/nacelles/__init__.py +0 -0
  88. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/nacelles/nacelle_frame.py +0 -0
  89. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/propulsors/__init__.py +0 -0
  90. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/propulsors/propulsor_frame.py +0 -0
  91. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/sources/__init__.py +0 -0
  92. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/powertrain/sources/energy_source_frame.py +0 -0
  93. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/vehicle_frame.py +0 -0
  94. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/wings/__init__.py +0 -0
  95. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/frames/wings/wings_frame.py +0 -0
  96. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/__init__.py +0 -0
  97. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/booms/__init__.py +0 -0
  98. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/booms/boom_section_widget.py +0 -0
  99. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/cargo_bays/__init__.py +0 -0
  100. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/fuselages/__init__.py +0 -0
  101. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/fuselages/cabin_class_widget.py +0 -0
  102. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/fuselages/cabin_widget.py +0 -0
  103. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/fuselages/fuselage_section_widget.py +0 -0
  104. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/geometry_data_widget.py +0 -0
  105. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/landing_gears/__init__.py +0 -0
  106. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/nacelles/__init__.py +0 -0
  107. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/converters/__init__.py +0 -0
  108. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/converters/turboelectric_generator_widget.py +0 -0
  109. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/distributors/__init__.py +0 -0
  110. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/modulators/__init__.py +0 -0
  111. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/modulators/esc_widget.py +0 -0
  112. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/nacelles/__init__.py +0 -0
  113. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/nacelles/nacelle_section_widget.py +0 -0
  114. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/propulsors/__init__.py +0 -0
  115. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/sources/__init__.py +0 -0
  116. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/sources/fuel_tank_widget.py +0 -0
  117. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/powertrain/sources/source_selector_widget.py +0 -0
  118. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/wings/__init__.py +0 -0
  119. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/wings/wing_cs_widget.py +0 -0
  120. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/geometry/widgets/wings/wing_section_widget.py +0 -0
  121. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/home/__init__.py +0 -0
  122. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/__init__.py +0 -0
  123. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/widgets/__init__.py +0 -0
  124. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/widgets/mission_analysis_widget.py +0 -0
  125. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/widgets/mission_segment_helper.py +0 -0
  126. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/mission/widgets/mission_segment_widget.py +0 -0
  127. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/results_viewer/__init__.py +0 -0
  128. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/__init__.py +0 -0
  129. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/__init__.py +0 -0
  130. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aeroacoustics/__init__.py +0 -0
  131. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aeroacoustics/plot_2D_noise_contour.py +0 -0
  132. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aeroacoustics/plot_3D_noise_contour.py +0 -0
  133. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aeroacoustics/plot_noise_certification_contour.py +0 -0
  134. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aeroacoustics/plot_noise_level.py +0 -0
  135. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/__init__.py +0 -0
  136. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_aerodynamic_coefficients.py +0 -0
  137. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_aerodynamic_forces.py +0 -0
  138. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_aircraft_aerodynamics.py +0 -0
  139. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_drag_components.py +0 -0
  140. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_lift_distribution.py +0 -0
  141. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_rotor_conditions.py +0 -0
  142. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_rotor_disc_performance.py +0 -0
  143. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/aerodynamics/plot_rotor_performance.py +0 -0
  144. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/common/__init__.py +0 -0
  145. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/common/plot_style.py +0 -0
  146. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/common/set_axes.py +0 -0
  147. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/create_plot_widgets.py +0 -0
  148. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/emissions/__init__.py +0 -0
  149. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/emissions/plot_emissions.py +0 -0
  150. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/__init__.py +0 -0
  151. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_altitude_sfc_weight.py +0 -0
  152. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_cell_conditions.py +0 -0
  153. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_degradation.py +0 -0
  154. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_module_C_rates.py +0 -0
  155. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_module_conditions.py +0 -0
  156. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_pack_conditions.py +0 -0
  157. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_ragone_diagram.py +0 -0
  158. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_battery_temperature.py +0 -0
  159. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_electric_propulsor_efficiencies.py +0 -0
  160. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/energy/plot_propulsor_throttles.py +0 -0
  161. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/mission/__init__.py +0 -0
  162. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/mission/plot_aircraft_velocities.py +0 -0
  163. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/mission/plot_flight_conditions.py +0 -0
  164. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/mission/plot_flight_trajectory.py +0 -0
  165. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/stability/__init__.py +0 -0
  166. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/stability/plot_flight_forces_and_moments.py +0 -0
  167. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/stability/plot_lateral_stability.py +0 -0
  168. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/stability/plot_longitudinal_stability.py +0 -0
  169. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/thermal_management/__init__.py +0 -0
  170. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/thermal_management/plot_air_cooled_conditions.py +0 -0
  171. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/thermal_management/plot_cross_flow_heat_exchanger_conditions.py +0 -0
  172. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/thermal_management/plot_reservoir_conditions.py +0 -0
  173. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/thermal_management/plot_thermal_management_performance.py +0 -0
  174. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/thermal_management/plot_wavy_channel_conditions.py +0 -0
  175. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/weights/__init__.py +0 -0
  176. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/weights/plot_load_diagram.py +0 -0
  177. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/solve/plots/weights/plot_weight_breakdown.py +0 -0
  178. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/style_sheet.py +0 -0
  179. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/tab_widget.py +0 -0
  180. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/__init__.py +0 -0
  181. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/__init__.py +0 -0
  182. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/axes_gizmo.py +0 -0
  183. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/background.py +0 -0
  184. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/blueprint.py +0 -0
  185. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/camera.py +0 -0
  186. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/drag_aircraft.py +0 -0
  187. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/grid.py +0 -0
  188. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/measurement.py +0 -0
  189. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/features/screenshot.py +0 -0
  190. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/tabs/visualize_geometry/geometry_helper_functions.py +0 -0
  191. {rcaide_gui-1.0.4 → rcaide_gui-1.0.5}/utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RCAIDE-GUI
3
- Version: 1.0.4
3
+ Version: 1.0.5
4
4
  Summary: RCAIDE Graphical User Interface: interactive desktop application for aircraft design and analysis
5
5
  License: MIT License
6
6
  Classifier: Development Status :: 4 - Beta
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RCAIDE-GUI
3
- Version: 1.0.4
3
+ Version: 1.0.5
4
4
  Summary: RCAIDE Graphical User Interface: interactive desktop application for aircraft design and analysis
5
5
  License: MIT License
6
6
  Classifier: Development Status :: 4 - Beta
@@ -67,6 +67,8 @@ utilities.py
67
67
  ./tabs/geometry/frames/powertrain/propulsors/propulsor_frame.py
68
68
  ./tabs/geometry/frames/powertrain/sources/__init__.py
69
69
  ./tabs/geometry/frames/powertrain/sources/energy_source_frame.py
70
+ ./tabs/geometry/frames/powertrain/systems/__init__.py
71
+ ./tabs/geometry/frames/powertrain/systems/system_frame.py
70
72
  ./tabs/geometry/frames/wings/__init__.py
71
73
  ./tabs/geometry/frames/wings/wings_frame.py
72
74
  ./tabs/geometry/widgets/__init__.py
@@ -96,6 +98,8 @@ utilities.py
96
98
  ./tabs/geometry/widgets/powertrain/sources/__init__.py
97
99
  ./tabs/geometry/widgets/powertrain/sources/fuel_tank_widget.py
98
100
  ./tabs/geometry/widgets/powertrain/sources/source_selector_widget.py
101
+ ./tabs/geometry/widgets/powertrain/systems/__init__.py
102
+ ./tabs/geometry/widgets/powertrain/systems/system_widget.py
99
103
  ./tabs/geometry/widgets/wings/__init__.py
100
104
  ./tabs/geometry/widgets/wings/wing_cs_widget.py
101
105
  ./tabs/geometry/widgets/wings/wing_section_widget.py
@@ -108,6 +112,10 @@ utilities.py
108
112
  ./tabs/mission/widgets/mission_analysis_widget.py
109
113
  ./tabs/mission/widgets/mission_segment_helper.py
110
114
  ./tabs/mission/widgets/mission_segment_widget.py
115
+ ./tabs/performance/__init__.py
116
+ ./tabs/performance/analysis_registry.py
117
+ ./tabs/performance/performance.py
118
+ ./tabs/performance/results_tracker.py
111
119
  ./tabs/results_viewer/__init__.py
112
120
  ./tabs/results_viewer/results_viewer.py
113
121
  ./tabs/solve/__init__.py
@@ -236,6 +244,8 @@ tabs/geometry/frames/powertrain/propulsors/__init__.py
236
244
  tabs/geometry/frames/powertrain/propulsors/propulsor_frame.py
237
245
  tabs/geometry/frames/powertrain/sources/__init__.py
238
246
  tabs/geometry/frames/powertrain/sources/energy_source_frame.py
247
+ tabs/geometry/frames/powertrain/systems/__init__.py
248
+ tabs/geometry/frames/powertrain/systems/system_frame.py
239
249
  tabs/geometry/frames/wings/__init__.py
240
250
  tabs/geometry/frames/wings/wings_frame.py
241
251
  tabs/geometry/widgets/__init__.py
@@ -265,6 +275,8 @@ tabs/geometry/widgets/powertrain/propulsors/turbofan_widget.py
265
275
  tabs/geometry/widgets/powertrain/sources/__init__.py
266
276
  tabs/geometry/widgets/powertrain/sources/fuel_tank_widget.py
267
277
  tabs/geometry/widgets/powertrain/sources/source_selector_widget.py
278
+ tabs/geometry/widgets/powertrain/systems/__init__.py
279
+ tabs/geometry/widgets/powertrain/systems/system_widget.py
268
280
  tabs/geometry/widgets/wings/__init__.py
269
281
  tabs/geometry/widgets/wings/wing_cs_widget.py
270
282
  tabs/geometry/widgets/wings/wing_section_widget.py
@@ -277,6 +289,10 @@ tabs/mission/widgets/flight_controls_widget.py
277
289
  tabs/mission/widgets/mission_analysis_widget.py
278
290
  tabs/mission/widgets/mission_segment_helper.py
279
291
  tabs/mission/widgets/mission_segment_widget.py
292
+ tabs/performance/__init__.py
293
+ tabs/performance/analysis_registry.py
294
+ tabs/performance/performance.py
295
+ tabs/performance/results_tracker.py
280
296
  tabs/results_viewer/__init__.py
281
297
  tabs/results_viewer/results_viewer.py
282
298
  tabs/solve/__init__.py
@@ -0,0 +1 @@
1
+ 1.0.5
@@ -1,10 +1,10 @@
1
1
  # RCAIDE_GUI/tabs/visualize_geometry/features/axes_gizmo.py
2
2
 
3
- # Created: M Clarke, LEADS, 2024
4
- # Python imports
5
- import ast
6
-
7
- from PyQt6.QtCore import Qt, pyqtSignal
3
+ # Created: M Clarke, LEADS, 2024
4
+ # Python imports
5
+ import ast
6
+
7
+ from PyQt6.QtCore import Qt, pyqtSignal
8
8
  from PyQt6.QtGui import QDoubleValidator
9
9
  from PyQt6.QtWidgets import QLineEdit, QLabel, QGridLayout, QWidget, QSizePolicy, QSpacerItem, QCheckBox, QHBoxLayout, \
10
10
  QVBoxLayout
@@ -94,12 +94,12 @@ class DataEntryWidget(QWidget):
94
94
  grid_layout.addLayout(layout, row, 0, 1, 4)
95
95
  col = num_cols - 1
96
96
  self.data_fields[label[0]] = ()
97
- else:
98
- line_edit = QLineEdit(self)
99
- # Inertia tensors are entered as list/matrix text, not scalar floats.
100
- if label[1] != Units.Intertia:
101
- line_edit.setValidator(QDoubleValidator())
102
- line_edit.setMinimumWidth(150)
97
+ else:
98
+ line_edit = QLineEdit(self)
99
+ # Inertia tensors are entered as list/matrix text, not scalar floats.
100
+ if label[1] != Units.Intertia:
101
+ line_edit.setValidator(QDoubleValidator())
102
+ line_edit.setMinimumWidth(150)
103
103
 
104
104
  unit_picker = UnitPickerWidget(label[1])
105
105
  unit_picker.on_change_callback = self._make_unit_change_handler(
@@ -143,17 +143,17 @@ class DataEntryWidget(QWidget):
143
143
  return si_value
144
144
  return (si_value - zero) / scale
145
145
 
146
- @staticmethod
147
- def _format_converted_value(value):
148
- return f"{value:.15g}"
149
-
150
- @staticmethod
151
- def _parse_list_value(text):
152
- # Use literal_eval so list-like fields become Python lists without eval.
153
- value = ast.literal_eval(text)
154
- if not isinstance(value, list):
155
- raise ValueError(f"Expected a list value, got {type(value).__name__}")
156
- return value
146
+ @staticmethod
147
+ def _format_converted_value(value):
148
+ return f"{value:.15g}"
149
+
150
+ @staticmethod
151
+ def _parse_list_value(text):
152
+ # Use literal_eval so list-like fields become Python lists without eval.
153
+ value = ast.literal_eval(text)
154
+ if not isinstance(value, list):
155
+ raise ValueError(f"Expected a list value, got {type(value).__name__}")
156
+ return value
157
157
 
158
158
  def _make_unit_change_handler(self, unit_picker, *line_edits):
159
159
  def convert_display_values(previous_index, new_index):
@@ -216,30 +216,30 @@ class DataEntryWidget(QWidget):
216
216
  z_value]], unit_picker.current_index
217
217
  elif self.data_units_labels[i][1] == Units.Heading:
218
218
  continue
219
- elif self.data_units_labels[i][1] == Units.Count:
220
- data_field = self.data_fields[label]
221
- line_edit, unit_picker = data_field
222
- text = line_edit.text()
223
- # Count fields should remain integers for RCAIDE.
224
- value = int(text) if text else 0
225
- data[label] = value, unit_picker.current_index
226
- elif self.data_units_labels[i][1] == Units.Intertia:
227
- data_field = self.data_fields[label]
228
- line_edit, unit_picker = data_field
229
- text = line_edit.text()
230
- # Inertia is stored as a tensor/list, not a single scalar.
231
- value = self._parse_list_value(text) if text else None
232
- data[label] = value, unit_picker.current_index
233
- else:
234
- data_field = self.data_fields[label]
235
- line_edit, unit_picker = data_field
236
- text = line_edit.text()
237
- # Most fields are numeric, but some Unitless fields are text labels.
238
- try:
239
- value = float(text) if text else None
240
- except ValueError:
241
- value = text
242
- data[label] = value, unit_picker.current_index
219
+ elif self.data_units_labels[i][1] == Units.Count:
220
+ data_field = self.data_fields[label]
221
+ line_edit, unit_picker = data_field
222
+ text = line_edit.text()
223
+ # Count fields should remain integers for RCAIDE.
224
+ value = int(text) if text else 0
225
+ data[label] = value, unit_picker.current_index
226
+ elif self.data_units_labels[i][1] == Units.Intertia:
227
+ data_field = self.data_fields[label]
228
+ line_edit, unit_picker = data_field
229
+ text = line_edit.text()
230
+ # Inertia is stored as a tensor/list, not a single scalar.
231
+ value = self._parse_list_value(text) if text else None
232
+ data[label] = value, unit_picker.current_index
233
+ else:
234
+ data_field = self.data_fields[label]
235
+ line_edit, unit_picker = data_field
236
+ text = line_edit.text()
237
+ # Most fields are numeric, but some Unitless fields are text labels.
238
+ try:
239
+ value = float(text) if text else None
240
+ except ValueError:
241
+ value = text
242
+ data[label] = value, unit_picker.current_index
243
243
  return data
244
244
 
245
245
  def get_values_si(self):
@@ -266,68 +266,70 @@ class DataEntryWidget(QWidget):
266
266
  z_value]], unit_picker.current_index
267
267
  elif self.data_units_labels[i][1] == Units.Heading:
268
268
  continue
269
- elif self.data_units_labels[i][1] == Units.Count:
270
- data_field = self.data_fields[label]
271
- line_edit, unit_picker = data_field
272
- text = line_edit.text()
273
- # Count fields should remain integers for RCAIDE.
274
- value = int(text) if text else 0
275
- data[label] = value, unit_picker.current_index
276
- elif self.data_units_labels[i][1] == Units.Intertia:
277
- data_field = self.data_fields[label]
278
- line_edit, unit_picker = data_field
279
- text = line_edit.text()
280
- # Inertia is stored as a tensor/list, not a single scalar.
281
- value = self._parse_list_value(text) if text else None
282
- data[label] = value, unit_picker.current_index
283
- else:
284
- data_field = self.data_fields[label]
285
- line_edit, unit_picker = data_field
286
- text = line_edit.text()
287
- # Numeric fields are converted to SI; text fields are preserved.
288
- try:
289
- value = unit_picker.apply_unit(float(text)) if text else None
290
- except ValueError:
291
- value = text
292
- data[label] = value, unit_picker.current_index
269
+ elif self.data_units_labels[i][1] == Units.Count:
270
+ data_field = self.data_fields[label]
271
+ line_edit, unit_picker = data_field
272
+ text = line_edit.text()
273
+ # Count fields should remain integers for RCAIDE.
274
+ value = int(text) if text else 0
275
+ data[label] = value, unit_picker.current_index
276
+ elif self.data_units_labels[i][1] == Units.Intertia:
277
+ data_field = self.data_fields[label]
278
+ line_edit, unit_picker = data_field
279
+ text = line_edit.text()
280
+ # Inertia is stored as a tensor/list, not a single scalar.
281
+ value = self._parse_list_value(text) if text else None
282
+ data[label] = value, unit_picker.current_index
283
+ else:
284
+ data_field = self.data_fields[label]
285
+ line_edit, unit_picker = data_field
286
+ text = line_edit.text()
287
+ # Numeric fields are converted to SI; text fields are preserved.
288
+ try:
289
+ value = unit_picker.apply_unit(float(text)) if text else None
290
+ except ValueError:
291
+ value = text
292
+ data[label] = value, unit_picker.current_index
293
293
  return data
294
294
 
295
- def load_data(self, data):
296
- # Loading saved data should not trigger auto-save.
297
- old_block_state = self.blockSignals(True)
298
- try:
299
- # Load each field based on its input type.
300
- for i, label in enumerate(self.data_fields.keys()):
301
- if self.data_units_labels[i][1] == Units.Boolean:
302
- # Checkbox field.
303
- self.data_fields[label].setChecked(data[label][0])
304
- elif self.data_units_labels[i][1] == Units.Position:
305
- # Three coordinate boxes and one unit picker.
306
- x_line_edit, y_line_edit, z_line_edit, unit_picker = self.data_fields[label]
307
- value, index = data[label]
308
- # Unwrap [[x, y, z]] if needed.
309
- if isinstance(value, list) and value and isinstance(value[0], list):
310
- value = value[0]
311
- # Use origin if the saved value is invalid.
312
- elif not isinstance(value, list):
313
- value = [0, 0, 0]
314
- x_line_edit.setText(str(value[0]))
315
- y_line_edit.setText(str(value[1]))
316
- z_line_edit.setText(str(value[2]))
317
- unit_picker.set_index(index)
318
- elif self.data_units_labels[i][1] == Units.Heading:
319
- # Heading label only.
320
- pass
321
- else:
322
- # Normal value field and unit picker.
323
- line_edit, unit_picker = self.data_fields[label]
324
- value, index = data[label]
325
- # Show None as an empty field.
326
- line_edit.setText("" if value is None else str(value))
327
- unit_picker.set_index(index)
328
- finally:
329
- # Restore signal behavior.
330
- self.blockSignals(old_block_state)
295
+ def load_data(self, data):
296
+ # Loading saved data should not trigger auto-save.
297
+ old_block_state = self.blockSignals(True)
298
+ try:
299
+ # Load each field based on its input type.
300
+ for i, label in enumerate(self.data_fields.keys()):
301
+ if label not in data:
302
+ continue
303
+ if self.data_units_labels[i][1] == Units.Boolean:
304
+ # Checkbox field.
305
+ self.data_fields[label].setChecked(data[label][0])
306
+ elif self.data_units_labels[i][1] == Units.Position:
307
+ # Three coordinate boxes and one unit picker.
308
+ x_line_edit, y_line_edit, z_line_edit, unit_picker = self.data_fields[label]
309
+ value, index = data[label]
310
+ # Unwrap [[x, y, z]] if needed.
311
+ if isinstance(value, list) and value and isinstance(value[0], list):
312
+ value = value[0]
313
+ # Use origin if the saved value is invalid.
314
+ elif not isinstance(value, list):
315
+ value = [0, 0, 0]
316
+ x_line_edit.setText(str(value[0]))
317
+ y_line_edit.setText(str(value[1]))
318
+ z_line_edit.setText(str(value[2]))
319
+ unit_picker.set_index(index)
320
+ elif self.data_units_labels[i][1] == Units.Heading:
321
+ # Heading label only.
322
+ pass
323
+ else:
324
+ # Normal value field and unit picker.
325
+ line_edit, unit_picker = self.data_fields[label]
326
+ value, index = data[label]
327
+ # Show None as an empty field.
328
+ line_edit.setText("" if value is None else str(value))
329
+ unit_picker.set_index(index)
330
+ finally:
331
+ # Restore signal behavior.
332
+ self.blockSignals(old_block_state)
331
333
 
332
334
  # TODO implement mark_save and changed_since_save
333
335
  def mark_save(self):
@@ -57,14 +57,13 @@ class App(QMainWindow):
57
57
  self.widgets = []
58
58
  self.widgets.append((home.get_widget(), "Home"))
59
59
  self.widgets.append((geometry.get_widget(), "Vehicle Setup"))
60
- self.widgets.append((visualize_geometry.get_widget(), "Geometry Visualization"))
61
- self.widgets.append((aircraft_configs.get_widget(), "Configurations Setup"))
60
+ self.widgets.append((visualize_geometry.get_widget(), "Geometry"))
61
+ self.widgets.append((aircraft_configs.get_widget(), "Configurations"))
62
62
  self.widgets.append((analysis.get_widget(), "Analyses Setup"))
63
63
  self.widgets.append((mission.get_widget(), "Mission Setup"))
64
- self.widgets.append((solve.get_widget(), "Mission Simulation"))
65
- # Results Viewer reads the last mission.evaluate() output stored in rcaide_io.rcaide_results.
64
+ self.widgets.append((performance.get_widget(), "Performance"))
65
+ self.widgets.append((solve.get_widget(), "Run Mission"))
66
66
  self.widgets.append((results_viewer.get_widget(), "Results Viewer"))
67
- # self.widgets.append((shared_analysis_widget, "Multidisciplinary Analyses"))
68
67
 
69
68
  for widget, name in self.widgets:
70
69
  self.tabs.addTab(widget, name)
@@ -142,7 +141,7 @@ class App(QMainWindow):
142
141
 
143
142
  def _go_to_geometry_visualization_tab(self):
144
143
  for index in range(self.tabs.count()):
145
- if self.tabs.tabText(index).strip().lower() == "geometry visualization":
144
+ if self.tabs.tabText(index).strip().lower() == "geometry":
146
145
  self.tabs.setCurrentIndex(index)
147
146
  current_widget = self.tabs.widget(index)
148
147
  if isinstance(current_widget, TabWidget):
@@ -415,6 +415,10 @@ rcaide_mission = RCAIDE.Framework.Mission.Sequential_Segments()
415
415
  # Last in-memory mission output. Set by the Solve tab after mission.evaluate()
416
416
  # and browsed by the Results Viewer so users can inspect values without rerunning.
417
417
  rcaide_results = None
418
+ # Last raw result from the Performance tab. Set after each analysis run so the
419
+ # Results Viewer can browse it (stability derivatives, polar arrays, etc.).
420
+ last_performance_result = None
421
+ last_performance_label = ""
418
422
 
419
423
 
420
424
  # ----------------------------------------------------------------------------------------------------------------------
@@ -441,6 +445,138 @@ def vehicle_to_ui_format(vehicle_obj):
441
445
  return ui_dict
442
446
 
443
447
 
448
+ _NETWORK_TYPE_LABEL = {
449
+ 'Fuel': 'Fuel',
450
+ 'Electric': 'Electric',
451
+ 'Hybrid': 'Hybrid',
452
+ 'Hydrogen': 'Hydrogen',
453
+ 'Fuel_Cell': 'Fuel Cell',
454
+ }
455
+
456
+
457
+ def _network_type_for_ui(network_dict):
458
+ type_str = network_dict.get('__type__', '')
459
+ class_name = type_str.rsplit('.', 1)[-1] if type_str else ''
460
+ return _NETWORK_TYPE_LABEL.get(class_name, 'Fuel')
461
+
462
+
463
+ def _propulsor_dict_to_ui(p):
464
+ """Convert a RCAIDE Turbofan JSON dict (unit-argument format) to TurbofanWidget GUI format."""
465
+ def g(d, *keys):
466
+ for k in keys[:-1]:
467
+ d = d.get(k, {}) if isinstance(d, dict) else {}
468
+ return d.get(keys[-1], [0, 0]) if isinstance(d, dict) else [0, 0]
469
+
470
+ return {
471
+ 'Propulsor Tag': p.get('tag', ''),
472
+ 'Origin': g(p, 'origin'),
473
+ 'Engine Length': g(p, 'length'),
474
+ 'Diameter': g(p, 'diameter'),
475
+ 'Bypass Ratio': g(p, 'bypass_ratio'),
476
+ 'Design Altitude': g(p, 'design_altitude'),
477
+ 'Design Mach Number': g(p, 'design_mach_number'),
478
+ 'Design Thrust': g(p, 'design_thrust'),
479
+ 'Fan Polytropic Efficiency': g(p, 'fan', 'polytropic_efficiency'),
480
+ 'Fan Pressure Ratio': g(p, 'fan', 'pressure_ratio'),
481
+ 'Inlet Nozzle Polytropic Efficiency': g(p, 'inlet_nozzle', 'polytropic_efficiency'),
482
+ 'Inlet Nozzle Pressure Ratio': g(p, 'inlet_nozzle', 'pressure_ratio'),
483
+ 'LPC Polytropic Efficiency': g(p, 'low_pressure_compressor', 'polytropic_efficiency'),
484
+ 'LPC Pressure Ratio': g(p, 'low_pressure_compressor', 'pressure_ratio'),
485
+ 'HPC Polytropic Efficiency': g(p, 'high_pressure_compressor', 'polytropic_efficiency'),
486
+ 'HPC Pressure Ratio': g(p, 'high_pressure_compressor', 'pressure_ratio'),
487
+ 'LPT Mechanical Efficiency': g(p, 'low_pressure_turbine', 'mechanical_efficiency'),
488
+ 'LPT Polytropic Efficiency': g(p, 'low_pressure_turbine', 'polytropic_efficiency'),
489
+ 'HPT Mechanical Efficiency': g(p, 'high_pressure_turbine', 'mechanical_efficiency'),
490
+ 'HPT Polytropic Efficiency': g(p, 'high_pressure_turbine', 'polytropic_efficiency'),
491
+ 'Combustor Efficiency': g(p, 'combustor', 'efficiency'),
492
+ 'Combustor Pressure Loss Coeff': g(p, 'combustor', 'alphac'),
493
+ 'Combustor Turbine Inlet Temp': g(p, 'combustor', 'turbine_inlet_temperature'),
494
+ 'Combustor Pressure Ratio': g(p, 'combustor', 'pressure_ratio'),
495
+ 'Core Nozzle Polytropic Efficiency': g(p, 'core_nozzle', 'polytropic_efficiency'),
496
+ 'Core Nozzle Pressure Ratio': g(p, 'core_nozzle', 'pressure_ratio'),
497
+ 'Fan Nozzle Polytropic Efficiency': g(p, 'fan_nozzle', 'polytropic_efficiency'),
498
+ 'Fan Nozzle Pressure Ratio': g(p, 'fan_nozzle', 'pressure_ratio'),
499
+ }
500
+
501
+
502
+ def _distributor_dict_to_ui(fl):
503
+ """Convert a RCAIDE Fuel_Line/Bus/Coolant_Line JSON dict to distributor GUI format."""
504
+ assigned_raw = fl.get('assigned_propulsors', [])
505
+ if is_unit_argument_pair(assigned_raw):
506
+ assigned_raw = assigned_raw[0]
507
+ if assigned_raw and isinstance(assigned_raw[0], list):
508
+ assigned_propulsors = list(assigned_raw[0])
509
+ else:
510
+ assigned_propulsors = [x for x in assigned_raw if isinstance(x, str)]
511
+
512
+ tanks = fl.get('fuel_tanks', {})
513
+ assigned_sources = (
514
+ [k for k in tanks.keys() if k != '__type__']
515
+ if isinstance(tanks, dict) else []
516
+ )
517
+ return {
518
+ 'distributor name': fl.get('tag', ''),
519
+ 'assigned_propulsors': assigned_propulsors,
520
+ 'assigned_sources': assigned_sources,
521
+ }
522
+
523
+
524
+ def _fuel_tank_dict_to_ui(tank):
525
+ """Convert a RCAIDE Fuel_Tank JSON dict to FuelTankWidget GUI format."""
526
+ def g(d, key):
527
+ return d.get(key, [0, 0]) if isinstance(d, dict) else [0, 0]
528
+ return {
529
+ 'Source Name': tank.get('tag', ''),
530
+ 'Fuel Tank Origin': g(tank, 'origin'),
531
+ 'Fuel Origin': g(tank, 'fuel_origin'),
532
+ 'Center of Gravity': g(tank, 'center_of_gravity'),
533
+ 'Mass': g(tank, 'mass_of_fuel'),
534
+ 'Internal Volume': g(tank, 'volume'),
535
+ }
536
+
537
+
538
+ def _network_dict_to_ui(net_dict):
539
+ """Convert one RCAIDE network JSON dict to the PowertrainFrame GUI data format."""
540
+ net_type = _network_type_for_ui(net_dict)
541
+
542
+ propulsor_data = []
543
+ propulsors = net_dict.get('propulsors', {})
544
+ if isinstance(propulsors, dict):
545
+ for k, v in propulsors.items():
546
+ if k == '__type__' or not isinstance(v, dict):
547
+ continue
548
+ propulsor_data.append(_propulsor_dict_to_ui(v))
549
+
550
+ distributor_data = []
551
+ source_by_tag = {}
552
+ for container_key in ('fuel_lines', 'busses', 'coolant_lines'):
553
+ container = net_dict.get(container_key, {})
554
+ if not isinstance(container, dict):
555
+ continue
556
+ for k, fl in container.items():
557
+ if k == '__type__' or not isinstance(fl, dict):
558
+ continue
559
+ distributor_data.append(_distributor_dict_to_ui(fl))
560
+ tanks = fl.get('fuel_tanks', {})
561
+ if isinstance(tanks, dict):
562
+ for t_key, t_val in tanks.items():
563
+ if t_key != '__type__' and isinstance(t_val, dict) and t_key not in source_by_tag:
564
+ source_by_tag[t_key] = t_val
565
+
566
+ source_data = [_fuel_tank_dict_to_ui(v) for v in source_by_tag.values()]
567
+
568
+ return {
569
+ 'energy network selected': net_type,
570
+ 'powertrain': {
571
+ 'distributor data': distributor_data,
572
+ 'source data': source_data,
573
+ 'propulsor data': propulsor_data,
574
+ 'system data': [],
575
+ 'converter data': [],
576
+ }
577
+ }
578
+
579
+
444
580
  def vehicle_dict_to_ui_list_structure(vehicle_dict):
445
581
  """Convert a stripped rcaide_vehicle dict to the 7-slot UI structure."""
446
582
  from tabs.geometry.frames.booms.boom_frame import BoomFrame
@@ -663,34 +799,10 @@ def vehicle_dict_to_ui_list_structure(vehicle_dict):
663
799
  if "powertrains" in vehicle_dict and vehicle_dict["powertrains"]:
664
800
  ui_structure[5] = [to_ui_format(p, PowertrainFrame) for p in vehicle_dict["powertrains"].values() if is_mapping(p)]
665
801
  elif "networks" in vehicle_dict and vehicle_dict["networks"]:
666
- for network in vehicle_dict["networks"].values():
667
- if not is_mapping(network):
802
+ for k, network in vehicle_dict["networks"].items():
803
+ if k == "__type__" or not is_mapping(network):
668
804
  continue
669
- network_tag = network.get("tag", "Fuel").title()
670
- propulsors = network.get("propulsors", {})
671
- if propulsors:
672
- for propulsor in propulsors.values():
673
- if not is_mapping(propulsor):
674
- continue
675
- ui_structure[5].append({
676
- "name": propulsor.get("tag", network_tag),
677
- "energy network selected": network_tag,
678
- "powertrain": {
679
- "distributor data": [], "source data": [],
680
- "propulsor data": [], "converter data": [],
681
- "connections": [],
682
- }
683
- })
684
- else:
685
- ui_structure[5].append({
686
- "name": network_tag,
687
- "energy network selected": network_tag,
688
- "powertrain": {
689
- "distributor data": [], "source data": [],
690
- "propulsor data": [], "converter data": [],
691
- "connections": [],
692
- }
693
- })
805
+ ui_structure[5].append(_network_dict_to_ui(network))
694
806
 
695
807
  if "wings" in vehicle_dict and vehicle_dict["wings"]:
696
808
  ui_structure[6] = [to_ui_format(w, WingsFrame) for w in vehicle_dict["wings"].values() if is_mapping(w)]
@@ -1,12 +1,13 @@
1
- # RCAIDE_GUI/tabs/__init__.py
2
- from .tab_widget import *
3
- from . import aircraft_configs
4
- from . import analysis
1
+ # RCAIDE_GUI/tabs/__init__.py
2
+ from .tab_widget import *
3
+ from . import aircraft_configs
4
+ from . import analysis
5
5
  from . import geometry
6
6
  from . import home
7
7
  from . import mission
8
8
  # Exposes the post-simulation results browser as a main application tab.
9
+ from . import performance
9
10
  from . import results_viewer
10
11
  from . import solve
11
12
  from . import visualize_geometry
12
-
13
+
@@ -37,6 +37,7 @@ class FuselageFrame(GeometryFrame):
37
37
  ("Area Front Projected", Units.Area, "areas.front_projected"),
38
38
  ("Differential Pressure", Units.Pressure, "differential_pressure"),
39
39
  ("Effective Diameter", Units.Length, "effective_diameter"),
40
+ ("Operational Items Origin", Units.Position, "operational_items.origin"),
40
41
  ]
41
42
 
42
43
  def __init__(self):
@@ -127,6 +127,17 @@ class DistributorFrame(QWidget):
127
127
 
128
128
  widget.index = i
129
129
 
130
+ def refresh_connections(self, propulsor_names: list[str], source_names: list[str]):
131
+ """Push current propulsor and source names into each distributor's inline checkboxes."""
132
+ for i in range(self.distributor_sections_layout.count()):
133
+ item = self.distributor_sections_layout.itemAt(i)
134
+ if item is None:
135
+ continue
136
+ widget = item.widget()
137
+ if isinstance(widget, FuelLineWidget):
138
+ widget.set_propulsors(propulsor_names)
139
+ widget.set_sources(source_names)
140
+
130
141
  def set_save_function(self, function):
131
142
  self.save_function = function
132
143