From 8680469b21d0c016dae71295c6f9d4e7038e5f7f Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 22 Oct 2024 07:46:40 -0700 Subject: [PATCH 01/12] adding unit test for json --- aviary/interface/methods_for_level2.py | 4 +- .../test/sizing_problem_for_test.json | 1307 +++++++++++++++++ aviary/interface/test/test_json.py | 67 + 3 files changed, 1376 insertions(+), 2 deletions(-) create mode 100644 aviary/interface/test/sizing_problem_for_test.json create mode 100644 aviary/interface/test/test_json.py diff --git a/aviary/interface/methods_for_level2.py b/aviary/interface/methods_for_level2.py index e1447b776..42a4e8bbc 100644 --- a/aviary/interface/methods_for_level2.py +++ b/aviary/interface/methods_for_level2.py @@ -2521,12 +2521,12 @@ def save_sizing_to_json(self, json_filename='sizing_problem.json'): # Lists are fine except if they contain enums if type_value == list: - if type(type(value[0])) == enum.EnumType: + if type(type(value[0])) == type(enum.Enum): for i in range(len(value)): value[i] = str([value[i]]) # Enums need converting to a string - if type(type(value)) == enum.EnumType: + if type(type(value)) == type(enum.Enum): value = str([value]) # Append the data to the list diff --git a/aviary/interface/test/sizing_problem_for_test.json b/aviary/interface/test/sizing_problem_for_test.json new file mode 100644 index 000000000..57eb1845b --- /dev/null +++ b/aviary/interface/test/sizing_problem_for_test.json @@ -0,0 +1,1307 @@ +[ + [ + "aircraft:blended_wing_body_design:num_bays", + 0, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:mass_per_passenger", + 180, + "lbm", + "" + ], + [ + "aircraft:crew_and_payload:num_business_class", + 0, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:num_first_class", + 11, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:num_passengers", + 169, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:num_tourist_class", + 158, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:passenger_mass_with_bags", + 200, + "lbm", + "" + ], + [ + "aircraft:design:compute_htail_volume_coeff", + false, + "unitless", + "" + ], + [ + "aircraft:design:compute_vtail_volume_coeff", + false, + "unitless", + "" + ], + [ + "aircraft:design:part25_structural_category", + 3, + "unitless", + "" + ], + [ + "aircraft:design:reserve_fuel_additional", + 3000, + "lbm", + "" + ], + [ + "aircraft:design:reserve_fuel_fraction", + 0, + "unitless", + "" + ], + [ + "aircraft:design:smooth_mass_discontinuities", + false, + "unitless", + "" + ], + [ + "aircraft:design:ulf_calculated_from_maneuver", + false, + "unitless", + "" + ], + [ + "aircraft:design:use_alt_mass", + false, + "unitless", + "" + ], + [ + "aircraft:electrical:has_hybrid_system", + false, + "unitless", + "" + ], + [ + "aircraft:engine:compute_propeller_installation_loss", + [ + true + ], + "unitless", + "" + ], + [ + "aircraft:engine:constant_fuel_consumption", + [ + 0.0 + ], + "lbm/h", + "" + ], + [ + "aircraft:engine:flight_idle_max_fraction", + [ + 1.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:flight_idle_min_fraction", + [ + 0.08 + ], + "unitless", + "" + ], + [ + "aircraft:engine:flight_idle_thrust_fraction", + [ + 0.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:fuel_flow_scaler_constant_term", + [ + 0.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:fuel_flow_scaler_linear_term", + [ + 0.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:generate_flight_idle", + [ + true + ], + "unitless", + "" + ], + [ + "aircraft:engine:geopotential_alt", + [ + false + ], + "unitless", + "" + ], + [ + "aircraft:engine:has_propellers", + [ + false + ], + "unitless", + "" + ], + [ + "aircraft:engine:ignore_negative_thrust", + [ + false + ], + "unitless", + "" + ], + [ + "aircraft:engine:interpolation_method", + [ + "slinear" + ], + "unitless", + "" + ], + [ + "aircraft:engine:num_engines", + [ + 2 + ], + "unitless", + "" + ], + [ + "aircraft:engine:num_fuselage_engines", + [ + 0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:num_propeller_blades", + [ + 0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:num_wing_engines", + [ + 2 + ], + "unitless", + "" + ], + [ + "aircraft:engine:scale_mass", + [ + true + ], + "unitless", + "" + ], + [ + "aircraft:engine:scale_performance", + [ + true + ], + "unitless", + "" + ], + [ + "aircraft:engine:subsonic_fuel_flow_scaler", + [ + 1.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:supersonic_fuel_flow_scaler", + [ + 1.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:type", + [ + "[]" + ], + "unitless", + "" + ], + [ + "aircraft:engine:use_propeller_map", + [ + false + ], + "unitless", + "" + ], + [ + "aircraft:engine:shaft_power_design", + [ + 1.0 + ], + "kW", + "" + ], + [ + "aircraft:fins:num_fins", + 0, + "unitless", + "" + ], + [ + "aircraft:fuel:num_tanks", + 7, + "unitless", + "" + ], + [ + "aircraft:fuselage:aisle_width", + 24, + "inch", + "" + ], + [ + "aircraft:fuselage:military_cargo_floor", + false, + "unitless", + "" + ], + [ + "aircraft:fuselage:num_aisles", + 1, + "unitless", + "" + ], + [ + "aircraft:fuselage:num_fuselages", + 1, + "unitless", + "" + ], + [ + "aircraft:fuselage:num_seats_abreast", + 6, + "unitless", + "" + ], + [ + "aircraft:fuselage:seat_pitch", + 29, + "inch", + "" + ], + [ + "aircraft:fuselage:seat_width", + 20, + "inch", + "" + ], + [ + "aircraft:landing_gear:carrier_based", + false, + "unitless", + "" + ], + [ + "aircraft:landing_gear:drag_coefficient", + 0.0, + "unitless", + "" + ], + [ + "aircraft:landing_gear:fixed_gear", + true, + "unitless", + "" + ], + [ + "aircraft:strut:dimensional_location_specified", + true, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:num_tails", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:airfoil_technology", + 1.92669766647637, + "unitless", + "" + ], + [ + "aircraft:wing:choose_fold_location", + true, + "unitless", + "" + ], + [ + "aircraft:wing:detailed_wing", + false, + "unitless", + "" + ], + [ + "aircraft:wing:flap_type", + "[]", + "unitless", + "" + ], + [ + "aircraft:wing:fold_dimensional_location_specified", + false, + "unitless", + "" + ], + [ + "aircraft:wing:has_fold", + false, + "unitless", + "" + ], + [ + "aircraft:wing:has_strut", + false, + "unitless", + "" + ], + [ + "aircraft:wing:load_distribution_control", + 2, + "unitless", + "" + ], + [ + "aircraft:wing:loading_above_20", + true, + "unitless", + "" + ], + [ + "aircraft:wing:num_flap_segments", + 2, + "unitless", + "" + ], + [ + "aircraft:wing:num_integration_stations", + 50, + "unitless", + "" + ], + [ + "aircraft:wing:span_efficiency_reduction", + false, + "unitless", + "" + ], + [ + "mission:design:cruise_altitude", + 35000, + "ft", + "" + ], + [ + "mission:design:rate_of_climb_at_top_of_climb", + 0.0, + "ft/min", + "" + ], + [ + "mission:summary:fuel_flow_scaler", + 1, + "unitless", + "" + ], + [ + "mission:takeoff:angle_of_attack_runway", + 0.0, + "deg", + "" + ], + [ + "mission:takeoff:obstacle_height", + 35.0, + "ft", + "" + ], + [ + "mission:takeoff:thrust_incidence", + 0.0, + "deg", + "" + ], + [ + "mission:taxi:duration", + 0.167, + "h", + "" + ], + [ + "mission:taxi:mach", + 0.0001, + "unitless", + "" + ], + [ + "settings:verbosity", + "[]", + "unitless", + "" + ], + [ + "INGASP.JENGSZ", + 4, + "unitless", + "" + ], + [ + "test_mode", + false, + "unitless", + "" + ], + [ + "use_surrogates", + true, + "unitless", + "" + ], + [ + "mass_defect", + 10000, + "lbm", + "" + ], + [ + "settings:problem_type", + "[]", + "unitless", + "" + ], + [ + "aircraft:air_conditioning:mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:anti_icing:mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:apu:mass_scaler", + 1.1, + "unitless", + "" + ], + [ + "aircraft:avionics:mass_scaler", + 1.2, + "unitless", + "" + ], + [ + "aircraft:canard:area", + 0, + "ft**2", + "" + ], + [ + "aircraft:canard:aspect_ratio", + 0, + "unitless", + "" + ], + [ + "aircraft:canard:thickness_to_chord", + 0, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:baggage_mass_per_passenger", + 45, + "lbm", + "" + ], + [ + "aircraft:crew_and_payload:cargo_container_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:flight_crew_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:misc_cargo", + 0, + "lbm", + "" + ], + [ + "aircraft:crew_and_payload:non_flight_crew_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:num_flight_attendants", + 3, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:num_flight_crew", + 2, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:num_galley_crew", + 0, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:passenger_service_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:crew_and_payload:wing_cargo", + 0, + "lbm", + "" + ], + [ + "aircraft:design:base_area", + 0, + "ft**2", + "" + ], + [ + "aircraft:design:empty_mass_margin_scaler", + 0, + "unitless", + "" + ], + [ + "aircraft:design:lift_dependent_drag_coeff_factor", + 0.909839381134961, + "unitless", + "" + ], + [ + "aircraft:design:touchdown_mass", + 152800, + "lbm", + "" + ], + [ + "aircraft:design:subsonic_drag_coeff_factor", + 1, + "unitless", + "" + ], + [ + "aircraft:design:supersonic_drag_coeff_factor", + 1, + "unitless", + "" + ], + [ + "aircraft:design:zero_lift_drag_coeff_factor", + 0.930890028006548, + "unitless", + "" + ], + [ + "aircraft:electrical:mass_scaler", + 1.25, + "unitless", + "" + ], + [ + "aircraft:engine:additional_mass_fraction", + [ + 0.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:data_file", + [ + "models/engines/turbofan_28k.deck" + ], + "unitless", + "" + ], + [ + "aircraft:engine:mass_scaler", + [ + 1.15 + ], + "unitless", + "" + ], + [ + "aircraft:engine:mass", + [ + 7400.0 + ], + "lbm", + "" + ], + [ + "aircraft:engine:reference_mass", + [ + 7400 + ], + "lbm", + "" + ], + [ + "aircraft:engine:reference_sls_thrust", + [ + 28928.1 + ], + "lbf", + "" + ], + [ + "aircraft:engine:scaled_sls_thrust", + [ + 28928.1 + ], + "lbf", + "" + ], + [ + "aircraft:engine:thrust_reversers_mass_scaler", + [ + 0.0 + ], + "unitless", + "" + ], + [ + "aircraft:engine:wing_locations", + [ + 0.26869218 + ], + "unitless", + "" + ], + [ + "aircraft:fins:area", + 0, + "ft**2", + "" + ], + [ + "aircraft:fins:mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:fins:mass", + 0, + "lbm", + "" + ], + [ + "aircraft:fins:taper_ratio", + 10, + "unitless", + "" + ], + [ + "aircraft:fuel:auxiliary_fuel_capacity", + 0, + "lbm", + "" + ], + [ + "aircraft:fuel:density_ratio", + 1, + "unitless", + "" + ], + [ + "aircraft:fuel:fuel_system_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:fuel:fuselage_fuel_capacity", + 0, + "lbm", + "" + ], + [ + "aircraft:fuel:total_capacity", + 45694, + "lbm", + "" + ], + [ + "aircraft:fuel:unusable_fuel_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:furnishings:mass_scaler", + 1.1, + "unitless", + "" + ], + [ + "aircraft:fuselage:length", + 128, + "ft", + "" + ], + [ + "aircraft:fuselage:mass_scaler", + 1.05, + "unitless", + "" + ], + [ + "aircraft:fuselage:max_height", + 13.17, + "ft", + "" + ], + [ + "aircraft:fuselage:max_width", + 12.33, + "ft", + "" + ], + [ + "aircraft:fuselage:passenger_compartment_length", + 85.5, + "ft", + "" + ], + [ + "aircraft:fuselage:planform_area", + 1578.24, + "ft**2", + "" + ], + [ + "aircraft:fuselage:wetted_area_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:fuselage:wetted_area", + 4158.62, + "ft**2", + "" + ], + [ + "aircraft:horizontal_tail:area", + 355, + "ft**2", + "" + ], + [ + "aircraft:horizontal_tail:aspect_ratio", + 6, + "unitless", + "" + ], + [ + "aircraft:horizontal_tail:mass_scaler", + 1.2, + "unitless", + "" + ], + [ + "aircraft:horizontal_tail:taper_ratio", + 0.22, + "unitless", + "" + ], + [ + "aircraft:horizontal_tail:thickness_to_chord", + 0.125, + "unitless", + "" + ], + [ + "aircraft:horizontal_tail:vertical_tail_fraction", + 0, + "unitless", + "" + ], + [ + "aircraft:horizontal_tail:wetted_area_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:horizontal_tail:wetted_area", + 592.65, + "ft**2", + "" + ], + [ + "aircraft:hydraulics:mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:hydraulics:system_pressure", + 3000, + "psi", + "" + ], + [ + "aircraft:instruments:mass_scaler", + 1.25, + "unitless", + "" + ], + [ + "aircraft:landing_gear:main_gear_mass_scaler", + 1.1, + "unitless", + "" + ], + [ + "aircraft:landing_gear:main_gear_oleo_length", + 102, + "inch", + "" + ], + [ + "aircraft:landing_gear:nose_gear_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:landing_gear:nose_gear_oleo_length", + 67, + "inch", + "" + ], + [ + "aircraft:nacelle:avg_diameter", + [ + 7.94 + ], + "ft", + "" + ], + [ + "aircraft:nacelle:avg_length", + [ + 12.3 + ], + "ft", + "" + ], + [ + "aircraft:nacelle:mass_scaler", + [ + 1.0 + ], + "unitless", + "" + ], + [ + "aircraft:nacelle:wetted_area_scaler", + [ + 1.0 + ], + "unitless", + "" + ], + [ + "aircraft:paint:mass_per_unit_area", + 0.037, + "lbm/ft**2", + "" + ], + [ + "aircraft:propulsion:engine_oil_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:propulsion:misc_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:area", + 284, + "ft**2", + "" + ], + [ + "aircraft:vertical_tail:aspect_ratio", + 1.75, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:taper_ratio", + 0.33, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:thickness_to_chord", + 0.1195, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:wetted_area_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:vertical_tail:wetted_area", + 581.13, + "ft**2", + "" + ], + [ + "aircraft:wing:aeroelastic_tailoring_factor", + 0, + "unitless", + "" + ], + [ + "aircraft:wing:area", + 1370, + "ft**2", + "" + ], + [ + "aircraft:wing:aspect_ratio", + 11.22091, + "unitless", + "" + ], + [ + "aircraft:wing:bending_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:chord_per_semispan", + [ + 0.31, + 0.23, + 0.084 + ], + "unitless", + "" + ], + [ + "aircraft:wing:composite_fraction", + 0.2, + "unitless", + "" + ], + [ + "aircraft:wing:control_surface_area", + 137, + "ft**2", + "" + ], + [ + "aircraft:wing:control_surface_area_ratio", + 0.1, + "unitless", + "" + ], + [ + "aircraft:wing:glove_and_bat", + 134, + "ft**2", + "" + ], + [ + "aircraft:wing:input_station_dist", + [ + 0, + 0.2759, + 0.9367 + ], + "unitless", + "" + ], + [ + "aircraft:wing:load_fraction", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:load_path_sweep_dist", + [ + 0, + 22 + ], + "deg", + "" + ], + [ + "aircraft:wing:mass_scaler", + 1.23, + "unitless", + "" + ], + [ + "aircraft:wing:max_camber_at_70_semispan", + 0, + "unitless", + "" + ], + [ + "aircraft:wing:misc_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:shear_control_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:span", + 117.83, + "ft", + "" + ], + [ + "aircraft:wing:strut_bracing_factor", + 0, + "unitless", + "" + ], + [ + "aircraft:wing:surface_ctrl_mass_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:sweep", + 25, + "deg", + "" + ], + [ + "aircraft:wing:taper_ratio", + 0.278, + "unitless", + "" + ], + [ + "aircraft:wing:thickness_to_chord_dist", + [ + 0.145, + 0.115, + 0.104 + ], + "unitless", + "" + ], + [ + "aircraft:wing:thickness_to_chord", + 0.13, + "unitless", + "" + ], + [ + "aircraft:wing:ultimate_load_factor", + 3.75, + "unitless", + "" + ], + [ + "aircraft:wing:var_sweep_mass_penalty", + 0, + "unitless", + "" + ], + [ + "aircraft:wing:wetted_area_scaler", + 1, + "unitless", + "" + ], + [ + "aircraft:wing:wetted_area", + 2396.56, + "ft**2", + "" + ], + [ + "mission:constraints:max_mach", + 0.785, + "unitless", + "" + ], + [ + "mission:design:gross_mass", + 175400.0, + "lbm", + "" + ], + [ + "mission:design:range", + 1906.0, + "NM", + "" + ], + [ + "mission:design:thrust_takeoff_per_eng", + 28928.1, + "lbf", + "" + ], + [ + "mission:landing:lift_coefficient_max", + 2, + "unitless", + "" + ], + [ + "mission:summary:cruise_mach", + 0.785, + "unitless", + "" + ], + [ + "mission:takeoff:fuel_simple", + 577, + "lbm", + "" + ], + [ + "mission:takeoff:lift_coefficient_max", + 3, + "unitless", + "" + ], + [ + "mission:takeoff:lift_over_drag", + 17.354, + "unitless", + "" + ], + [ + "settings:equations_of_motion", + "[]", + "unitless", + "" + ], + [ + "settings:mass_method", + "[]", + "unitless", + "" + ], + [ + "mission:summary:gross_mass", + 175400.0, + "lbm", + "" + ], + [ + "aircraft:propulsion:total_num_engines", + 2, + "unitless", + "" + ], + [ + "aircraft:propulsion:total_num_fuselage_engines", + 0, + "unitless", + "" + ], + [ + "aircraft:propulsion:total_num_wing_engines", + 2, + "unitless", + "" + ] +] \ No newline at end of file diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py new file mode 100644 index 000000000..d0da93ebb --- /dev/null +++ b/aviary/interface/test/test_json.py @@ -0,0 +1,67 @@ +import subprocess +import unittest +from pathlib import Path + +from aviary.utils.functions import get_aviary_resource_path +from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs +import aviary.api as av +from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization + + +@use_tempdirs +class TestJson(unittest.TestCase): + def run_and_test_cmd(self, cmd): + # this only tests that a given command line tool returns a 0 return code. It doesn't + # check the expected output at all. The underlying functions that implement the + # commands should be tested seperately. + try: + output = subprocess.check_output(cmd.split()) + except subprocess.CalledProcessError as err: + self.fail(f"Command '{cmd}' failed. Return code: {err.returncode}") + + def get_file(self, filename): + filepath = get_aviary_resource_path(filename) + if not Path(filepath).exists(): + self.skipTest(f"couldn't find {filepath}") + return filepath + + def setUp(self): + self.prob = prob = av.AviaryProblem() + # Load aircraft and options data from user + # Allow for user overrides here + prob.load_inputs('models/test_aircraft/aircraft_for_bench_FwFm.csv', phase_info) + + # Preprocess inputs + prob.check_and_preprocess_inputs() + prob.add_pre_mission_systems() + prob.add_phases(phase_info_parameterization=phase_info_parameterization) + prob.add_post_mission_systems() + + # Link phases and variables + prob.link_phases() + prob.add_driver('SNOPT', max_iter=0) + prob.add_design_variables() + + # Load optimization problem formulation + # Detail which variables the optimizer can control + prob.add_objective() + prob.setup() + prob.set_initial_guesses() + + def test_save_json(self): + self.prob.run_aviary_problem() + self.prob.save_sizing_to_json() + + def test_alternate(self): + filepath = self.get_file('interface/test/sizing_problem_for_test.json') + prob_alternate = self.prob.alternate_mission( + run_mission=False, json_filename=filepath, phase_info=phase_info) + + def test_fallout(self): + filepath = self.get_file('interface/test/sizing_problem_for_test.json') + prob_fallout = self.prob.fallout_mission( + run_mission=False, json_filename=filepath, phase_info=phase_info) + + +if __name__ == "__main__": + unittest.main() From a25d6800686f7ab18896386e144e3c5293b7dd96 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 22 Oct 2024 07:47:11 -0700 Subject: [PATCH 02/12] remove copy-pasted function --- aviary/interface/test/test_json.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index d0da93ebb..8ae09ec3d 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -10,15 +10,6 @@ @use_tempdirs class TestJson(unittest.TestCase): - def run_and_test_cmd(self, cmd): - # this only tests that a given command line tool returns a 0 return code. It doesn't - # check the expected output at all. The underlying functions that implement the - # commands should be tested seperately. - try: - output = subprocess.check_output(cmd.split()) - except subprocess.CalledProcessError as err: - self.fail(f"Command '{cmd}' failed. Return code: {err.returncode}") - def get_file(self, filename): filepath = get_aviary_resource_path(filename) if not Path(filepath).exists(): From 590daf733e52864b35577f442909a2624df2af46 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 22 Oct 2024 08:24:46 -0700 Subject: [PATCH 03/12] changed optimizer for CI --- aviary/interface/test/test_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 8ae09ec3d..19a381f28 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -30,7 +30,7 @@ def setUp(self): # Link phases and variables prob.link_phases() - prob.add_driver('SNOPT', max_iter=0) + prob.add_driver('IPOPT', max_iter=0) prob.add_design_variables() # Load optimization problem formulation From b71055382515bbdf04046fc780a61aa7ebdbd401 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 22 Oct 2024 10:00:47 -0700 Subject: [PATCH 04/12] adding require_pyoptsparse to test --- aviary/interface/test/test_json.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 19a381f28..564f7f346 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -9,6 +9,7 @@ @use_tempdirs +@require_pyoptsparse class TestJson(unittest.TestCase): def get_file(self, filename): filepath = get_aviary_resource_path(filename) From 7cc5b12d749dcea1b1427d8f123c5777c065a52a Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 22 Oct 2024 11:49:54 -0700 Subject: [PATCH 05/12] adding _clear_problem_names() to fix CI failure --- aviary/interface/test/test_json.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 564f7f346..395844838 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -1,9 +1,9 @@ -import subprocess import unittest from pathlib import Path from aviary.utils.functions import get_aviary_resource_path from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs +from openmdao.core.problem import _clear_problem_names import aviary.api as av from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization @@ -40,19 +40,24 @@ def setUp(self): prob.setup() prob.set_initial_guesses() + _clear_problem_names() + def test_save_json(self): self.prob.run_aviary_problem() self.prob.save_sizing_to_json() + _clear_problem_names() def test_alternate(self): filepath = self.get_file('interface/test/sizing_problem_for_test.json') prob_alternate = self.prob.alternate_mission( run_mission=False, json_filename=filepath, phase_info=phase_info) + _clear_problem_names() def test_fallout(self): filepath = self.get_file('interface/test/sizing_problem_for_test.json') prob_fallout = self.prob.fallout_mission( run_mission=False, json_filename=filepath, phase_info=phase_info) + _clear_problem_names() if __name__ == "__main__": From ac52c8245c703419b4d0378d9a14238a15a1d097 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 22 Oct 2024 11:51:47 -0700 Subject: [PATCH 06/12] reverting unnecessary change --- aviary/interface/test/test_json.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 395844838..bb64e4433 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -3,7 +3,6 @@ from aviary.utils.functions import get_aviary_resource_path from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs -from openmdao.core.problem import _clear_problem_names import aviary.api as av from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization @@ -40,24 +39,19 @@ def setUp(self): prob.setup() prob.set_initial_guesses() - _clear_problem_names() - def test_save_json(self): self.prob.run_aviary_problem() self.prob.save_sizing_to_json() - _clear_problem_names() def test_alternate(self): filepath = self.get_file('interface/test/sizing_problem_for_test.json') prob_alternate = self.prob.alternate_mission( run_mission=False, json_filename=filepath, phase_info=phase_info) - _clear_problem_names() def test_fallout(self): filepath = self.get_file('interface/test/sizing_problem_for_test.json') prob_fallout = self.prob.fallout_mission( run_mission=False, json_filename=filepath, phase_info=phase_info) - _clear_problem_names() if __name__ == "__main__": From 706b8d7e93e14ab52d0a9a39a42665a1ea182fa0 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 29 Oct 2024 12:19:44 -0700 Subject: [PATCH 07/12] renamed examples/off_design_example.py to run as part of CI --- .../examples/{off_design_example.py => run_off_design_example.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename aviary/examples/{off_design_example.py => run_off_design_example.py} (100%) diff --git a/aviary/examples/off_design_example.py b/aviary/examples/run_off_design_example.py similarity index 100% rename from aviary/examples/off_design_example.py rename to aviary/examples/run_off_design_example.py From a37dede7f87588a8b4b6f06b6c0a5a605cfd9088 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 29 Oct 2024 14:46:31 -0700 Subject: [PATCH 08/12] PR feedback --- aviary/interface/methods_for_level2.py | 4 ++-- aviary/interface/test/test_json.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/aviary/interface/methods_for_level2.py b/aviary/interface/methods_for_level2.py index 45b5f384c..fc9061a7d 100644 --- a/aviary/interface/methods_for_level2.py +++ b/aviary/interface/methods_for_level2.py @@ -2516,12 +2516,12 @@ def save_sizing_to_json(self, json_filename='sizing_problem.json'): # Lists are fine except if they contain enums if type_value == list: - if type(type(value[0])) == type(enum.Enum): + if isinstance(value[0], enum.Enum): for i in range(len(value)): value[i] = str([value[i]]) # Enums need converting to a string - if type(type(value)) == type(enum.Enum): + if isinstance(value, enum.Enum): value = str([value]) # Append the data to the list diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index bb64e4433..37249e2fb 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -2,14 +2,20 @@ from pathlib import Path from aviary.utils.functions import get_aviary_resource_path -from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs +from openmdao.utils.testing_utils import use_tempdirs import aviary.api as av from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization @use_tempdirs -@require_pyoptsparse class TestJson(unittest.TestCase): + """ + These tests just check that the json files can be saved or loaded + They don't check that the files were properly created or that the + off-design mission ran correctly. + run_off_design_example.py in aviary/examples tests the full functionality + """ + def get_file(self, filename): filepath = get_aviary_resource_path(filename) if not Path(filepath).exists(): From 8a3d796a655debd99d43a9d51cb3894f8c1c0534 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 29 Oct 2024 15:22:54 -0700 Subject: [PATCH 09/12] fixes for CI --- aviary/examples/run_off_design_example.py | 6 +++++- aviary/interface/test/test_json.py | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/aviary/examples/run_off_design_example.py b/aviary/examples/run_off_design_example.py index ff3393990..69d6bcc46 100644 --- a/aviary/examples/run_off_design_example.py +++ b/aviary/examples/run_off_design_example.py @@ -8,6 +8,7 @@ We then call the correct methods in order to set up and run an Aviary optimization problem. This performs a coupled design-mission optimization and outputs the results from Aviary into the `reports` folder. """ +from openmdao.utils.general_utils import env_truthy import aviary.api as av from aviary.interface.default_phase_info.height_energy import phase_info_parameterization @@ -117,7 +118,10 @@ # Link phases and variables prob.link_phases() -prob.add_driver('SNOPT', max_iter=100) +if env_truthy("TESTFLO_RUNNING"): + prob.add_driver('IPOPT', max_iter=100) +else: + prob.add_driver('SNOPT', max_iter=100) prob.add_design_variables() # Load optimization problem formulation diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 37249e2fb..6c44f0ec5 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -2,12 +2,13 @@ from pathlib import Path from aviary.utils.functions import get_aviary_resource_path -from openmdao.utils.testing_utils import use_tempdirs +from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs import aviary.api as av from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization @use_tempdirs +@require_pyoptsparse class TestJson(unittest.TestCase): """ These tests just check that the json files can be saved or loaded From bb4a37aed77b4174fe7528f7595ff8fd4770c8a9 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 29 Oct 2024 15:25:01 -0700 Subject: [PATCH 10/12] deep copy phase info for test --- aviary/interface/test/test_json.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 6c44f0ec5..20ff573f1 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -1,5 +1,6 @@ import unittest from pathlib import Path +from copy import deepcopy from aviary.utils.functions import get_aviary_resource_path from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs @@ -7,6 +8,9 @@ from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization +local_phase_info = deepcopy(phase_info) + + @use_tempdirs @require_pyoptsparse class TestJson(unittest.TestCase): @@ -27,7 +31,8 @@ def setUp(self): self.prob = prob = av.AviaryProblem() # Load aircraft and options data from user # Allow for user overrides here - prob.load_inputs('models/test_aircraft/aircraft_for_bench_FwFm.csv', phase_info) + prob.load_inputs( + 'models/test_aircraft/aircraft_for_bench_FwFm.csv', local_phase_info) # Preprocess inputs prob.check_and_preprocess_inputs() @@ -53,12 +58,12 @@ def test_save_json(self): def test_alternate(self): filepath = self.get_file('interface/test/sizing_problem_for_test.json') prob_alternate = self.prob.alternate_mission( - run_mission=False, json_filename=filepath, phase_info=phase_info) + run_mission=False, json_filename=filepath, phase_info=local_phase_info) def test_fallout(self): filepath = self.get_file('interface/test/sizing_problem_for_test.json') prob_fallout = self.prob.fallout_mission( - run_mission=False, json_filename=filepath, phase_info=phase_info) + run_mission=False, json_filename=filepath, phase_info=local_phase_info) if __name__ == "__main__": From dfd360a885a76c669c3d4b8b0738ed21800ac67f Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 29 Oct 2024 15:44:41 -0700 Subject: [PATCH 11/12] switching to SLSQP for CI --- aviary/examples/run_off_design_example.py | 2 +- aviary/interface/test/test_json.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/aviary/examples/run_off_design_example.py b/aviary/examples/run_off_design_example.py index 69d6bcc46..7ff669934 100644 --- a/aviary/examples/run_off_design_example.py +++ b/aviary/examples/run_off_design_example.py @@ -119,7 +119,7 @@ # Link phases and variables prob.link_phases() if env_truthy("TESTFLO_RUNNING"): - prob.add_driver('IPOPT', max_iter=100) + prob.add_driver('SLSQP', max_iter=100) else: prob.add_driver('SNOPT', max_iter=100) prob.add_design_variables() diff --git a/aviary/interface/test/test_json.py b/aviary/interface/test/test_json.py index 20ff573f1..7b6ac524f 100644 --- a/aviary/interface/test/test_json.py +++ b/aviary/interface/test/test_json.py @@ -3,7 +3,7 @@ from copy import deepcopy from aviary.utils.functions import get_aviary_resource_path -from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs +from openmdao.utils.testing_utils import use_tempdirs import aviary.api as av from aviary.interface.default_phase_info.height_energy import phase_info, phase_info_parameterization @@ -12,7 +12,6 @@ @use_tempdirs -@require_pyoptsparse class TestJson(unittest.TestCase): """ These tests just check that the json files can be saved or loaded @@ -42,7 +41,7 @@ def setUp(self): # Link phases and variables prob.link_phases() - prob.add_driver('IPOPT', max_iter=0) + prob.add_driver('SLSQP', max_iter=0) prob.add_design_variables() # Load optimization problem formulation From e8ceace5cf2415e77920d5591357e4ca63c2abe9 Mon Sep 17 00:00:00 2001 From: Carl Recine Date: Tue, 29 Oct 2024 16:05:50 -0700 Subject: [PATCH 12/12] updated docs with renamed file --- aviary/docs/examples/off_design_example.ipynb | 4 ++-- aviary/docs/user_guide/off_design_missions.ipynb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aviary/docs/examples/off_design_example.ipynb b/aviary/docs/examples/off_design_example.ipynb index 14cb8530f..9b53836b0 100644 --- a/aviary/docs/examples/off_design_example.ipynb +++ b/aviary/docs/examples/off_design_example.ipynb @@ -11,8 +11,8 @@ "Running a sizing mission followed by running fallout and alternate missions on the sized aircraft will be presented.\n", "An overview of off-design missions is presented in [Off-Design Mission User Guide](../user_guide/off_design_missions).\n", "\n", - "The example is available in `aviary/examples/off_design_example.py`\n", - "The examples start with `run_aviary_example.py` and add off-design missions.\n", + "The example is available in `aviary/examples/run_off_design_example.py`\n", + "The examples start with `run_aviary_example.py` and adds off-design missions.\n", "\n", "The results of the sizing problem are saved using `prob.save_sizing_to_json()`.\n", "By default, this method saves the results to `sizing_problem.json` but the name of the file may be changed using the `json_filename` argument.\n", diff --git a/aviary/docs/user_guide/off_design_missions.ipynb b/aviary/docs/user_guide/off_design_missions.ipynb index 8f2dc03cc..78b214d3a 100644 --- a/aviary/docs/user_guide/off_design_missions.ipynb +++ b/aviary/docs/user_guide/off_design_missions.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "source": [ "You may also run multiple off-design missions in the same script used to solve the design mission.\n", - "An examples of this is shown in `off_design_example.py`." + "An examples of this is shown in `run_off_design_example.py`." ] }, { @@ -54,7 +54,7 @@ "\n", "off_design_examples = av.get_path(os.path.join('examples'))\n", "check_contains(\n", - " ('off_design_example.py'),\n", + " ('run_off_design_example.py'),\n", " os.listdir(off_design_examples),\n", " error_string=\"{var} not in \"+str(off_design_examples),\n", " error_type=FileNotFoundError)"