Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor level2 to eliminate the input_sink and set all input defaults in the top group's configure method. #132

Merged
merged 7 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions aviary/docs/getting_started/onboarding_level2.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,6 @@
"metadata": {},
"outputs": [],
"source": [
"print(\"Zero Fuel Mass (lbm)\",\n",
" prob.get_val(Aircraft.Design.ZERO_FUEL_MASS, units='lbm'))\n",
"print(\"Mission.Objectives.FUEL\",\n",
" prob.get_val(Mission.Objectives.FUEL, units='unitless'))\n",
"print(\"Mission.Design.FUEL_MASS\",\n",
Expand Down Expand Up @@ -889,7 +887,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
Expand All @@ -903,7 +901,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.17"
"version": "3.8.10"
}
},
"nbformat": 4,
Expand Down
72 changes: 56 additions & 16 deletions aviary/interface/methods_for_level2.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from aviary.mission.gasp_based.phases.v_rotate_comp import VRotateComp
from aviary.mission.gasp_based.polynomial_fit import PolynomialFit
from aviary.subsystems.premission import CorePreMission
from aviary.utils.functions import set_aviary_initial_values, create_opts2vals, add_opts2vals, promote_aircraft_and_mission_vars
from aviary.utils.functions import create_opts2vals, add_opts2vals, promote_aircraft_and_mission_vars
from aviary.utils.process_input_decks import create_vehicle, update_GASP_options, initial_guessing
from aviary.utils.preprocessors import preprocess_crewpayload
from aviary.interface.utils.check_phase_info import check_phase_info
Expand All @@ -46,7 +46,6 @@
from aviary.variable_info.variables import Aircraft, Mission, Dynamic, Settings
from aviary.variable_info.enums import AnalysisScheme, ProblemType, SpeedType, AlphaModes, EquationsOfMotion, LegacyCode
from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData
from aviary.variable_info.variables_in import VariablesIn

from aviary.subsystems.propulsion.engine_deck import EngineDeck
from aviary.subsystems.propulsion.propulsion_builder import CorePropulsionBuilder
Expand All @@ -58,7 +57,6 @@

from aviary.interface.default_phase_info.two_dof_fiti import create_2dof_based_ascent_phases, create_2dof_based_descent_phases
from aviary.mission.gasp_based.idle_descent_estimation import descent_range_and_fuel
from aviary.mission.flops_based.phases.phase_utils import get_initial
from aviary.mission.phase_builder_base import PhaseBuilderBase


Expand Down Expand Up @@ -114,6 +112,58 @@ def configure(self):
promote_aircraft_and_mission_vars(self)


class AviaryGroup(om.Group):
"""
A standard OpenMDAO group that handles Aviary's promotions in the configure
method. This assures that we only call set_input_defaults on variables
that are present in the model.
"""

def initialize(self):
self.options.declare(
'aviary_options', types=AviaryValues,
desc='collection of Aircraft/Mission specific options')
self.options.declare(
'aviary_metadata', types=dict,
desc='metadata dictionary of the full aviary problem.')

def configure(self):
aviary_options = self.options['aviary_options']
aviary_metadata = self.options['aviary_metadata']

all_prom_inputs = []

# Find promoted name of every input in the model.
for system in self.system_iter(recurse=False):
var_abs = system.list_inputs(out_stream=None)
var_prom = [v['prom_name'] for k, v in var_abs]
all_prom_inputs.extend(var_prom)

for key in aviary_metadata:

if ':' not in key or key.startswith('dynamic:'):
continue

if aviary_metadata[key]['option']:
continue

# Skip anything that is not presently an input.
if key not in all_prom_inputs:
continue

if key in aviary_options:
val, units = aviary_options.get_item(key)
else:
val = aviary_metadata[key]['default_value']
units = aviary_metadata[key]['units']

if val is None:
# optional, but no default value
continue

self.set_input_defaults(key, val=val, units=units)


class AviaryProblem(om.Problem):
"""
Main class for instantiating, formulating, and solving Aviary problems.
Expand All @@ -135,7 +185,7 @@ def __init__(self, analysis_scheme=AnalysisScheme.COLLOCATION, **kwargs):

self.timestamp = datetime.now()

self.model = om.Group()
self.model = AviaryGroup()
self.pre_mission = PreMissionGroup()
self.post_mission = PostMissionGroup()

Expand Down Expand Up @@ -1772,22 +1822,12 @@ def setup(self, **kwargs):
calls to `set_input_defaults` and do some simple `set_vals`
if needed.
"""
# Adding a trailing component that contains all inputs so that set_input_defaults
# doesn't raise any errors.
self.model.add_subsystem(
'input_sink',
VariablesIn(aviary_options=self.aviary_inputs,
meta_data=self.meta_data),
promotes_inputs=['*'],
promotes_outputs=['*'])

# suppress warnings:
# "input variable '...' promoted using '*' was already promoted using 'aircraft:*'
with warnings.catch_warnings():

# Set initial default values for all LEAPS aircraft variables.
set_aviary_initial_values(
self.model, self.aviary_inputs, meta_data=self.meta_data)
self.model.options['aviary_options'] = self.aviary_inputs
self.model.options['aviary_metadata'] = self.meta_data

warnings.simplefilter("ignore", om.OpenMDAOWarning)
warnings.simplefilter("ignore", om.PromotionWarning)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_subsystems_in_a_mission(self):

prob.add_design_variables()

prob.add_objective('fuel')
prob.add_objective('fuel_burned')

prob.setup()

Expand Down
Loading