diff --git a/aviary/core/aviary_group.py b/aviary/core/aviary_group.py index c157ccdab4..84869f6789 100644 --- a/aviary/core/aviary_group.py +++ b/aviary/core/aviary_group.py @@ -9,8 +9,7 @@ from dymos.utils.misc import _unspecified from openmdao.utils.mpi import MPI -from aviary.core.post_mission_group import PostMissionGroup -from aviary.core.pre_mission_group import PreMissionGroup +from aviary.core.static_group import StaticGroup from aviary.interface.utils import set_warning_format from aviary.mission.energy_state_problem_configurator import EnergyStateProblemConfigurator from aviary.mission.solved_two_dof_problem_configurator import SolvedTwoDOFProblemConfigurator @@ -70,7 +69,7 @@ class AviaryGroup(om.Group): def __init__(self, verbosity=None, **kwargs): super().__init__(**kwargs) - self.post_mission = PostMissionGroup() + self.post_mission = StaticGroup() self.verbosity = verbosity self.external_subsystems = [] self.engine_models = [] @@ -206,6 +205,28 @@ def configure(self): phase.indep_states.nonlinear_solver = om.NewtonSolver(solve_subsystems=True) phase.indep_states.linear_solver = om.DirectSolver(rhs_checking=True) + def _override_verbosity(self, verbosity): + """ + Overrides verbosity setting for this method. + + Parameters + ---------- + verbosity : int, Verbosity (optional) + Verbosity level requested for this method. + + Returns + ------- + Verbosity + New verbosity for this method. + """ + if verbosity is not None: + # compatibility with being passed int for verbosity + verbosity = Verbosity(verbosity) + else: + verbosity = self.verbosity # defaults to BRIEF + + return verbosity + def load_inputs( self, aircraft_data, @@ -224,13 +245,7 @@ def load_inputs( This method is not strictly necessary; a user could also supply an AviaryValues object and/or phase_info dict of their own. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) # validate phase info modifier function if phase_info_modifier is not None: @@ -339,17 +354,10 @@ def load_external_subsystems(self, external_subsystems: list = [], verbosity=Non ---------- external_subsystems : list of SubsystemBuilders List of all external subsystems to be added. - verbosity : int, Verbosity (optional) - Sets the printout level for the entire off-design problem that is ran. + Verbosity level for this API call. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) for subsystem in external_subsystems: if not isinstance(subsystem, SubsystemBuilder) and verbosity >= verbosity.BRIEF: @@ -370,13 +378,7 @@ def check_and_preprocess_inputs(self, verbosity=None): This method checks the user-supplied input values for any potential problems and preprocesses the inputs to prepare them for use in the Aviary problem. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) aviary_inputs = self.aviary_inputs # Target_distance verification for all phases @@ -559,7 +561,7 @@ def add_pre_mission_systems(self, verbosity=None): A user can override this method with their own pre-mission systems as desired. """ - pre_mission = PreMissionGroup() + pre_mission = StaticGroup() all_subsystem_options = self.pre_mission_info.get('subsystem_options', {}) self.add_subsystem( @@ -569,7 +571,7 @@ def add_pre_mission_systems(self, verbosity=None): promotes_outputs=['aircraft:*', 'mission:*'], ) - # TODO temporary until way to merge PreMissionGroup and CorePreMission group is found + # TODO temporary until way to merge StaticGroup and CorePreMission group is found core_subsystems = self.subsystems[0:5] # Propulsion isn't included in core pre-mission group to avoid override step in @@ -715,13 +717,7 @@ def add_phases(self, parallel_phases=True, verbosity=None, comm=None): ------- traj: The Dymos Trajectory object containing the added mission phases. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.phase_info_modifier is not None: self.mission_info, self.post_mission_info = self.phase_info_modifier( @@ -824,13 +820,7 @@ def add_post_mission_systems(self, verbosity=None): A user can override this with their own postmission systems. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) post_mission = self.post_mission self.add_subsystem( @@ -1111,13 +1101,7 @@ def link_phases(self, verbosity=None, comm=None): If a variable is common to two phases, it can be linked via a direct connection or a constraint. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity override for - # just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) self._add_bus_variables_and_connect() self._connect_mission_bus_variables() @@ -1486,13 +1470,7 @@ def add_design_variables(self, problem_type: ProblemType = None, verbosity=None) In all cases, a design variable is added for the final cruise mass of the aircraft, with no upper bound, and a residual mass constraint is added to ensure that the mass balances. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) all_subsystems = self.subsystems @@ -1641,13 +1619,7 @@ def set_initial_guesses(self, parent_prob=None, parent_prefix='', verbosity=None if not hasattr(self, 'traj'): return - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) target_prob = self if parent_prob is not None and parent_prefix != '': diff --git a/aviary/core/aviary_problem.py b/aviary/core/aviary_problem.py index c03c32afdf..e38f82714c 100644 --- a/aviary/core/aviary_problem.py +++ b/aviary/core/aviary_problem.py @@ -121,6 +121,28 @@ def __init__( # problems don't have a consistent variable path to check the inputs later on self.generate_payload_range = False + def _override_verbosity(self, verbosity): + """ + Overrides verbosity setting for this method. + + Parameters + ---------- + verbosity : int, Verbosity (optional) + Verbosity level requested for this method. + + Returns + ------- + Verbosity + New verbosity for this method. + """ + if verbosity is not None: + # compatibility with being passed int for verbosity + verbosity = Verbosity(verbosity) + else: + verbosity = self.verbosity # defaults to BRIEF + + return verbosity + def load_inputs( self, aircraft_data, @@ -166,11 +188,7 @@ def load_inputs( # We haven't read the input data yet, we don't know what desired run verbosity is # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # usually None + verbosity = self._override_verbosity(verbosity) if meta_data is not None: # Support for custom meta_data set. @@ -215,13 +233,7 @@ def load_external_subsystems(self, external_subsystems: list = [], verbosity=Non Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -277,13 +289,7 @@ def add_aviary_group( ValueError If ``problem_type`` is not ``ProblemType.MULTI_MISSION``. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type is not ProblemType.MULTI_MISSION: ValueError( @@ -330,13 +336,7 @@ def check_and_preprocess_inputs(self, verbosity=None): Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -368,13 +368,7 @@ def add_pre_mission_systems(self, verbosity=None): Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -407,13 +401,7 @@ def add_phases( dm.Trajectory The Dymos Trajectory object containing the added mission phases. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -461,13 +449,7 @@ def add_post_mission_systems(self, verbosity=None): Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -499,13 +481,7 @@ def link_phases(self, verbosity=None): Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -537,13 +513,7 @@ def add_driver(self, optimizer='IPOPT', use_coloring=True, max_iter=50, verbosit Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) # Set defaults for optimizer, use_coloring and max_iter if optimizer is None: @@ -682,13 +652,7 @@ def add_design_variables(self, verbosity=None): In all cases, a design variable is added for the final cruise mass of the aircraft, with no upper bound, and a residual mass constraint is added to ensure that the mass balances. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -725,13 +689,7 @@ def add_objective(self, objective_type=None, ref=None, verbosity=None): ValueError If an invalid ``objective_type`` or ``problem_type`` is provided. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) # This isn't really a fuel objective, it's a hybrid or compound objective self.model.add_subsystem( @@ -1042,9 +1000,8 @@ def add_composite_objective(self, *args, ref: float = None): # weighted_str looks like: 'model1_fuelburn*0.67*0.5 + model1_gross_mass*0.33*0.5 + model2_fuelburn*0.67*0.5 + model2_gross_mass*0.33*0.5' kwargs = {} - if version.parse(openmdao.__version__) >= version.parse('3.40'): - # We can get the correct unit from the source. This prevents a warning. - kwargs = {k: {'units_by_conn': True} for k in obj_inputs} + # We can get the correct unit from the source. This prevents a warning. + kwargs = {k: {'units_by_conn': True} for k in obj_inputs} # adding composite execComp to super problem self.model.add_subsystem( @@ -1148,13 +1105,7 @@ def build_model(self, verbosity=None): Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -1257,13 +1208,7 @@ def set_initial_guesses(self, parent_prob=None, parent_prefix='', verbosity=None Controls the level of terminal output for this method. If None, uses the problem-level verbosity. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if self.problem_type == ProblemType.MULTI_MISSION: for name, group in self.aviary_groups_dict.items(): @@ -1316,13 +1261,7 @@ def run_aviary_problem( real_time_plotting : bool, optional If True, enables real-time plotting of the optimization progress. """ - # `self.verbosity` is "true" verbosity for entire run. `verbosity` is verbosity - # override for just this method - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if ( verbosity >= Verbosity.VERBOSE or real_time_plotting @@ -1492,12 +1431,7 @@ def run_off_design_mission( UserWarning If ``problem_type`` is ``SIZING``, or if both ``fill_cargo`` and ``fill_fuel`` are True. """ - # For off-design missions, provided verbosity will be used for all L2 method calls - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) # accept str for problem type problem_type = ProblemType(problem_type) @@ -1735,12 +1669,7 @@ def run_payload_range(self, verbosity=None): Currently only supported for the energy state equations of motion. Reserve fuel is not yet accounted for in the analysis. """ - # For off-design missions, provided verbosity will be used for all L2 method calls - if verbosity is not None: - # compatibility with being passed int for verbosity - verbosity = Verbosity(verbosity) - else: - verbosity = self.verbosity # defaults to BRIEF + verbosity = self._override_verbosity(verbosity) if not self.result.success and verbosity > Verbosity.QUIET: warnings.warn( diff --git a/aviary/core/post_mission_group.py b/aviary/core/post_mission_group.py deleted file mode 100644 index 48d5895f42..0000000000 --- a/aviary/core/post_mission_group.py +++ /dev/null @@ -1,23 +0,0 @@ -import openmdao -import openmdao.api as om -from packaging import version - -from aviary.utils.functions import promote_aircraft_and_mission_vars - -use_new_openmdao_syntax = version.parse(openmdao.__version__) >= version.parse('3.28') - - -class PostMissionGroup(om.Group): - """OpenMDAO group that holds all post-mission systems.""" - - def setup(self, **kwargs): - if use_new_openmdao_syntax: - # rely on openMDAO's auto-ordering for this group - self.options['auto_order'] = True - - def configure(self): - """ - Configure this group for post-mission. - Promote aircraft and mission variables. - """ - promote_aircraft_and_mission_vars(self) diff --git a/aviary/core/pre_mission_group.py b/aviary/core/pre_mission_group.py deleted file mode 100644 index 0122d37b95..0000000000 --- a/aviary/core/pre_mission_group.py +++ /dev/null @@ -1,24 +0,0 @@ -import openmdao.api as om - -from aviary.utils.functions import promote_aircraft_and_mission_vars -from aviary.variable_info.functions import override_aviary_vars - - -class PreMissionGroup(om.Group): - """OpenMDAO group that holds all pre-mission systems.""" - - def configure(self): - """ - Configure this group for pre-mission. - Promote aircraft and mission variables. - Override output aviary variables. - """ - external_outputs = promote_aircraft_and_mission_vars(self) - - pre_mission = self.core_subsystems - override_aviary_vars( - pre_mission, - pre_mission.options['aviary_options'], - external_overrides=external_outputs, - code_origin_overrides=pre_mission.code_origin_overrides, - ) diff --git a/aviary/core/static_group.py b/aviary/core/static_group.py new file mode 100644 index 0000000000..5ba7bd705e --- /dev/null +++ b/aviary/core/static_group.py @@ -0,0 +1,34 @@ +import openmdao.api as om + +from aviary.utils.functions import promote_aircraft_and_mission_vars +from aviary.variable_info.functions import override_aviary_vars + + +class StaticGroup(om.Group): + """Aviary top-level group that is not a dynamic mission. + + This class is used for top pre_mission and post_mission groups. + """ + + def setup(self, **kwargs): + self.options['auto_order'] = True + + def configure(self): + """ + Configure this group for pre or post mission. + Promote aircraft and mission variables. + Override output aviary variables. + """ + external_outputs = promote_aircraft_and_mission_vars(self) + + if not hasattr(self, 'core_subsystems'): + # TODO Post mission doesn't support core subsystems yet. + return + + core_subs = self.core_subsystems + override_aviary_vars( + core_subs, + core_subs.options['aviary_options'], + external_overrides=external_outputs, + code_origin_overrides=core_subs.code_origin_overrides, + ) diff --git a/aviary/docs/examples_unreviewed/deconstructed_example.ipynb b/aviary/docs/examples_unreviewed/deconstructed_example.ipynb index 10df31ffcc..a333b6a82e 100644 --- a/aviary/docs/examples_unreviewed/deconstructed_example.ipynb +++ b/aviary/docs/examples_unreviewed/deconstructed_example.ipynb @@ -149,7 +149,7 @@ "import openmdao.api as om\n", "\n", "import aviary.api as av\n", - "from aviary.core.pre_mission_group import PreMissionGroup\n", + "from aviary.core.static_group import StaticGroup\n", "from aviary.mission.flight_phase_builder import FlightPhaseOptions\n", "from aviary.mission.energy_state.ode.energy_state_ODE import EnergyStateODE\n", "from aviary.models.missions.energy_state_default import phase_info\n", @@ -215,7 +215,7 @@ "\n", "prob.model.add_subsystem(\n", " 'pre_mission',\n", - " PreMissionGroup(),\n", + " StaticGroup(),\n", " promotes_inputs=['aircraft:*', 'mission:*'],\n", " promotes_outputs=['aircraft:*', 'mission:*'],\n", ")\n", @@ -1009,7 +1009,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.11" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/aviary/mission/base_ode.py b/aviary/mission/base_ode.py index 53cfdea8d6..f541ac7a7f 100644 --- a/aviary/mission/base_ode.py +++ b/aviary/mission/base_ode.py @@ -21,6 +21,12 @@ def configure(self): class BaseODE(om.Group): """The base class for all ODE components.""" + def __init__(self, **kwargs): + super().__init__(**kwargs) + + # Turn on for all ODE systems. + self.options['auto_order'] = True + def initialize(self): self.options.declare('num_nodes', default=1, types=int) self.options.declare( diff --git a/aviary/mission/energy_state/ode/energy_state_ODE.py b/aviary/mission/energy_state/ode/energy_state_ODE.py index 1fff10a71e..31c05d8d08 100644 --- a/aviary/mission/energy_state/ode/energy_state_ODE.py +++ b/aviary/mission/energy_state/ode/energy_state_ODE.py @@ -59,6 +59,7 @@ def setup(self): throttle_enforcement = options['throttle_enforcement'] sub1 = self.add_subsystem('solver_sub', om.Group(), promotes=['*']) + sub1.options['auto_order'] = True use_mission_solver = self.add_subsystems(solver_group=sub1) @@ -175,5 +176,3 @@ def setup(self): sub1.linear_solver = om.DirectSolver(assemble_jac=True) sub1.nonlinear_solver.options['err_on_non_converge'] = True sub1.nonlinear_solver.options['iprint'] = print_level - - self.options['auto_order'] = True diff --git a/aviary/mission/solved_two_dof/ode/unsteady_solved_ode.py b/aviary/mission/solved_two_dof/ode/unsteady_solved_ode.py index 59ccd9783b..4780b481ab 100644 --- a/aviary/mission/solved_two_dof/ode/unsteady_solved_ode.py +++ b/aviary/mission/solved_two_dof/ode/unsteady_solved_ode.py @@ -122,6 +122,7 @@ def setup(self): throttle_balance_group = self.add_subsystem( 'throttle_balance_group', om.Group(), promotes=['*'] ) + throttle_balance_group.options['auto_order'] = True throttle_balance_comp = om.BalanceComp() throttle_balance_comp.add_balance( diff --git a/aviary/mission/two_dof/ode/flight_ode.py b/aviary/mission/two_dof/ode/flight_ode.py index 3b9535bdfc..ec10f9c3e0 100644 --- a/aviary/mission/two_dof/ode/flight_ode.py +++ b/aviary/mission/two_dof/ode/flight_ode.py @@ -33,7 +33,6 @@ def initialize(self): self.options.declare('EAS_target', desc='Targeted EAS in knots') def setup(self): - self.options['auto_order'] = True nn = self.options['num_nodes'] aviary_options = self.options['aviary_options'] subsystems = self.options['subsystems'] diff --git a/aviary/mission/two_dof/ode/flight_path_ode.py b/aviary/mission/two_dof/ode/flight_path_ode.py index 3e4b7fc3f5..17c8c7c4a7 100644 --- a/aviary/mission/two_dof/ode/flight_path_ode.py +++ b/aviary/mission/two_dof/ode/flight_path_ode.py @@ -38,7 +38,6 @@ def initialize(self): ) def setup(self): - self.options['auto_order'] = True nn = self.options['num_nodes'] aviary_options = self.options['aviary_options'] alpha_mode = self.options['alpha_mode'] diff --git a/aviary/mission/two_dof/ode/test/test_flight_ode.py b/aviary/mission/two_dof/ode/test/test_flight_ode.py index d854e77642..2fdcd8a372 100644 --- a/aviary/mission/two_dof/ode/test/test_flight_ode.py +++ b/aviary/mission/two_dof/ode/test/test_flight_ode.py @@ -156,10 +156,6 @@ def setUp(self): setup_model_options(self.prob, aviary_options) - @unittest.skipIf( - version.parse(openmdao.__version__) < version.parse('3.26'), - 'Skipping due to OpenMDAO version being too low (<3.26)', - ) def test_high_alt(self): # Test descent above 10k ft with Mach under and over the EAS limit self.sys.options['num_nodes'] = 2 diff --git a/aviary/mission/two_dof/ode/test/test_landing_ode.py b/aviary/mission/two_dof/ode/test/test_landing_ode.py index 8503b80fd0..2a802c1f02 100644 --- a/aviary/mission/two_dof/ode/test/test_landing_ode.py +++ b/aviary/mission/two_dof/ode/test/test_landing_ode.py @@ -32,10 +32,6 @@ def setUp(self): setup_model_options(self.prob, options) self.prob.model.set_input_defaults(Mission.Landing.AIRPORT_ALTITUDE, 0, units='ft') - @unittest.skipIf( - version.parse(openmdao.__version__) < version.parse('3.26'), - 'Skipping due to OpenMDAO version being too low (<3.26)', - ) def test_dland(self): self.prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/mission/two_dof/ode/test/test_taxi_ode.py b/aviary/mission/two_dof/ode/test/test_taxi_ode.py index 79c2f0d524..2535215b5e 100644 --- a/aviary/mission/two_dof/ode/test/test_taxi_ode.py +++ b/aviary/mission/two_dof/ode/test/test_taxi_ode.py @@ -38,10 +38,6 @@ def setUp(self): 0.0, ) - @unittest.skipIf( - version.parse(openmdao.__version__) < version.parse('3.26'), - 'Skipping due to OpenMDAO version being too low (<3.26)', - ) def test_taxi(self): self.prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/mission/two_dof/test/test_promotion.py b/aviary/mission/two_dof/test/test_promotion.py index 99e64ff0f1..23c7a155d4 100644 --- a/aviary/mission/two_dof/test/test_promotion.py +++ b/aviary/mission/two_dof/test/test_promotion.py @@ -1,3 +1,4 @@ +from copy import deepcopy import unittest import openmdao.api as om @@ -16,9 +17,11 @@ class Test2DOFMissionPromotion(unittest.TestCase): def test_promotion(self): prob = AviaryProblem() + local_phase_info = deepcopy(phase_info) + prob.load_inputs( 'validation_cases/validation_data/test_models/aircraft_for_bench_GwGm.csv', - phase_info, + local_phase_info, verbosity=0, ) diff --git a/aviary/subsystems/atmosphere/test/test_atmosphere.py b/aviary/subsystems/atmosphere/test/test_atmosphere.py index aa0939363d..ca7ca04ba1 100644 --- a/aviary/subsystems/atmosphere/test/test_atmosphere.py +++ b/aviary/subsystems/atmosphere/test/test_atmosphere.py @@ -318,14 +318,12 @@ def test_case1(self): with self.subTest(var=var_name): assert_near_equal(self.prob.get_val(var_name, units=units), expected, tol) - # inHg60 is a newer unit in OpenMDAO so we'll do this check only of that newer version is installed - if Version(openmdao.__version__) >= Version('3.42.0'): - with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): - assert_near_equal( - self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), - expected_pressure, - tol, - ) + with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): + assert_near_equal( + self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), + expected_pressure, + tol, + ) partial_data = self.prob.check_partials(out_stream=None, method='cs') @@ -400,13 +398,12 @@ def test_case1(self): with self.subTest(var=var_name): assert_near_equal(self.prob.get_val(var_name, units=units), expected, tol) - if Version(openmdao.__version__) >= Version('3.42.0'): - with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): - assert_near_equal( - self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), - expected_pressure, - tol, - ) + with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): + assert_near_equal( + self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), + expected_pressure, + tol, + ) partial_data = self.prob.check_partials(out_stream=None, method='cs') @@ -481,13 +478,12 @@ def test_case1(self): with self.subTest(var=var_name): assert_near_equal(self.prob.get_val(var_name, units=units), expected, tol) - if Version(openmdao.__version__) >= Version('3.42.0'): - with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): - assert_near_equal( - self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), - expected_pressure, - tol, - ) + with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): + assert_near_equal( + self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), + expected_pressure, + tol, + ) partial_data = self.prob.check_partials(out_stream=None, method='cs') @@ -562,13 +558,12 @@ def test_case1(self): with self.subTest(var=var_name): assert_near_equal(self.prob.get_val(var_name, units=units), expected, tol) - if Version(openmdao.__version__) >= Version('3.42.0'): - with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): - assert_near_equal( - self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), - expected_pressure, - tol, - ) + with self.subTest(var=Dynamic.Atmosphere.STATIC_PRESSURE): + assert_near_equal( + self.prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, units='inHg60'), + expected_pressure, + tol, + ) partial_data = self.prob.check_partials(out_stream=None, method='cs') diff --git a/aviary/subsystems/premission.py b/aviary/subsystems/premission.py index 09e4f43015..512e408f1d 100644 --- a/aviary/subsystems/premission.py +++ b/aviary/subsystems/premission.py @@ -6,8 +6,6 @@ from aviary.variable_info.functions import override_aviary_vars from aviary.variable_info.variable_meta_data import CoreMetaData -use_new_openmdao_syntax = version.parse(openmdao.__version__) >= version.parse('3.28') - class CorePreMission(om.Group): """ @@ -38,9 +36,8 @@ def initialize(self): ) def setup(self, **kwargs): - if use_new_openmdao_syntax: - # rely on openMDAO's auto-ordering for this group - self.options['auto_order'] = True + # rely on openMDAO's auto-ordering for this group + self.options['auto_order'] = True aviary_options = self.options['aviary_options'] subsystems = self.options['subsystems'] diff --git a/aviary/subsystems/propulsion/test/test_propulsion_mission.py b/aviary/subsystems/propulsion/test/test_propulsion_mission.py index 0faddea21b..c53336b6f4 100644 --- a/aviary/subsystems/propulsion/test/test_propulsion_mission.py +++ b/aviary/subsystems/propulsion/test/test_propulsion_mission.py @@ -29,10 +29,6 @@ def setUp(self): self.options = AviaryValues() self.options.set_val(Settings.VERBOSITY, 0) - @unittest.skipIf( - version.parse(openmdao.__version__) < version.parse('3.26'), - 'Skipping due to OpenMDAO version being too low (<3.26)', - ) def test_case_1(self): # 'clean' test using GASP-derived engine deck nn = 20 diff --git a/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py b/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py index cfcff344e7..4d568d0ef5 100644 --- a/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py +++ b/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py @@ -101,8 +101,8 @@ def test_subsystems_in_a_mission(self): f'traj.cruise2.timeseries.{av.Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED}' ) expected_scalar_values = { - cumulative_energy_var: (38.46816871, 'kW*h'), - av.Mission.FUEL_MASS: (1249.64650547, 'lbm'), + cumulative_energy_var: (38.61409156, 'kW*h'), + av.Mission.FUEL_MASS: (1254.14061154, 'lbm'), } for var_name, (expected, units) in expected_scalar_values.items(): @@ -119,51 +119,51 @@ def test_subsystems_in_a_mission(self): expected_soc_values = { soc_cruise1_var: ( [ - 0.9999957806265609, - 0.9877977965127587, - 0.9709679386644526, - 0.9656415564989798, - 0.9656415564989798, - 0.9407334200010511, - 0.906368905403873, - 0.8954935308182879, - 0.8954935308182879, - 0.8658878715348804, - 0.8250432325811342, - 0.8121172826623315, - 0.8121172826623315, - 0.7872227709968601, - 0.752877052113554, - 0.7420076253955674, - 0.7420076253955674, - 0.729820851948888, - 0.7130064610124855, - 0.7076849737044318, + 0.99999578, + 0.98775148, + 0.97085772, + 0.96551112, + 0.96551112, + 0.94050842, + 0.90601345, + 0.8950968, + 0.8950968, + 0.86537877, + 0.82437912, + 0.81140412, + 0.81140412, + 0.78641514, + 0.75193911, + 0.74102844, + 0.74102844, + 0.72879544, + 0.71191726, + 0.70657558, ], None, ), soc_cruise2_var: ( [ - 0.7076849737044318, - 0.6954996910206249, - 0.6786873568305393, - 0.6733665204268243, - 0.6733665204268243, - 0.6484843167073028, - 0.6141555768684874, - 0.6032915231366659, - 0.6032915231366659, - 0.5737166802223987, - 0.532914551421322, - 0.5200020533696793, - 0.5200020533696793, - 0.49513344752347366, - 0.460823466208866, - 0.44996534857628184, - 0.44996534857628184, - 0.4377912370406455, - 0.4209942619176692, - 0.41567827333310314, + 0.70657558, + 0.69434408, + 0.67746797, + 0.67212695, + 0.67212695, + 0.64715037, + 0.61269144, + 0.60178619, + 0.60178619, + 0.5720992, + 0.53114236, + 0.51818091, + 0.51818091, + 0.49321803, + 0.45877799, + 0.44787871, + 0.44787871, + 0.43565848, + 0.41879792, + 0.41346182, ], None, ), diff --git a/aviary/validation_cases/benchmark_tests/test_subsystems_within_a_mission.py b/aviary/validation_cases/benchmark_tests/test_subsystems_within_a_mission.py index b0bc9bf5d1..1c7c9f23c9 100644 --- a/aviary/validation_cases/benchmark_tests/test_subsystems_within_a_mission.py +++ b/aviary/validation_cases/benchmark_tests/test_subsystems_within_a_mission.py @@ -1,3 +1,4 @@ +from copy import deepcopy import unittest import numpy as np @@ -127,9 +128,11 @@ def test_subsystems_in_a_mission_energy_state(self): def test_subsystems_in_a_mission_2dof(self): prob = AviaryProblem(verbosity=0) + local_phase_info = deepcopy(two_dof_phase_info) + prob.load_inputs( 'validation_cases/validation_data/test_models/aircraft_for_bench_GwGm.csv', - two_dof_phase_info, + local_phase_info, ) prob.load_external_subsystems(