Fancy post-mission bus variables
Summary
This PR adds a new method to SubsystemBuilderBase called get_mission_bus_variables. This method allows users to tell which mission output variables are needed in post-mission, and how to connect them from mission to post-mission. It is version of get_bus_variables but for mission variables: get_bus_variables is for connecting pre-mission variables to mission and post-mission, and get_mission_bus_variables is for connecting mission variables to post-mission.
To accomplish this, a new dymos timeseries is created for each phase called mission_bus_variables. Currently this timeseries is defined on a uniform time grid with the same number of segments as the corresponding phase. The get_mission_bus_variables method returns a nested dict that describes how the mission variables are connected to the post-mission:
def get_mission_bus_variables(self, aviary_data=None, phase_info=None):
"""
Return a dict mapping phase names to a dict mapping mission variable names to (a list of) post-mission variable names.
Mission variables local to a given external subsystem should be prefixed with that subsystem's name.
For example, to connect a variable 'bar' that is an output of the external subsystem "foo"'s mission to the post-mission variable "cruise_foo", map "foo.bar" to "cruise_foo".
Parameters
----------
aviary_inputs : dict
A dictionary containing the inputs to the subsystem.
phase_info : dict
The phase_info dict for all phases
Example
-------
out = {}
if phase_info:
for phase_name, phase_data in phase_info.items():
phase_d = {}
if phase_data["do_the_thing"]:
phase_d[f"{self.name}.mission_variable_a"] = f"{phase_name}_post_mission_variable_a"
phase_d[f"{self.name}.mission_variable_b"] = [f"{phase_name}_post_mission_variable_b_name1", f"{phase_name}_post_mission_variable_b_name2"]
phase_d[f"{self.name}.mission_variable_c"] = [f"{phase_name}_post_mission_variable_c_name1"]
phase_d[Dynamic.Mission.VELOCITY] = [f"{phase_name}_post_mission_velocity_name1"]
if phase_data["do_the_other_thing"]:
phase_d[f"{self.name}.mission_variable_d"] = f"{phase_name}_post_mission_variable_d"
phase_d[f"{self.name}.mission_variable_e"] = [f"{phase_name}_post_mission_variable_e_name1", f"{phase_name}_post_mission_variable_e_name2"]
phase_d[f"{self.name}.mission_variable_f"] = [f"{phase_name}_post_mission_variable_f_name1"]
phase_d[Dynamic.Atmosphere.KINEMATIC_VISCOSITY] = f"{phase_name}_post_mission_nu_name1"
out[phase_name] = phase_d
return out
"""
return {}
The Aviary/aviary/subsystems/test/test_external_subsystem_bus.py file has been updated to test this new functionality.
I haven't run any other tests, or updated the docs, or...
Just want to get this on someone's radar for feedback, etc..
Related Issues
- Resolves #
Backwards incompatibilities
~~Maybe!
I had to change the interface for build_post_mission to accept a few more arguments to make this doable.
I haven't thought about if it's backwards-compatible or not.~~
get_bus_variableshas been renamed toget_pre_mission_bus_variables- An external subsystem's
build_post_missionwill now be called in the following manner:
def build_post_mission(self, aviary_inputs, phase_info, phase_mission_bus_lengths):
New Dependencies
None
OK, I guess this PR is where I'd like it to be. Appreciate any feedback!
You might get some formatting-based conflicts since we just switched the repo over to using ruff - if you run ruff over your code it should line it back up with main and the conflicts with main might resolve themselves
https://github.com/astral-sh/ruff
pip install ruff
ruff format <filename.py>
@jkirk5 @Kenneth-T-Moore Do you have any idea what went wrong with the docs build? I only made one small change to one of the Jupyter notebooks (just renaming get_bus_variables to get_pre_mission_bus_variables). I tried to build them locally but I don't think I have everything set up (IPOPT, etc) to do that successfully.
@jkirk5 @Kenneth-T-Moore Do you have any idea what went wrong with the docs build? I only made one small change to one of the Jupyter notebooks (just renaming
get_bus_variablestoget_pre_mission_bus_variables). I tried to build them locally but I don't think I have everything set up (IPOPT, etc) to do that successfully.
@dingraha
I think you will just need to go to this file:
https://github.com/OpenMDAO/Aviary/blob/85861c0ec5bb83f84ddeb0f29204742c16e1539a/aviary/docs/user_guide/subsystems.ipynb
and replace get_bus_variables with get_pre_mission_bus_variables.
@Kenneth-T-Moore Thanks, that did the trick! I did grep for get_bus_variables, but must have missed that one somehow.