Examples of the same mission at different UI levels#
Here we present a sort of Rosetta Stone for the same mission at different UI levels. This is to show the code used to make and solve similar mission optimization problems at different UI levels.
In each of these cases we’ll set the maximum iterations to 0 to save execution time. If you wanted to actually solve these problems, you’d need to set the maximum iterations to a larger number, like 50.
Note
Because we’re setting the max iter to 0, we see an “Optimization FAILED” output, but do not be concerned, this is expected as we’re simply showing the different levels here, not actually solving the problems.
Level 1#
This is the most basic level of the UI.
There’s a command-line interface (CLI) for Level 1, or you can use the Python API shown below.
If you want to make minor modifications to phase_info
, you can do so here, but Level 1 largely assumes you’re using the default setup.
import aviary.api as av
prob = av.run_aviary('models/test_aircraft/aircraft_for_bench_FwFm.csv',
av.default_height_energy_phase_info,
max_iter=0, optimizer="SLSQP", make_plots=False)
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/pyoptsparse/pyOpt_MPI.py:68: UserWarning: mpi4py could not be imported. mpi4py is required to use the parallel gradient analysis and parallel objective analysis for non-gradient based optimizers. Continuing using a dummy MPI module from pyOptSparse.
warnings.warn(warn)
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:897: OMDeprecationWarning:None: The method `add_polynomial_control` is deprecated and will be removed in Dymos 2.1. Please use `add_control` with the appropriate options to define a polynomial control.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'climb': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'climb': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'cruise': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'cruise': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'descent': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'descent': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
The following variables have been overridden:
'aircraft:design:touchdown_mass 152800 lbm
'aircraft:engine:mass [7400.] lbm
'aircraft:fins:mass 0 lbm
'aircraft:fuel:auxiliary_fuel_capacity 0 lbm
'aircraft:fuel:fuselage_fuel_capacity 0 lbm
'aircraft:fuel:total_capacity 45694 lbm
'aircraft:fuselage:planform_area 1578.24 ft**2
'aircraft:fuselage:wetted_area 4158.62 ft**2
'aircraft:horizontal_tail:wetted_area 592.65 ft**2
'aircraft:landing_gear:main_gear_oleo_length 102 inch
'aircraft:landing_gear:nose_gear_oleo_length 67 inch
'aircraft:vertical_tail:wetted_area 581.13 ft**2
'aircraft:wing:aspect_ratio 11.22091 unitless
'aircraft:wing:control_surface_area 137 ft**2
'aircraft:wing:wetted_area 2396.56 ft**2
--- Constraint Report [traj] ---
--- climb ---
[path] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
--- cruise ---
[initial] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
[final] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
--- descent ---
[path] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/solvers/linear/linear_rhs_checker.py:178: SolverWarning:DirectSolver in 'traj.phases.cruise.indep_states' <class StateIndependentsComp>: 'rhs_checking' is active but no redundant adjoint dependencies were found, so caching has been disabled.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/solvers/linear/linear_rhs_checker.py:178: SolverWarning:DirectSolver in 'traj.phases.descent.indep_states' <class StateIndependentsComp>: 'rhs_checking' is active but no redundant adjoint dependencies were found, so caching has been disabled.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/recorders/sqlite_recorder.py:226: UserWarning:The existing case recorder file, problem_history.db, is being overwritten.
Model viewer data has already been recorded for Driver.
Full total jacobian for problem 'aircraft_for_bench_FwFm' was computed 3 times, taking 0.6557928720000064 seconds.
Total jacobian shape: (137, 96)
Jacobian shape: (137, 96) (7.79% nonzero)
FWD solves: 14 REV solves: 0
Total colors vs. total size: 14 vs 96 (85.42% improvement)
Sparsity computed using tolerance: 1e-25
Time to compute sparsity: 0.6558 sec
Time to compute coloring: 0.0529 sec
Memory to compute coloring: 0.0000 MB
Coloring created on: 2024-11-19 19:11:29
Iteration limit reached (Exit mode 9)
Current function value: 0.3
Iterations: 1
Function evaluations: 1
Gradient evaluations: 1
Optimization FAILED.
Iteration limit reached
-----------------------------------
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/driver.py:143: OMDeprecationWarning:boolean evaluation of DriverResult is temporarily implemented to mimick the previous `failed` return behavior of run_driver.
Use the `success` attribute of the returned DriverResult object to test for successful driver completion.
Level 2#
This level grants more flexibility both in defining the phase_info
object but also in calling the individual methods of AviaryProblem
when setting up and running your model.
You can modify the methods you call, what they do, and what info they’re given here.
This is much more verbose than Level 1.
In the absence of additional arguments to the methods, much of the default behavior here is the same as Level 1.
import aviary.api as av
phase_info = {
"pre_mission": {"include_takeoff": False, "optimize_mass": True},
"climb": {
"subsystem_options": {"core_aerodynamics": {"method": "computed"}},
"user_options": {
"optimize_mach": False,
"optimize_altitude": False,
"polynomial_control_order": 1,
"num_segments": 5,
"order": 3,
"solve_for_distance": False,
"initial_mach": (0.2, "unitless"),
"final_mach": (0.72, "unitless"),
"mach_bounds": ((0.18, 0.74), "unitless"),
"initial_altitude": (0.0, "ft"),
"final_altitude": (32000.0, "ft"),
"altitude_bounds": ((0.0, 34000.0), "ft"),
"throttle_enforcement": "path_constraint",
"fix_initial": True,
"constrain_final": False,
"fix_duration": False,
"initial_bounds": ((0.0, 0.0), "min"),
"duration_bounds": ((64.0, 192.0), "min"),
"add_initial_mass_constraint": False,
},
"initial_guesses": {"time": ([0, 128], "min")},
},
"cruise": {
"subsystem_options": {"core_aerodynamics": {"method": "computed"}},
"user_options": {
"optimize_mach": False,
"optimize_altitude": False,
"polynomial_control_order": 1,
"num_segments": 5,
"order": 3,
"solve_for_distance": False,
"initial_mach": (0.72, "unitless"),
"final_mach": (0.72, "unitless"),
"mach_bounds": ((0.7, 0.74), "unitless"),
"initial_altitude": (32000.0, "ft"),
"final_altitude": (34000.0, "ft"),
"altitude_bounds": ((23000.0, 38000.0), "ft"),
"throttle_enforcement": "boundary_constraint",
"fix_initial": False,
"constrain_final": False,
"fix_duration": False,
"initial_bounds": ((64.0, 192.0), "min"),
"duration_bounds": ((56.5, 169.5), "min"),
},
"initial_guesses": {"time": ([128, 113], "min")},
},
"descent": {
"subsystem_options": {"core_aerodynamics": {"method": "computed"}},
"user_options": {
"optimize_mach": False,
"optimize_altitude": False,
"polynomial_control_order": 1,
"num_segments": 5,
"order": 3,
"solve_for_distance": False,
"initial_mach": (0.72, "unitless"),
"final_mach": (0.36, "unitless"),
"mach_bounds": ((0.34, 0.74), "unitless"),
"initial_altitude": (34000.0, "ft"),
"final_altitude": (500.0, "ft"),
"altitude_bounds": ((0.0, 38000.0), "ft"),
"throttle_enforcement": "path_constraint",
"fix_initial": False,
"constrain_final": True,
"fix_duration": False,
"initial_bounds": ((120.5, 361.5), "min"),
"duration_bounds": ((29.0, 87.0), "min"),
},
"initial_guesses": {"time": ([241, 58], "min")},
},
"post_mission": {
"include_landing": False,
"constrain_range": True,
"target_range": (1906, "nmi"),
},
}
csv_path = "models/test_aircraft/aircraft_for_bench_FwFm.csv"
prob = av.AviaryProblem()
# Load aircraft and options data from user
# Allow for user overrides here
prob.load_inputs(csv_path, phase_info)
prob.check_and_preprocess_inputs()
prob.add_pre_mission_systems()
prob.add_phases()
prob.add_post_mission_systems()
# Link phases and variables
prob.link_phases()
prob.add_driver("SLSQP", max_iter=0)
prob.add_design_variables()
prob.add_objective(objective_type="mass", ref=-1e5)
prob.setup()
prob.set_initial_guesses()
prob.run_aviary_problem(record_filename='level2_example.db', suppress_solver_print=True, make_plots=False)
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:897: OMDeprecationWarning:None: The method `add_polynomial_control` is deprecated and will be removed in Dymos 2.1. Please use `add_control` with the appropriate options to define a polynomial control.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'climb': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'climb': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'cruise': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'cruise': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'descent': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'descent': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
The following variables have been overridden:
'aircraft:design:touchdown_mass 152800 lbm
'aircraft:engine:mass [7400.] lbm
'aircraft:fins:mass 0 lbm
'aircraft:fuel:auxiliary_fuel_capacity 0 lbm
'aircraft:fuel:fuselage_fuel_capacity 0 lbm
'aircraft:fuel:total_capacity 45694 lbm
'aircraft:fuselage:planform_area 1578.24 ft**2
'aircraft:fuselage:wetted_area 4158.62 ft**2
'aircraft:horizontal_tail:wetted_area 592.65 ft**2
'aircraft:landing_gear:main_gear_oleo_length 102 inch
'aircraft:landing_gear:nose_gear_oleo_length 67 inch
'aircraft:vertical_tail:wetted_area 581.13 ft**2
'aircraft:wing:aspect_ratio 11.22091 unitless
'aircraft:wing:control_surface_area 137 ft**2
'aircraft:wing:wetted_area 2396.56 ft**2
--- Constraint Report [traj] ---
--- climb ---
[path] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
--- cruise ---
[initial] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
[final] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
--- descent ---
[path] 0.0000e+00 <= throttle <= 1.0000e+00 [unitless]
Model viewer data has already been recorded for Driver.
Full total jacobian for problem 'problem2' was computed 3 times, taking 0.6447690980000971 seconds.
Total jacobian shape: (137, 96)
Jacobian shape: (137, 96) (8.80% nonzero)
FWD solves: 13 REV solves: 0
Total colors vs. total size: 13 vs 96 (86.46% improvement)
Sparsity computed using tolerance: 1e-25
Time to compute sparsity: 0.6448 sec
Time to compute coloring: 0.0543 sec
Memory to compute coloring: 0.0000 MB
Coloring created on: 2024-11-19 19:11:33
Iteration limit reached (Exit mode 9)
Current function value: -0.7956010169800001
Iterations: 1
Function evaluations: 1
Gradient evaluations: 1
Optimization FAILED.
Iteration limit reached
-----------------------------------
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/driver.py:143: OMDeprecationWarning:boolean evaluation of DriverResult is temporarily implemented to mimick the previous `failed` return behavior of run_driver.
Use the `success` attribute of the returned DriverResult object to test for successful driver completion.
Level 3#
This level is the most flexible and the code will be the most verbose. This directly calls the OpenMDAO and Dymos methods used to set up and run the model. You have supreme control over every part of the model and mission definition, but that flexibility results in much more code.
import scipy.constants as _units
import openmdao.api as om
import dymos as dm
import aviary.api as av
from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems
prob = om.Problem(model=om.Group())
driver = prob.driver = om.ScipyOptimizeDriver()
driver.options["optimizer"] = "SLSQP"
driver.options["maxiter"] = 1
########################################
# Aircraft Input Variables and Options #
########################################
csv_path = "models/test_aircraft/aircraft_for_bench_FwFm.csv"
aviary_inputs, _ = av.create_vehicle('models/test_aircraft/aircraft_for_bench_FwFm.csv')
engine = av.build_engine_deck(aviary_inputs)
av.preprocess_options(aviary_inputs, engine_models=engine)
alt_airport = 0 # ft
alt_i_climb = 0*_units.foot # m
alt_f_climb = 32000.0*_units.foot # m
mass_i_climb = 131000*_units.lb # kg
mass_f_climb = 126000*_units.lb # kg
mach_i_climb = 0.2
mach_f_climb = 0.72
distance_i_climb = 0*_units.nautical_mile # m
distance_f_climb = 160.3*_units.nautical_mile # m
t_i_climb = 0. * _units.minute # sec
t_f_climb = 128 * _units.minute # sec
t_duration_climb = t_f_climb - t_i_climb
alt_i_cruise = 32000*_units.foot # m
alt_f_cruise = 34000*_units.foot # m
alt_min_cruise = 32000*_units.foot # m
alt_max_cruise = 34000*_units.foot # m
mass_i_cruise = 126000*_units.lb # kg
mass_f_cruise = 102000*_units.lb # kg
cruise_mach = 0.79
distance_i_cruise = 160.3*_units.nautical_mile # m
distance_f_cruise = 3243.9*_units.nautical_mile # m
t_i_cruise = 128. * _units.minute # sec
t_f_cruise = 241. * _units.minute # sec
t_duration_cruise = t_f_cruise - t_i_cruise
alt_i_descent = 34000*_units.foot
alt_f_descent = 500*_units.foot
mach_i_descent = 0.72
mach_f_descent = 0.3
mass_i_descent = 102000*_units.pound
mass_f_descent = 101000*_units.pound
distance_i_descent = 3243.9*_units.nautical_mile
distance_f_descent = 3378.7*_units.nautical_mile
t_i_descent = 241. * _units.minute
t_f_descent = 299. * _units.minute
t_duration_descent = t_f_descent - t_i_descent
####################
# Build Subsystems #
####################
aero = av.CoreAerodynamicsBuilder(code_origin=av.LegacyCode('FLOPS'))
geom = av.CoreGeometryBuilder(code_origin=av.LegacyCode('FLOPS'))
mass = av.CoreMassBuilder(code_origin=av.LegacyCode('FLOPS'))
prop = av.CorePropulsionBuilder(engine_models=engine)
premission_subsystems = [prop, geom, aero, mass]
mission_subsystems = [aero, prop]
####################
# Design Variables #
####################
# Nudge it a bit off the correct answer to verify that the optimize takes us there.
aviary_inputs.set_val(av.Mission.Design.GROSS_MASS, 135000.0, units='lbm')
prob.model.add_design_var(av.Mission.Design.GROSS_MASS, units='lbm',
lower=100000.0, upper=200000.0, ref=135000)
# default subsystems
default_mission_subsystems = get_default_mission_subsystems('FLOPS', engine)
#################
# Define Phases #
#################
num_segments_climb = 6
num_segments_cruise = 1
num_segments_descent = 5
climb_seg_ends, _ = dm.utils.lgl.lgl(num_segments_climb + 1)
descent_seg_ends, _ = dm.utils.lgl.lgl(num_segments_descent + 1)
transcription_climb = dm.Radau(
num_segments=num_segments_climb, order=3, compressed=True,
segment_ends=climb_seg_ends)
transcription_cruise = dm.Radau(
num_segments=num_segments_cruise, order=3, compressed=True)
transcription_descent = dm.Radau(
num_segments=num_segments_descent, order=3, compressed=True,
segment_ends=descent_seg_ends)
climb_options = av.HeightEnergyPhaseBuilder(
'test_climb',
user_options=av.AviaryValues({
'initial_altitude': (alt_i_climb, 'm'),
'final_altitude': (alt_f_climb, 'm'),
'initial_mach': (mach_i_climb, 'unitless'),
'final_mach': (mach_f_climb, 'unitless'),
'fix_initial': (True, 'unitless'),
'use_polynomial_control': (False, 'unitless'),
}),
core_subsystems=default_mission_subsystems,
subsystem_options={'core_aerodynamics': {'method': 'computed'}},
transcription=transcription_climb,
)
cruise_options = av.HeightEnergyPhaseBuilder(
'test_cruise',
user_options=av.AviaryValues({
'initial_altitude': (alt_min_cruise, 'm'),
'final_altitude': (alt_max_cruise, 'm'),
'initial_mach': (cruise_mach, 'unitless'),
'final_mach': (cruise_mach, 'unitless'),
'required_available_climb_rate': (300, 'ft/min'),
'fix_initial': (False, 'unitless'),
}),
core_subsystems=default_mission_subsystems,
subsystem_options={'core_aerodynamics': {'method': 'computed'}},
transcription=transcription_cruise,
)
descent_options = av.HeightEnergyPhaseBuilder(
'test_descent',
user_options=av.AviaryValues({
'final_altitude': (alt_f_descent, 'm'),
'initial_altitude': (alt_i_descent, 'm'),
'initial_mach': (mach_i_descent, 'unitless'),
'final_mach': (mach_f_descent, 'unitless'),
'fix_initial': (False, 'unitless'),
'use_polynomial_control': (False, 'unitless'),
}),
core_subsystems=default_mission_subsystems,
subsystem_options={'core_aerodynamics': {'method': 'computed'}},
transcription=transcription_descent,
)
av.preprocess_crewpayload(aviary_inputs)
# Upstream pre-mission analysis for aero
prob.model.add_subsystem(
'pre_mission',
av.CorePreMission(aviary_options=aviary_inputs,
subsystems=premission_subsystems),
promotes_inputs=['aircraft:*', 'mission:*'],
promotes_outputs=['aircraft:*', 'mission:*'])
# directly connect phases (strong_couple = True), or use linkage constraints (weak
# coupling / strong_couple=False)
strong_couple = False
climb = climb_options.build_phase(aviary_options=aviary_inputs)
cruise = cruise_options.build_phase(aviary_options=aviary_inputs)
descent = descent_options.build_phase(aviary_options=aviary_inputs)
traj = prob.model.add_subsystem('traj', dm.Trajectory())
# if fix_initial is false, can we always set input_initial to be true for
# necessary states, and then ignore if we use a linkage?
climb.set_time_options(fix_initial=True, fix_duration=False, units='s',
duration_bounds=(t_duration_climb*0.5, t_duration_climb*2),
duration_ref=t_duration_climb)
cruise.set_time_options(fix_initial=False, fix_duration=False, units='s',
duration_bounds=(t_duration_cruise*0.5, t_duration_cruise*2),
duration_ref=t_duration_cruise,
initial_bounds=(t_duration_climb*0.5, t_duration_climb*2))
descent.set_time_options(
fix_initial=False, fix_duration=False, units='s',
duration_bounds=(t_duration_descent*0.5, t_duration_descent*2),
duration_ref=t_duration_descent,
initial_bounds=(
(t_duration_cruise + t_duration_climb)*0.5,
(t_duration_cruise + t_duration_climb)*2))
traj.add_phase('climb', climb)
traj.add_phase('cruise', cruise)
traj.add_phase('descent', descent)
traj.link_phases(["climb", "cruise", "descent"], [
"time", "mass", "distance"], connected=strong_couple)
# Need to declare dymos parameters for every input that is promoted out of the missions.
external_parameters = {'climb': {}, 'cruise': {}, 'descent': {}}
for default_subsys in default_mission_subsystems:
params = default_subsys.get_parameters(aviary_inputs=aviary_inputs,
phase_info={})
for key, val in params.items():
for phname in external_parameters:
external_parameters[phname][key] = val
traj = av.setup_trajectory_params(prob.model, traj, aviary_inputs,
external_parameters=external_parameters)
###############
# Constraints #
###############
ecomp = om.ExecComp('fuel_burned = initial_mass - descent_mass_final',
initial_mass={'units': 'lbm', 'shape': 1},
descent_mass_final={'units': 'lbm', 'shape': 1},
fuel_burned={'units': 'lbm', 'shape': 1})
prob.model.add_subsystem('fuel_burn', ecomp,
promotes_inputs=[
('initial_mass', av.Mission.Design.GROSS_MASS)],
promotes_outputs=['fuel_burned'])
prob.model.connect("traj.descent.states:mass",
"fuel_burn.descent_mass_final", src_indices=[-1])
##########################
# Add Objective Function #
##########################
prob.model.add_objective("fuel_burned", ref=1e4)
# Set initial default values for any variables that have
# different defaults in premission and mission.
varnames = [
av.Aircraft.Wing.AREA,
av.Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN,
av.Aircraft.Wing.SWEEP,
av.Aircraft.Wing.TAPER_RATIO,
av.Aircraft.Wing.THICKNESS_TO_CHORD,
av.Mission.Design.GROSS_MASS,
]
av.set_aviary_input_defaults(prob.model, varnames, aviary_inputs)
prob.setup(force_alloc_complex=True)
av.set_aviary_initial_values(prob, aviary_inputs)
############################################
# Initial Settings for States and Controls #
############################################
prob.set_val('traj.climb.t_initial', t_i_climb, units='s')
prob.set_val('traj.climb.t_duration', t_duration_climb, units='s')
prob.set_val('traj.climb.controls:altitude', climb.interp(
av.Dynamic.Mission.ALTITUDE, ys=[alt_i_climb, alt_f_climb]), units='m')
prob.set_val(
'traj.climb.controls:mach', climb.interp(
av.Dynamic.Mission.MACH, ys=[mach_i_climb, mach_f_climb]), units='unitless')
prob.set_val('traj.climb.states:mass', climb.interp(
av.Dynamic.Mission.MASS, ys=[mass_i_climb, mass_f_climb]), units='kg')
prob.set_val('traj.climb.states:distance', climb.interp(
av.Dynamic.Mission.DISTANCE, ys=[distance_i_climb, distance_f_climb]), units='m')
prob.set_val('traj.cruise.t_initial', t_i_cruise, units='s')
prob.set_val('traj.cruise.t_duration', t_duration_cruise, units='s')
prob.set_val('traj.cruise.controls:altitude', cruise.interp(
av.Dynamic.Mission.ALTITUDE, ys=[alt_i_cruise, alt_f_cruise]), units='m')
prob.set_val(
'traj.cruise.controls:mach', cruise.interp(
av.Dynamic.Mission.MACH, ys=[cruise_mach, cruise_mach]), units='unitless')
prob.set_val('traj.cruise.states:mass', cruise.interp(
av.Dynamic.Mission.MASS, ys=[mass_i_cruise, mass_f_cruise]), units='kg')
prob.set_val('traj.cruise.states:distance', cruise.interp(
av.Dynamic.Mission.DISTANCE, ys=[distance_i_cruise, distance_f_cruise]), units='m')
prob.set_val('traj.descent.t_initial', t_i_descent, units='s')
prob.set_val('traj.descent.t_duration', t_duration_descent, units='s')
prob.set_val('traj.descent.controls:altitude', descent.interp(
av.Dynamic.Mission.ALTITUDE, ys=[alt_i_descent, alt_f_descent]), units='m')
prob.set_val(
'traj.descent.controls:mach', descent.interp(
av.Dynamic.Mission.MACH, ys=[mach_i_descent, mach_f_descent]), units='unitless')
prob.set_val('traj.descent.states:mass', descent.interp(
av.Dynamic.Mission.MASS, ys=[mass_i_descent, mass_f_descent]), units='kg')
prob.set_val('traj.descent.states:distance', descent.interp(
av.Dynamic.Mission.DISTANCE, ys=[distance_i_descent, distance_f_descent]), units='m')
# Turn off solver printing so that the SNOPT output is readable.
prob.set_solver_print(level=0)
dm.run_problem(prob, simulate=False, make_plots=False, simulate_kwargs={
'times_per_seg': 100, 'atol': 1e-9, 'rtol': 1e-9})
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:897: OMDeprecationWarning:None: The method `add_polynomial_control` is deprecated and will be removed in Dymos 2.1. Please use `add_control` with the appropriate options to define a polynomial control.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'climb': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'climb': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'cruise': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'cruise': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'mach' in phase 'descent': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:2323: RuntimeWarning: Invalid options for non-optimal control 'altitude' in phase 'descent': lower, upper, ref
warnings.warn(f"Invalid options for non-optimal control '{name}' in phase "
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:4284: OpenMDAOWarning:Calling `list_inputs` before `final_setup` will only display the default values of variables and will not show the result of any `set_val` calls.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_propulsion.turbofan_28k' <class SizeEngine>: input variable 'aircraft:engine:scaled_sls_thrust', promoted using 'aircraft:engine:scaled_sls_thrust', was already promoted using 'aircraft:engine:scaled_sls_thrust'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.canard' <class Canard>: input variable 'aircraft:canard:area', promoted using 'aircraft:canard:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.canard' <class Canard>: input variable 'aircraft:canard:thickness_to_chord', promoted using 'aircraft:canard:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.canard' <class Canard>: input variable 'aircraft:canard:wetted_area_scaler', promoted using 'aircraft:canard:wetted_area_scaler', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:canard:area', promoted using 'aircraft:canard:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:canard:aspect_ratio', promoted using 'aircraft:canard:aspect_ratio', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:canard:thickness_to_chord', promoted using 'aircraft:canard:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:fuselage:avg_diameter', promoted using 'aircraft:fuselage:avg_diameter', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:fuselage:length', promoted using 'aircraft:fuselage:length', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:horizontal_tail:area', promoted using 'aircraft:horizontal_tail:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:horizontal_tail:aspect_ratio', promoted using 'aircraft:horizontal_tail:aspect_ratio', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:horizontal_tail:thickness_to_chord', promoted using 'aircraft:horizontal_tail:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:nacelle:avg_diameter', promoted using 'aircraft:nacelle:avg_diameter', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:nacelle:avg_length', promoted using 'aircraft:nacelle:avg_length', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:vertical_tail:area', promoted using 'aircraft:vertical_tail:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:vertical_tail:aspect_ratio', promoted using 'aircraft:vertical_tail:aspect_ratio', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:vertical_tail:thickness_to_chord', promoted using 'aircraft:vertical_tail:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:wing:area', promoted using 'aircraft:wing:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:wing:aspect_ratio', promoted using 'aircraft:wing:aspect_ratio', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:wing:glove_and_bat', promoted using 'aircraft:wing:glove_and_bat', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:wing:taper_ratio', promoted using 'aircraft:wing:taper_ratio', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.characteristic_lengths' <class CharacteristicLengths>: input variable 'aircraft:wing:thickness_to_chord', promoted using 'aircraft:wing:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:fuselage:avg_diameter', promoted using 'aircraft:fuselage:avg_diameter', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:fuselage:length', promoted using 'aircraft:fuselage:length', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:fuselage:wetted_area_scaler', promoted using 'aircraft:fuselage:wetted_area_scaler', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:horizontal_tail:thickness_to_chord', promoted using 'aircraft:horizontal_tail:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:horizontal_tail:vertical_tail_fraction', promoted using 'aircraft:horizontal_tail:vertical_tail_fraction', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:vertical_tail:thickness_to_chord', promoted using 'aircraft:vertical_tail:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:wing:area', promoted using 'aircraft:wing:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:wing:aspect_ratio', promoted using 'aircraft:wing:aspect_ratio', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:wing:glove_and_bat', promoted using 'aircraft:wing:glove_and_bat', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.fuselage' <class _Fuselage>: input variable 'aircraft:wing:thickness_to_chord', promoted using 'aircraft:wing:thickness_to_chord', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.nacelles' <class Nacelles>: input variable 'aircraft:nacelle:avg_diameter', promoted using 'aircraft:nacelle:avg_diameter', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.nacelles' <class Nacelles>: input variable 'aircraft:nacelle:avg_length', promoted using 'aircraft:nacelle:avg_length', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.nacelles' <class Nacelles>: input variable 'aircraft:nacelle:wetted_area_scaler', promoted using 'aircraft:nacelle:wetted_area_scaler', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.tail' <class _Tail>: input variable 'aircraft:horizontal_tail:area', promoted using 'aircraft:horizontal_tail:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.tail' <class _Tail>: input variable 'aircraft:horizontal_tail:vertical_tail_fraction', promoted using 'aircraft:horizontal_tail:vertical_tail_fraction', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.tail' <class _Tail>: input variable 'aircraft:horizontal_tail:wetted_area_scaler', promoted using 'aircraft:horizontal_tail:wetted_area_scaler', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.tail' <class _Tail>: input variable 'aircraft:vertical_tail:area', promoted using 'aircraft:vertical_tail:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.tail' <class _Tail>: input variable 'aircraft:vertical_tail:wetted_area_scaler', promoted using 'aircraft:vertical_tail:wetted_area_scaler', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.wing' <class _Wing>: input variable 'aircraft:wing:area', promoted using 'aircraft:wing:area', was already promoted using 'aircraft*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:2422: PromotionWarning:'pre_mission.core_geometry.wing' <class _Wing>: input variable 'aircraft:wing:wetted_area_scaler', promoted using 'aircraft:wing:wetted_area_scaler', was already promoted using 'aircraft*'.
The following variables have been overridden:
'aircraft:design:touchdown_mass 152800 lbm
'aircraft:engine:mass [7400.] lbm
'aircraft:fins:mass 0 lbm
'aircraft:fuel:auxiliary_fuel_capacity 0 lbm
'aircraft:fuel:fuselage_fuel_capacity 0 lbm
'aircraft:fuel:total_capacity 45694 lbm
'aircraft:fuselage:planform_area 1578.24 ft**2
'aircraft:fuselage:wetted_area 4158.62 ft**2
'aircraft:horizontal_tail:wetted_area 592.65 ft**2
'aircraft:landing_gear:main_gear_oleo_length 102 inch
'aircraft:landing_gear:nose_gear_oleo_length 67 inch
'aircraft:vertical_tail:wetted_area 581.13 ft**2
'aircraft:wing:aspect_ratio 11.22091 unitless
'aircraft:wing:control_surface_area 137 ft**2
'aircraft:wing:wetted_area 2396.56 ft**2
--- Constraint Report [traj] ---
--- climb ---
None
--- cruise ---
[path] 3.0000e+02 <= altitude_rate_max [ft/min]
--- descent ---
None
Model viewer data has already been recorded for Driver.
Iteration limit reached (Exit mode 9)
Current function value: 3.4000000000000017
Iterations: 1
Function evaluations: 1
Gradient evaluations: 1
Optimization FAILED.
Iteration limit reached
-----------------------------------
Problem: problem3
Driver: ScipyOptimizeDriver
success : False
iterations : 2
runtime : 6.6887E-01 s
model_evals : 2
model_time : 5.5774E-01 s
deriv_evals : 1
deriv_time : 9.3493E-02 s
exit_status : FAIL