From 258b491f5eabdc6fbd9359da3987a6d9a262b9d6 Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Tue, 21 Jan 2025 19:33:07 -0500 Subject: [PATCH 1/4] added 'external' method to aero, geom, mass builders --- .../aerodynamics/aerodynamics_builder.py | 159 ++++++++++-------- .../subsystems/geometry/geometry_builder.py | 39 +++-- aviary/subsystems/mass/mass_builder.py | 30 +++- 3 files changed, 139 insertions(+), 89 deletions(-) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index 52a82d710..b38e62400 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -100,14 +100,20 @@ def __init__(self, name=None, meta_data=None, code_origin=None): super().__init__(name=name, meta_data=meta_data) - def build_pre_mission(self, aviary_inputs): + def build_pre_mission(self, aviary_inputs, **kwargs): code_origin = self.code_origin + try: + method = kwargs.pop('method') + except KeyError: + method = None + aero_group = None - if code_origin is GASP: - aero_group = PreMissionAero() + if method != 'external': + if code_origin is GASP: + aero_group = PreMissionAero() - elif code_origin is FLOPS: - aero_group = Design() + elif code_origin is FLOPS: + aero_group = Design() return aero_group @@ -116,76 +122,89 @@ def build_mission(self, num_nodes, aviary_inputs, **kwargs): method = kwargs.pop('method') except KeyError: method = None - if self.code_origin is FLOPS: - if method is None: - aero_group = ComputedAeroGroup(num_nodes=num_nodes) - - elif method == 'computed': - aero_group = ComputedAeroGroup(num_nodes=num_nodes, - **kwargs) - - elif method == 'low_speed': - aero_group = TakeoffAeroGroup(num_nodes=num_nodes, - aviary_options=aviary_inputs, - **kwargs) - - # TODO solved alpha belongs in the GASP side, rolled into tabular aero - # It is currently only here because it is not possible to define - # per-subsystem code origins in AviaryProblem yet - elif method == 'solved_alpha': - aero_group = SolvedAlphaGroup(num_nodes=num_nodes, - aero_data=kwargs.pop('aero_data'), - **kwargs) - - elif method == 'tabular': - aero_group = TabularAeroGroup(num_nodes=num_nodes, - CD0_data=kwargs.pop('CD0_data'), - CDI_data=kwargs.pop('CDI_data'), - **kwargs) - elif method == 'external': - # Aero completely replaced by external group. - aero_group = None + aero_group = None + + if method != 'external': + if self.code_origin is FLOPS: + if method is None: + aero_group = ComputedAeroGroup(num_nodes=num_nodes) + + elif method == 'computed': + aero_group = ComputedAeroGroup(num_nodes=num_nodes, **kwargs) + + elif method == 'low_speed': + aero_group = TakeoffAeroGroup( + num_nodes=num_nodes, aviary_options=aviary_inputs, **kwargs + ) + + # TODO solved alpha belongs in the GASP side, rolled into tabular aero + # It is currently only here because it is not possible to define + # per-subsystem code origins in AviaryProblem yet + elif method == 'solved_alpha': + aero_group = SolvedAlphaGroup( + num_nodes=num_nodes, aero_data=kwargs.pop('aero_data'), **kwargs + ) + + elif method == 'tabular': + aero_group = TabularAeroGroup( + num_nodes=num_nodes, + CD0_data=kwargs.pop('CD0_data'), + CDI_data=kwargs.pop('CDI_data'), + **kwargs + ) - else: - raise ValueError('FLOPS-based aero method is not one of the following: ' - '(computed, low_speed, solved_alpha, tabular)') - - elif self.code_origin is GASP: - if method is None: - aero_group = CruiseAero(num_nodes=num_nodes, - aviary_options=aviary_inputs) - - elif method == 'cruise': - if 'aero_data' in kwargs: - aero_group = TabularCruiseAero(num_nodes=num_nodes, - aviary_options=aviary_inputs, - aero_data=kwargs.pop('aero_data'), - **kwargs) else: - aero_group = CruiseAero(num_nodes=num_nodes, - **kwargs) - - elif method == 'low_speed': - if any(key in kwargs for key in ['free_aero_data', - 'free_flaps_data', - 'free_ground_data']) in kwargs: - aero_group = TabularLowSpeedAero(num_nodes=num_nodes, - free_aero_data=kwargs.pop( - 'free_aero_data'), - free_flaps_data=kwargs.pop( - 'free_flaps_data'), - free_ground_data=kwargs.pop( - 'free_ground_data'), - **kwargs) + raise ValueError( + 'FLOPS-based aero method is not one of the following: ' + '(computed, low_speed, solved_alpha, tabular)' + ) + + elif self.code_origin is GASP: + if method is None: + aero_group = CruiseAero( + num_nodes=num_nodes, aviary_options=aviary_inputs + ) + + elif method == 'cruise': + if 'aero_data' in kwargs: + aero_group = TabularCruiseAero( + num_nodes=num_nodes, + aviary_options=aviary_inputs, + aero_data=kwargs.pop('aero_data'), + **kwargs + ) + else: + aero_group = CruiseAero(num_nodes=num_nodes, **kwargs) + + elif method == 'low_speed': + if ( + any( + key in kwargs + for key in [ + 'free_aero_data', + 'free_flaps_data', + 'free_ground_data', + ] + ) + in kwargs + ): + aero_group = TabularLowSpeedAero( + num_nodes=num_nodes, + free_aero_data=kwargs.pop('free_aero_data'), + free_flaps_data=kwargs.pop('free_flaps_data'), + free_ground_data=kwargs.pop('free_ground_data'), + **kwargs + ) + + else: + aero_group = LowSpeedAero(num_nodes=num_nodes, **kwargs) else: - aero_group = LowSpeedAero(num_nodes=num_nodes, - **kwargs) - - else: - raise ValueError('GASP-based aero method is not one of the following: ' - '(cruise, low_speed)') + raise ValueError( + 'GASP-based aero method is not one of the following: ' + '(cruise, low_speed)' + ) return aero_group diff --git a/aviary/subsystems/geometry/geometry_builder.py b/aviary/subsystems/geometry/geometry_builder.py index 37c3b7358..3187f4c70 100644 --- a/aviary/subsystems/geometry/geometry_builder.py +++ b/aviary/subsystems/geometry/geometry_builder.py @@ -82,30 +82,45 @@ def __init__(self, name=None, meta_data=None, code_origin=None, super().__init__(name=name, meta_data=meta_data) - def build_pre_mission(self, aviary_inputs): + def build_pre_mission(self, aviary_inputs, **kwargs): code_origin = self.code_origin both_geom = self.use_both_geometries code_origin_to_prioritize = self.code_origin_to_prioritize + try: + method = kwargs.pop('method') + except KeyError: + method = None geom_group = None - if both_geom: - geom_group = CombinedGeometry( - code_origin_to_prioritize=code_origin_to_prioritize - ) + if method != 'external': + if both_geom: + geom_group = CombinedGeometry( + code_origin_to_prioritize=code_origin_to_prioritize + ) - elif code_origin is GASP: - geom_group = SizeGroup() - geom_group.manual_overrides = None + elif code_origin is GASP: + geom_group = SizeGroup() + geom_group.manual_overrides = None - elif code_origin is FLOPS: - geom_group = PrepGeom() - geom_group.manual_overrides = None + elif code_origin is FLOPS: + geom_group = PrepGeom() + geom_group.manual_overrides = None return geom_group def build_mission(self, num_nodes, aviary_inputs, **kwargs): - super().build_mission(num_nodes, aviary_inputs) + # by default there is no geom mission, but call super for safety/future-proofing + try: + method = kwargs.pop('method') + except KeyError: + method = None + geom_group = None + + if method != 'external': + geom_group = super().build_mission(num_nodes, aviary_inputs) + + geom_group def get_parameters(self, aviary_inputs=None, phase_info=None): num_engine_type = len(aviary_inputs.get_val(Aircraft.Engine.NUM_ENGINES)) diff --git a/aviary/subsystems/mass/mass_builder.py b/aviary/subsystems/mass/mass_builder.py index 772a9b838..9ef1a178c 100644 --- a/aviary/subsystems/mass/mass_builder.py +++ b/aviary/subsystems/mass/mass_builder.py @@ -55,19 +55,35 @@ def __init__(self, name=None, meta_data=None, code_origin=None): super().__init__(name=name, meta_data=meta_data) - def build_pre_mission(self, aviary_inputs): + def build_pre_mission(self, aviary_inputs, **kwargs): code_origin = self.code_origin + try: + method = kwargs.pop('method') + except KeyError: + method = None + mass_group = None - if code_origin is GASP: - mass_premission = MassPremissionGASP() + if method != 'external': + if code_origin is GASP: + mass_group = MassPremissionGASP() - elif code_origin is FLOPS: - mass_premission = MassPremissionFLOPS() + elif code_origin is FLOPS: + mass_group = MassPremissionFLOPS() - return mass_premission + return mass_group def build_mission(self, num_nodes, aviary_inputs, **kwargs): - super().build_mission(num_nodes, aviary_inputs) + # by default there is no mass mission, but call super for safety/future-proofing + try: + method = kwargs.pop('method') + except KeyError: + method = None + mass_group = None + + if method != 'external': + mass_group = super().build_mission(num_nodes, aviary_inputs) + + mass_group def report(self, prob, reports_folder, **kwargs): """ From c00b63e08f3d3e97b8a1c61af2c089f66dead578 Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Tue, 21 Jan 2025 19:33:17 -0500 Subject: [PATCH 2/4] docs update --- aviary/docs/user_guide/mass.ipynb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aviary/docs/user_guide/mass.ipynb b/aviary/docs/user_guide/mass.ipynb index 912484e2e..07230f4b6 100644 --- a/aviary/docs/user_guide/mass.ipynb +++ b/aviary/docs/user_guide/mass.ipynb @@ -44,7 +44,10 @@ "Which variables are used depends on which mass estimation subsystem you're using, such as `aircraft:crew_and_payload:mass_per_passenger`, `aircraft:engine:additional_mass_fraction`, etc.\n", "\n", "Aviary allows for extensive customization and extensions within the mass subsystem.\n", - "Users can develop alternative components and integrate them as subsystems with the existing platform." + "Users can develop alternative components and integrate them as subsystems with the existing platform.\n", + "\n", + "## External Mass\n", + "Specifying the `external` mass method disables Aviary's core mass group. This allows for external subsystems to completely replace these calculations." ] }, { From 6befc84f7a04717f4b704e872c0f1a2bd823491f Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Wed, 22 Jan 2025 15:17:29 -0500 Subject: [PATCH 3/4] Fixed glue arg check for aerodynamics builder --- aviary/docs/user_guide/aerodynamics.ipynb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aviary/docs/user_guide/aerodynamics.ipynb b/aviary/docs/user_guide/aerodynamics.ipynb index e8504ef81..7ea616e97 100644 --- a/aviary/docs/user_guide/aerodynamics.ipynb +++ b/aviary/docs/user_guide/aerodynamics.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "tags": [ "remove-cell" @@ -43,7 +43,7 @@ "# Testing Cell\n", "from aviary.api import CoreAerodynamicsBuilder\n", "from aviary.utils.doctape import check_args\n", - "check_args(CoreAerodynamicsBuilder.build_pre_mission,['aviary_inputs'])" + "check_args(CoreAerodynamicsBuilder.build_pre_mission,['aviary_inputs', 'kwargs'])" ] }, { @@ -133,7 +133,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "tags": [ "remove-cell" From 3c7313c68b998a2620373d98034d565d842b61e5 Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Wed, 22 Jan 2025 15:48:16 -0500 Subject: [PATCH 4/4] removed output cells --- aviary/docs/user_guide/aerodynamics.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aviary/docs/user_guide/aerodynamics.ipynb b/aviary/docs/user_guide/aerodynamics.ipynb index 7ea616e97..336258a67 100644 --- a/aviary/docs/user_guide/aerodynamics.ipynb +++ b/aviary/docs/user_guide/aerodynamics.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "tags": [ "remove-cell" @@ -133,7 +133,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "tags": [ "remove-cell"