Two-dof refactor part 3: Added a new ODE/Phase for a simple cruise that is more consistent with the other phases.#986
Conversation
… the basic 2DOF problem. May need to investigate
… the basic 2DOF problem. May need to investigate
… the basic 2DOF problem. May need to investigate
| for subsystem in subsystems: | ||
| # check if subsystem_options has entry for a subsystem of this name | ||
| if subsystem.name in subsystem_options: | ||
| kwargs.update(subsystem_options[subsystem.name]) |
There was a problem hiding this comment.
I think we need to update how we handle the kwargs. Some things like num_nodes, aviary_options could be provided directly as arguments to build_mission(), and we can check for AerodynamicsBuilders before getting the subsystem-specific kwargs to make sure 'method' and 'output_alpha' are defaulted to our desired values.
This prevents kwargs from getting more cluttered with irrelevant options as we loop through subsystems and makes sure the desired aero defaults don't get overwritten if an earlier subsystem happens to use an identically named option
There was a problem hiding this comment.
This applies to all the 2DOF ODEs but should be able to be quickly copy-pasted to them all
| kwargs = { | ||
| 'num_nodes': nn, | ||
| 'aviary_inputs': aviary_options, | ||
| 'method': 'cruise', | ||
| 'output_alpha': True, | ||
| } | ||
| for subsystem in subsystems: | ||
| # check if subsystem_options has entry for a subsystem of this name | ||
| if subsystem.name in subsystem_options: | ||
| kwargs.update(subsystem_options[subsystem.name]) | ||
| system = subsystem.build_mission(**kwargs) | ||
| if system is not None: | ||
| if isinstance(subsystem, PropulsionBuilder): | ||
| prop_group.add_subsystem( | ||
| subsystem.name, | ||
| system, | ||
| promotes_inputs=subsystem.mission_inputs(**kwargs), | ||
| promotes_outputs=subsystem.mission_outputs(**kwargs), | ||
| ) | ||
| else: | ||
| self.add_subsystem( | ||
| subsystem.name, | ||
| system, | ||
| promotes_inputs=subsystem.mission_inputs(**kwargs), | ||
| promotes_outputs=subsystem.mission_outputs(**kwargs), | ||
| ) |
There was a problem hiding this comment.
I took a quick crack at what a revised kwargs handling could look like
| kwargs = { | |
| 'num_nodes': nn, | |
| 'aviary_inputs': aviary_options, | |
| 'method': 'cruise', | |
| 'output_alpha': True, | |
| } | |
| for subsystem in subsystems: | |
| # check if subsystem_options has entry for a subsystem of this name | |
| if subsystem.name in subsystem_options: | |
| kwargs.update(subsystem_options[subsystem.name]) | |
| system = subsystem.build_mission(**kwargs) | |
| if system is not None: | |
| if isinstance(subsystem, PropulsionBuilder): | |
| prop_group.add_subsystem( | |
| subsystem.name, | |
| system, | |
| promotes_inputs=subsystem.mission_inputs(**kwargs), | |
| promotes_outputs=subsystem.mission_outputs(**kwargs), | |
| ) | |
| else: | |
| self.add_subsystem( | |
| subsystem.name, | |
| system, | |
| promotes_inputs=subsystem.mission_inputs(**kwargs), | |
| promotes_outputs=subsystem.mission_outputs(**kwargs), | |
| ) | |
| for subsystem in subsystems: | |
| kwargs = {} | |
| # check if subsystem_options has entry for a subsystem of this name | |
| if subsystem.name in subsystem_options: | |
| kwargs = subsystem_options[subsystem.name] | |
| if isinstance(subsystem, AerodynamicsBuilder): | |
| # set default options for Aero if not specified by user | |
| base_kwargs = { | |
| 'method': 'cruise', | |
| 'output_alpha': True | |
| } | |
| kwargs = base_kwargs.update(kwargs) | |
| system = subsystem.build_mission(num_nodes=nn, aviary_inputs=aviary_options, **kwargs) | |
| if system is not None: | |
| if isinstance(subsystem, PropulsionBuilder): | |
| prop_group.add_subsystem( | |
| subsystem.name, | |
| system, | |
| promotes_inputs=subsystem.mission_inputs(**kwargs), | |
| promotes_outputs=subsystem.mission_outputs(**kwargs), | |
| ) | |
| else: | |
| self.add_subsystem( | |
| subsystem.name, | |
| system, | |
| promotes_inputs=subsystem.mission_inputs(**kwargs), | |
| promotes_outputs=subsystem.mission_outputs(**kwargs), | |
| ) |
There was a problem hiding this comment.
Good point. This should be easy to clean up.
EDIT - Updated Simple Cruise, Breguet Cruise, and Flight. The other ones got deleted and replaced in part 4, so I will continue this there.
| is_analytic_phase=True, | ||
| ): | ||
| if is_analytic_phase is not True: | ||
| msg = 'The Breguet Cruise phase does not support dynamic variables in its subsystems.' | ||
| raise AttributeError(msg) | ||
|
|
There was a problem hiding this comment.
Why even provide the option to try making Breguet cruise not analytic?
Maybe something I should have noticed earlier... does this ever need to be defined when initializing any PhaseBuilder? The user will typically never be able to toggle this without breaking everything
There was a problem hiding this comment.
The is_analytic_phase gets toggled to False if one of the subsystems has a dynamic phase. I don't think the user can ever set this flag. I could probably rename it to something like _subsystems_have states.
EDIT - I am going to rework this, and check the subsystems directly in Breguet Range instead of in the base class.
|
Ok, rework done. Much cleaner now. Also added a test for that error message. |
Summary
Motivation: The original Cruise phase in the two-dof equations of motion is based on the Breguet Range equations, and uses an AnalyticPhase from Dymos, and additionally integrates over mass instead of time. This causes problems when trying to add an external subsystem with a state that needs to be integrated over time. This PR adds an alternative that eliminates these problems.
Added a new SimpleCruise eom, ode, and phase to the two-dof formulation.
Added a new option "phase_builder" to the phase_options to allow the user to specify what phase_builder to use for this phase. The following choices are valid:
Presently, this option only works for the two-dof equations of motion, but there is a potential to expand the capability to use these phases in other equations.
Related Issues
Backwards incompatibilities
None
New Dependencies
None