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 be08a70b0..531ff5694 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", 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, diff --git a/aviary/mission/flops_based/ode/landing_eom.py b/aviary/mission/flops_based/ode/landing_eom.py index 1ebf06ec4..8da834de7 100644 --- a/aviary/mission/flops_based/ode/landing_eom.py +++ b/aviary/mission/flops_based/ode/landing_eom.py @@ -196,7 +196,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.Vehicle.MASS] lift = inputs[Dynamic.Vehicle.LIFT] @@ -234,7 +234,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.Vehicle.MASS] lift = inputs[Dynamic.Vehicle.LIFT] diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index 0dd98dfd8..9135f4ed2 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -7,12 +7,10 @@ CoreAerodynamicsBuilder : the interface for Aviary's core aerodynamics subsystem builder """ -from itertools import chain - import numpy as np +from itertools import chain -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 +37,7 @@ GASP = LegacyCode.GASP FLOPS = LegacyCode.FLOPS -_default_name = 'aerodynamics' +default_name = 'aerodynamics' class AerodynamicsBuilderBase(SubsystemBuilderBase): @@ -58,7 +56,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) @@ -333,7 +331,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. @@ -383,7 +381,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: @@ -393,6 +391,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: @@ -406,7 +405,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: @@ -416,6 +415,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": @@ -426,7 +426,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: @@ -436,6 +436,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: @@ -443,7 +444,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) @@ -454,7 +455,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: @@ -464,6 +465,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 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() diff --git a/aviary/subsystems/test/subsystem_tester.py b/aviary/subsystems/test/subsystem_tester.py index 636a7685f..18a344606 100644 --- a/aviary/subsystems/test/subsystem_tester.py +++ b/aviary/subsystems/test/subsystem_tester.py @@ -165,11 +165,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()