From 4c62481c1e028972cc180dfcb4b39396385a5c0a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Dec 2024 08:44:50 -0800 Subject: [PATCH 1/9] commment out lines of total_num_engines that are never used in landing_eom.py --- aviary/mission/flops_based/ode/landing_eom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aviary/mission/flops_based/ode/landing_eom.py b/aviary/mission/flops_based/ode/landing_eom.py index 10c2304aa..f05f132ea 100644 --- a/aviary/mission/flops_based/ode/landing_eom.py +++ b/aviary/mission/flops_based/ode/landing_eom.py @@ -178,7 +178,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + # total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) mass = inputs[Dynamic.Mission.MASS] lift = inputs[Dynamic.Mission.LIFT] @@ -216,7 +216,7 @@ def compute_partials(self, inputs, J, discrete_inputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + # total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) mass = inputs[Dynamic.Mission.MASS] lift = inputs[Dynamic.Mission.LIFT] From 14ef4df52eae70ee9190d33f454cd8c0982e4eee Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Dec 2024 08:46:13 -0800 Subject: [PATCH 2/9] add detail of key in assertIn() in subsystem_tester.py --- aviary/subsystems/test/subsystem_tester.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aviary/subsystems/test/subsystem_tester.py b/aviary/subsystems/test/subsystem_tester.py index 771ceb003..a653babc5 100644 --- a/aviary/subsystems/test/subsystem_tester.py +++ b/aviary/subsystems/test/subsystem_tester.py @@ -164,11 +164,11 @@ def test_get_parameters(self): val, dict, "The values in the dictionary returned by get_parameters() should be dictionaries") # Verify that the dictionaries have the correct keys - for val in parameters.values(): + for key, val in parameters.items(): self.assertIn( - 'val', val, "The dictionaries returned by get_parameters() should have a 'val' key") + 'val', val, f"The dictionaries returned by get_parameters() should have a 'val' key for {key}") self.assertIn( - 'units', val, "The dictionaries returned by get_parameters() should have a 'units' key") + 'units', val, f"The dictionaries returned by get_parameters() should have a 'units' key for {key}") def test_get_initial_guesses(self): initial_guesses = self.subsystem_builder.get_initial_guesses() From 499dca3ef81e89af067d046e862f4e1152df056a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Dec 2024 08:47:53 -0800 Subject: [PATCH 3/9] update aerodynamics_builder.py to pass unit test --- .../aerodynamics/aerodynamics_builder.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index f43e45930..58c10b0b4 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -9,10 +9,7 @@ """ from itertools import chain -import numpy as np - -import openmdao.api as om -from dymos.utils.misc import _unspecified +# from dymos.utils.misc import _unspecified from aviary.subsystems.aerodynamics.flops_based.computed_aero_group import \ ComputedAeroGroup @@ -39,7 +36,7 @@ GASP = LegacyCode.GASP FLOPS = LegacyCode.FLOPS -_default_name = 'aerodynamics' +default_name = 'aerodynamics' class AerodynamicsBuilderBase(SubsystemBuilderBase): @@ -58,7 +55,7 @@ class AerodynamicsBuilderBase(SubsystemBuilderBase): def __init__(self, name=None, meta_data=None): if name is None: - name = _default_name + name = default_name super().__init__(name=name, meta_data=meta_data) @@ -327,7 +324,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): aero_opt = phase_info['subsystem_options'][self.name] method = aero_opt['method'] except KeyError: - method = 'computed' + method = None if phase_info is not None: # Only solved_alpha has connectable inputs. @@ -377,7 +374,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = meta['default_value'] if val is None: - val = _unspecified + val = 0.0 # _unspecified units = meta['units'] if var in aviary_inputs: @@ -387,6 +384,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = aviary_inputs.get_val(var) params[var] = {'val': val, + 'units': units, 'static_target': True} for var in ENGINE_SIZED_INPUTS: @@ -400,7 +398,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = meta['default_value'] if val is None: - val = _unspecified + val = 0.0 # _unspecified units = meta['units'] if var in aviary_inputs: @@ -410,6 +408,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = aviary_inputs.get_val(var) params[var] = {'val': val, + 'units': units, 'static_target': True} elif method == "low_speed": @@ -420,7 +419,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = meta['default_value'] if val is None: - val = _unspecified + val = 0.0 # _unspecified units = meta['units'] if var in aviary_inputs: @@ -430,6 +429,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = aviary_inputs.get_val(var) params[var] = {'val': val, + 'units': units, 'static_target': True} else: @@ -437,7 +437,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): # TODO: 2DOF/Gasp decided on phases based on phase names. We used # a saved phase_name to determine the correct aero variables to # promote. Ideally, this should all be refactored. - if phase_info['phase_type'] in ['ascent', 'groundroll', 'rotation']: + if bool(phase_info) and phase_info['phase_type'] in ['ascent', 'groundroll', 'rotation']: all_vars = (AERO_2DOF_INPUTS, AERO_LS_2DOF_INPUTS) else: all_vars = (AERO_2DOF_INPUTS, AERO_CLEAN_2DOF_INPUTS) @@ -448,7 +448,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = meta['default_value'] if val is None: - val = _unspecified + val = 0.0 # _unspecified units = meta['units'] if var in aviary_inputs: @@ -458,6 +458,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): val = aviary_inputs.get_val(var) params[var] = {'val': val, + 'units': units, 'static_target': True} return params @@ -466,12 +467,12 @@ def get_bus_variables(self): if self.code_origin is GASP: return { "interference_independent_of_shielded_area": { - "mission_name": ['interference_independent_of_shielded_area'], + "mission_name": 'interference_independent_of_shielded_area', # "post_mission_name": ['interference_independent_of_shielded_area'], "units": "unitless", }, "drag_loss_due_to_shielded_wing_area": { - "mission_name": ['drag_loss_due_to_shielded_wing_area'], + "mission_name": 'drag_loss_due_to_shielded_wing_area', # "post_mission_name": ['drag_loss_due_to_shielded_wing_area'], "units": "unitless", }, From 0de5a9daaada108f092a12edf24947baba6e81b3 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Dec 2024 08:51:39 -0800 Subject: [PATCH 4/9] add test_flops_aero_builder.py --- .../test/test_flops_aero_builder.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 aviary/subsystems/aerodynamics/test/test_flops_aero_builder.py diff --git a/aviary/subsystems/aerodynamics/test/test_flops_aero_builder.py b/aviary/subsystems/aerodynamics/test/test_flops_aero_builder.py new file mode 100644 index 000000000..f3405d048 --- /dev/null +++ b/aviary/subsystems/aerodynamics/test/test_flops_aero_builder.py @@ -0,0 +1,27 @@ +import unittest + +from aviary.subsystems.aerodynamics.aerodynamics_builder import CoreAerodynamicsBuilder +from aviary.variable_info.enums import LegacyCode +from aviary.variable_info.variables import Aircraft +from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData +import aviary.api as av + +FLOPS = LegacyCode.FLOPS + + +class TestAeroBuilder(av.TestSubsystemBuilderBase): + """ + That class inherits from TestSubsystemBuilder. So all the test functions are + within that inherited class. The setUp() method prepares the class and is run + before the test methods; then the test methods are run. + """ + + def setUp(self): + self.subsystem_builder = CoreAerodynamicsBuilder( + 'core_aerodynamics', BaseMetaData, FLOPS) + self.aviary_values = av.AviaryValues() + self.aviary_values.set_val(Aircraft.Engine.NUM_ENGINES, [1], units='unitless') + + +if __name__ == '__main__': + unittest.main() From 233c1d05c2bd037158c5689076988061b55821ea Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Dec 2024 10:09:46 -0800 Subject: [PATCH 5/9] add numpy back --- aviary/subsystems/aerodynamics/aerodynamics_builder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index 58c10b0b4..56bd6ec84 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -7,6 +7,7 @@ CoreAerodynamicsBuilder : the interface for Aviary's core aerodynamics subsystem builder """ +import numpy as np from itertools import chain # from dymos.utils.misc import _unspecified From 15ca23572948cc76e199add231f0ba9fc1245963 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Dec 2024 18:30:38 -0800 Subject: [PATCH 6/9] update phase_info in get_parameters() call --- ...examples_of_the_same_mission_at_different_UI_levels.ipynb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb b/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb index 84634708f..eb65a5b25 100644 --- a/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb +++ b/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb @@ -390,8 +390,9 @@ "# Need to declare dymos parameters for every input that is promoted out of the missions.\n", "external_parameters = {'climb': {}, 'cruise': {}, 'descent': {}}\n", "for default_subsys in default_mission_subsystems:\n", - " params = default_subsys.get_parameters(aviary_inputs=aviary_inputs,\n", - " phase_info={})\n", + " params = default_subsys.get_parameters(\n", + " aviary_inputs=aviary_inputs,\n", + " phase_info={\"subsystem_options\": {\"core_aerodynamics\": {\"method\": \"computed\"}}})\n", " for key, val in params.items():\n", " for phname in external_parameters:\n", " external_parameters[phname][key] = val\n", From f68bc73d0edf024125cb83730f1f939a7cfdedd7 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 11 Dec 2024 14:28:53 -0800 Subject: [PATCH 7/9] user must specify a method to build aerodynamics. Otherwise, an exception is generated. --- aviary/subsystems/aerodynamics/aerodynamics_builder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index 56bd6ec84..c2736ac60 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -325,7 +325,8 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): aero_opt = phase_info['subsystem_options'][self.name] method = aero_opt['method'] except KeyError: - method = None + raise ValueError('FLOPS-based aero method is not one of the following: ' + '(computed, low_speed, solved_alpha, tabular)') if phase_info is not None: # Only solved_alpha has connectable inputs. From d6fa153c0c31ed26c1228600a7cd175214a16a6e Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 11 Dec 2024 16:21:01 -0800 Subject: [PATCH 8/9] allow list in get_bus_variables --- aviary/subsystems/aerodynamics/aerodynamics_builder.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index c2736ac60..a68286458 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -325,8 +325,7 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): aero_opt = phase_info['subsystem_options'][self.name] method = aero_opt['method'] except KeyError: - raise ValueError('FLOPS-based aero method is not one of the following: ' - '(computed, low_speed, solved_alpha, tabular)') + method = None if phase_info is not None: # Only solved_alpha has connectable inputs. @@ -469,12 +468,12 @@ def get_bus_variables(self): if self.code_origin is GASP: return { "interference_independent_of_shielded_area": { - "mission_name": 'interference_independent_of_shielded_area', + "mission_name": ['interference_independent_of_shielded_area'], # "post_mission_name": ['interference_independent_of_shielded_area'], "units": "unitless", }, "drag_loss_due_to_shielded_wing_area": { - "mission_name": 'drag_loss_due_to_shielded_wing_area', + "mission_name": ['drag_loss_due_to_shielded_wing_area'], # "post_mission_name": ['drag_loss_due_to_shielded_wing_area'], "units": "unitless", }, From 791d910997f842f0265d181a59dbe0c6c8676762 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 31 Dec 2024 08:22:27 -0800 Subject: [PATCH 9/9] add a note for add_aviary_input/add_aviary_output --- aviary/docs/user_guide/variable_hierarchy.ipynb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aviary/docs/user_guide/variable_hierarchy.ipynb b/aviary/docs/user_guide/variable_hierarchy.ipynb index 8f213a134..01676f547 100644 --- a/aviary/docs/user_guide/variable_hierarchy.ipynb +++ b/aviary/docs/user_guide/variable_hierarchy.ipynb @@ -92,6 +92,13 @@ " av.add_aviary_output(self, Aircraft.VerticalTail.SPAN, val=0, units='ft', desc='span of the vertical tail')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If `units` is not provided, it assumes the `units` in the metadata." + ] + }, { "cell_type": "code", "execution_count": null,