Level 3#
Level 3 represents the highest level of user control and customization in Aviary’s user interface. At this level, users have full access to Python and OpenMDAO methods that Aviary calls. They can use the complete set of Aviary’s methods, functionalities, and classes to construct and fine-tune their aircraft models. Level 3 enables users to have supreme control over every aspect of the model, including subsystems, connections, and advanced optimization techniques.
Level 3 is the most complex but specific methods defined at this level are used in levels 1 and 2, hopefully reducing user activation energy when learning more about Aviary. This progressive approach helps users gradually enhance their analysis capabilities and adapt to more complex modeling requirements as they gain proficiency and experience.
We will show two approaches of level 3 development using two examples: The first one will implement all methods differently from what are available in aviary/interface/methods_for_level2.py
but will follow the same steps. It will show that you don’t have to have a .csv
input file and you don’t have to have a phase_info
dictionary. The second is a solved
mission approach that is embedded into all the methods of aviary/interface/methods_for_level2.py
.
Note
For each of these examples we have set max_iter = 0
, which means that the optimization will not run. This is done to reduce the computational time for the examples. If you want to run the optimization, you can set max_iter = 100
or some similar value.
A level 3 example: N3CC#
In level 2, we have shown how to follow the standard steps to build an Aviary model, but sometimes you may find that the model you have in mind does not match that predefined structure. If you start a new model that cannot been embedded in those methods, we can write special methods ourselves. This example will show you how to do that.
In aviary/validation_cases/benchmark_tests
folder, there is an N3CC aircraft full mission benchmark test test_FLOPS_based_sizing_N3CC.py
. Now, we will show how to create an N3CC example in level3. The key is that we follow the same steps:
init
load_inputs
check_and_preprocess_inputs (optional)
add_pre_mission_systems
add_phases
add_post_mission_systems
link_phases
add_driver
add_design_variables (optional)
add_objective
setup
set_initial_guesses
run_aviary_problem
Examining an N3CC design case#
'''
NOTES:
Includes:
Takeoff, Climb, Cruise, Descent, Landing
Computed Aero
N3CC data
'''
import dymos as dm
import openmdao.api as om
import scipy.constants as _units
import aviary.api as av
from aviary.validation_cases.validation_tests import get_flops_inputs
prob = om.Problem(model=om.Group())
driver = prob.driver = om.pyOptSparseDriver()
driver.options["optimizer"] = "IPOPT"
driver.opt_settings["max_iter"] = 100
driver.opt_settings["tol"] = 1e-3
driver.opt_settings['print_level'] = 4
########################################
# Aircraft Input Variables and Options #
########################################
aviary_inputs = get_flops_inputs('N3CC')
aviary_inputs.set_val(av.Mission.Landing.LIFT_COEFFICIENT_MAX,
2.4, units="unitless")
aviary_inputs.set_val(av.Mission.Takeoff.LIFT_COEFFICIENT_MAX,
2.0, units="unitless")
aviary_inputs.set_val(
av.Mission.Takeoff.ROLLING_FRICTION_COEFFICIENT,
val=.0175, units="unitless")
takeoff_fuel_burned = 577 # lbm
takeoff_thrust_per_eng = 24555.5 # lbf
takeoff_L_over_D = 17.35
aviary_inputs.set_val(av.Mission.Takeoff.FUEL_SIMPLE,
takeoff_fuel_burned, units='lbm')
aviary_inputs.set_val(av.Mission.Takeoff.LIFT_OVER_DRAG,
takeoff_L_over_D, units="unitless")
aviary_inputs.set_val(av.Mission.Design.THRUST_TAKEOFF_PER_ENG,
takeoff_thrust_per_eng, units='lbf')
alt_airport = 0 # ft
cruise_mach = 0.79
alt_i_climb = 0*_units.foot # m
alt_f_climb = 35000.0*_units.foot # m
mass_i_climb = 131000*_units.lb # kg
mass_f_climb = 126000*_units.lb # kg
# initial mach set to lower value so it can intersect with takeoff end mach
# mach_i_climb = 0.3
mach_i_climb = 0.2
mach_f_climb = cruise_mach
range_i_climb = 0*_units.nautical_mile # m
range_f_climb = 160.3*_units.nautical_mile # m
t_i_climb = 2 * _units.minute # sec
t_f_climb = 26.20*_units.minute # sec
t_duration_climb = t_f_climb - t_i_climb
alt_i_cruise = 35000*_units.foot # m
alt_f_cruise = 35000*_units.foot # m
alt_min_cruise = 35000*_units.foot # m
alt_max_cruise = 35000*_units.foot # m
mass_i_cruise = 126000*_units.lb # kg
mass_f_cruise = 102000*_units.lb # kg
cruise_mach = cruise_mach
range_i_cruise = 160.3*_units.nautical_mile # m
range_f_cruise = 3243.9*_units.nautical_mile # m
t_i_cruise = 26.20*_units.minute # sec
t_f_cruise = 432.38*_units.minute # sec
t_duration_cruise = t_f_cruise - t_i_cruise
alt_i_descent = 35000*_units.foot
# final altitude set to 35 to ensure landing is feasible point
# alt_f_descent = 0*_units.foot
alt_f_descent = 35*_units.foot
mach_i_descent = 0.79
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 = 432.38*_units.minute
t_f_descent = 461.62*_units.minute
t_duration_descent = t_f_descent - t_i_descent
engine = av.build_engine_deck(aviary_inputs)
av.preprocess_options(aviary_inputs, engine_models=engine)
# define 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')
aviary_inputs.set_val(av.Mission.Summary.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)
prob.model.add_design_var(av.Mission.Summary.GROSS_MASS, units='lbm',
lower=100000.0, upper=200000.0, ref=135000)
takeoff_options = av.HeightEnergyTakeoffPhaseBuilder(
airport_altitude=alt_airport, # ft
# no units
num_engines=aviary_inputs.get_val(av.Aircraft.Engine.NUM_ENGINES)
)
#################
# 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': (False, 'unitless'),
'input_initial': (True, 'unitless'),
'use_polynomial_control': (False, 'unitless'),
}),
core_subsystems=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=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=mission_subsystems,
subsystem_options={'core_aerodynamics': {'method': 'computed'}},
transcription=transcription_descent,
)
landing_options = av.HeightEnergyLandingPhaseBuilder(
ref_wing_area=aviary_inputs.get_val(av.Aircraft.Wing.AREA, units='ft**2'),
Cl_max_ldg=aviary_inputs.get_val(
av.Mission.Landing.LIFT_COEFFICIENT_MAX) # no units
)
# 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
takeoff = takeoff_options.build_phase(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)
landing = landing_options.build_phase(False)
prob.model.add_subsystem(
'takeoff', takeoff, promotes_inputs=['aircraft:*', 'mission:*'],
promotes_outputs=['mission:*'])
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)
prob.model.add_subsystem(
'landing', landing, promotes_inputs=['aircraft:*', 'mission:*'],
promotes_outputs=['mission:*'])
###############
# link phases #
###############
traj.link_phases(["climb", "cruise", "descent"], ["time", av.Dynamic.Mission.MASS, av.Dynamic.Mission.DISTANCE], connected=strong_couple)
param_vars = [av.Aircraft.Nacelle.CHARACTERISTIC_LENGTH,
av.Aircraft.Nacelle.FINENESS,
av.Aircraft.Nacelle.LAMINAR_FLOW_LOWER,
av.Aircraft.Nacelle.LAMINAR_FLOW_UPPER,
av.Aircraft.Nacelle.WETTED_AREA]
params = {}
for var in param_vars:
params[var] = {'shape': (1, ), 'static_target': True}
external_parameters = {}
external_parameters['climb'] = params
external_parameters['cruise'] = params
external_parameters['descent'] = params
traj = av.setup_trajectory_params(prob.model, traj, aviary_inputs,
external_parameters=external_parameters)
##################################
# Connect in Takeoff and Landing #
##################################
prob.model.connect(av.Mission.Takeoff.FINAL_MASS,
'traj.climb.initial_states:mass')
prob.model.connect(av.Mission.Takeoff.GROUND_DISTANCE,
'traj.climb.initial_states:distance')
prob.model.connect('traj.descent.states:mass',
av.Mission.Landing.TOUCHDOWN_MASS, src_indices=[-1])
prob.model.connect('traj.descent.control_values:altitude', av.Mission.Landing.INITIAL_ALTITUDE,
src_indices=[-1])
###############
# 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])
ecomp = om.ExecComp('overall_fuel = fuel_burned + fuel_reserve',
fuel_burned={'units': 'lbm', 'shape': 1},
fuel_reserve={'units': 'lbm', 'val': 2173.},
overall_fuel={'units': 'lbm'})
prob.model.add_subsystem('fuel_calc', ecomp,
promotes_inputs=['fuel_burned'],
promotes_outputs=['overall_fuel'])
ecomp = om.ExecComp(
'mass_resid = operating_empty_mass + overall_fuel + payload_mass '
'- initial_mass',
operating_empty_mass={'units': 'lbm'},
overall_fuel={'units': 'lbm'},
payload_mass={'units': 'lbm'},
initial_mass={'units': 'lbm'},
mass_resid={'units': 'lbm'})
prob.model.add_subsystem(
'mass_constraint', ecomp,
promotes_inputs=[
('operating_empty_mass', av.Aircraft.Design.OPERATING_MASS),
'overall_fuel',
('payload_mass', av.Aircraft.CrewPayload.TOTAL_PAYLOAD_MASS),
('initial_mass', av.Mission.Design.GROSS_MASS)],
promotes_outputs=['mass_resid'])
prob.model.add_constraint('mass_resid', equals=0.0, ref=1.0)
prob.model.add_subsystem(
'gtow_constraint',
om.EQConstraintComp(
'GTOW',
eq_units='lbm',
normalize=True,
add_constraint=True,
),
promotes_inputs=[
('lhs:GTOW', av.Mission.Design.GROSS_MASS),
('rhs:GTOW', av.Mission.Summary.GROSS_MASS),
],
)
##########################
# Add Objective Function #
##########################
# This is an example of a overall mission objective
# create a compound objective that minimizes climb time and maximizes final mass
# we are maxing final mass b/c we don't have an independent value for fuel_mass yet
# we are going to normalize these (making each of the sub-objectives approx = 1 )
prob.model.add_subsystem(
"regularization",
om.ExecComp(
"reg_objective = fuel_mass/1500",
reg_objective=0.0,
fuel_mass={"units": "lbm", "shape": 1},
),
promotes_outputs=['reg_objective']
)
# connect the final mass from cruise into the objective
prob.model.connect(av.Mission.Design.FUEL_MASS, "regularization.fuel_mass")
prob.model.add_objective('reg_objective', ref=1)
# Set initial default values for all LEAPS aircraft variables.
varnames = [
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.Mission.Summary.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=[range_i_climb, range_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=[range_i_cruise, range_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},
solution_record_file='N3CC_sizing.db')
prob.record("final")
prob.cleanup()
times_climb = prob.get_val('traj.climb.timeseries.time', units='s')
altitudes_climb = prob.get_val(
'traj.climb.timeseries.altitude', units='m')
masses_climb = prob.get_val('traj.climb.timeseries.mass', units='kg')
ranges_climb = prob.get_val('traj.climb.timeseries.distance', units='m')
velocities_climb = prob.get_val(
'traj.climb.timeseries.velocity', units='m/s')
thrusts_climb = prob.get_val('traj.climb.timeseries.thrust_net_total', units='N')
times_cruise = prob.get_val('traj.cruise.timeseries.time', units='s')
altitudes_cruise = prob.get_val(
'traj.cruise.timeseries.altitude', units='m')
masses_cruise = prob.get_val('traj.cruise.timeseries.mass', units='kg')
ranges_cruise = prob.get_val('traj.cruise.timeseries.distance', units='m')
velocities_cruise = prob.get_val(
'traj.cruise.timeseries.velocity', units='m/s')
thrusts_cruise = prob.get_val(
'traj.cruise.timeseries.thrust_net_total', units='N')
times_descent = prob.get_val('traj.descent.timeseries.time', units='s')
altitudes_descent = prob.get_val(
'traj.descent.timeseries.altitude', units='m')
masses_descent = prob.get_val('traj.descent.timeseries.mass', units='kg')
ranges_descent = prob.get_val('traj.descent.timeseries.distance', units='m')
velocities_descent = prob.get_val(
'traj.descent.timeseries.velocity', units='m/s')
thrusts_descent = prob.get_val(
'traj.descent.timeseries.thrust_net_total', units='N')
print("-------------------------------")
print(f"times_climb: {times_climb[-1]} (s)")
print(f"altitudes_climb: {altitudes_climb[-1]} (m)")
print(f"masses_climb: {masses_climb[-1]} (kg)")
print(f"ranges_climb: {ranges_climb[-1]} (m)")
print(f"velocities_climb: {velocities_climb[-1]} (m/s)")
print(f"thrusts_climb: {thrusts_climb[-1]} (N)")
print(f"times_cruise: {times_cruise[-1]} (s)")
print(f"altitudes_cruise: {altitudes_cruise[-1]} (m)")
print(f"masses_cruise: {masses_cruise[-1]} (kg)")
print(f"ranges_cruise: {ranges_cruise[-1]} (m)")
print(f"velocities_cruise: {velocities_cruise[-1]} (m/s)")
print(f"thrusts_cruise: {thrusts_cruise[-1]} (N)")
print(f"times_descent: {times_descent[-1]} (s)")
print(f"altitudes_descent: {altitudes_descent[-1]} (m)")
print(f"masses_descent: {masses_descent[-1]} (kg)")
print(f"ranges_descent: {ranges_descent[-1]} (m)")
print(f"velocities_descent: {velocities_descent[-1]} (m/s)")
print(f"thrusts_descent: {thrusts_descent[-1]} (N)")
print("-------------------------------")
/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_22k' <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*'.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/transcriptions/transcription_base.py:390: OpenMDAOWarning:'traj.phases.climb' <class Phase>
Non-default solvers are required
implicit duration: False
solved segments: False
input initial: True
Setting `traj.phases.climb.nonlinear_solver = om.NewtonSolver(iprint=0, solve_subsystems=True, maxiter=1000, stall_limit=3)`
Explicitly set traj.phases.climb.nonlinear_solver to override.
Setting `traj.phases.climb.linear_solver = om.DirectSolver(iprint=2)`
Explicitly set traj.phases.climb.linear_solver to override.
Set `traj.phases.climb.options["auto_solvers"] = False` to disable this behavior.
--- 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.
+ NL: NewtonSolver 'NL: Newton' on system 'traj.phases.climb.rhs_all': residuals contain 'inf' or 'NaN' after 0 iterations.
NL: NewtonSolver 'NL: Newton' on system 'traj.phases.climb': residuals contain 'inf' or 'NaN' after 0 iterations.
NL: NewtonSolver 'NL: Newton' on system 'traj.phases.cruise.rhs_all': residuals contain 'inf' or 'NaN' after 0 iterations.
List of user-set options:
Name Value used
file_print_level = 5 yes
hessian_approximation = limited-memory yes
linear_solver = mumps yes
max_iter = 100 yes
nlp_scaling_method = user-scaling yes
output_file = reports/problem/IPOPT.out yes
print_level = 4 yes
print_user_options = yes yes
sb = yes yes
tol = 0.001 yes
Number of Iterations....: 0
Number of objective function evaluations = 0
Number of objective gradient evaluations = 0
Number of equality constraint evaluations = 0
Number of inequality constraint evaluations = 1
Number of equality constraint Jacobian evaluations = 0
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 0
Total seconds in IPOPT = 0.071
EXIT: Invalid number in NLP function or derivative detected.
Optimization Problem -- Optimization using pyOpt_sparse
================================================================================
Objective Function: _objfunc
Solution:
--------------------------------------------------------------------------------
Total Time: 0.0722
User Objective Time : 0.0703
User Sensitivity Time : 0.0000
Interface Time : 0.0006
Opt Solver Time: 0.0014
Calls to Objective Function : 1
Calls to Sens Function : 0
Objectives
Index Name Value
0 reg_objective NAN
Variables (c - continuous, i - integer, d - discrete)
Index Name Type Lower Bound Value Upper Bound Status
0 mission:design:gross_mass_0 c 7.407407E-01 1.000000E+00 1.481481E+00
1 mission:summary:gross_mass_0 c 7.407407E-01 1.000000E+00 1.481481E+00
2 traj.climb.t_duration_0 c 5.000000E-01 1.000000E+00 2.000000E+00
3 traj.climb.states:mass_0 c 0.000000E+00 5.935225E+00 1.000000E+17
4 traj.climb.states:mass_1 c 0.000000E+00 5.925793E+00 1.000000E+17
5 traj.climb.states:mass_2 c 0.000000E+00 5.922808E+00 1.000000E+17
6 traj.climb.states:mass_3 c 0.000000E+00 5.908258E+00 1.000000E+17
7 traj.climb.states:mass_4 c 0.000000E+00 5.888182E+00 1.000000E+17
8 traj.climb.states:mass_5 c 0.000000E+00 5.881829E+00 1.000000E+17
9 traj.climb.states:mass_6 c 0.000000E+00 5.862952E+00 1.000000E+17
10 traj.climb.states:mass_7 c 0.000000E+00 5.836905E+00 1.000000E+17
11 traj.climb.states:mass_8 c 0.000000E+00 5.828662E+00 1.000000E+17
12 traj.climb.states:mass_9 c 0.000000E+00 5.809785E+00 1.000000E+17
13 traj.climb.states:mass_10 c 0.000000E+00 5.783739E+00 1.000000E+17
14 traj.climb.states:mass_11 c 0.000000E+00 5.775495E+00 1.000000E+17
15 traj.climb.states:mass_12 c 0.000000E+00 5.760946E+00 1.000000E+17
16 traj.climb.states:mass_13 c 0.000000E+00 5.740870E+00 1.000000E+17
17 traj.climb.states:mass_14 c 0.000000E+00 5.734516E+00 1.000000E+17
18 traj.climb.states:mass_15 c 0.000000E+00 5.727681E+00 1.000000E+17
19 traj.climb.states:mass_16 c 0.000000E+00 5.718249E+00 1.000000E+17
20 traj.climb.states:mass_17 c 0.000000E+00 5.715264E+00 1.000000E+17
21 traj.climb.states:distance_0 c 0.000000E+00 8.947709E-03 1.000000E+15
22 traj.climb.states:distance_1 c 0.000000E+00 2.129372E-02 1.000000E+15
23 traj.climb.states:distance_2 c 0.000000E+00 2.520119E-02 1.000000E+15
24 traj.climb.states:distance_3 c 0.000000E+00 4.424674E-02 1.000000E+15
25 traj.climb.states:distance_4 c 0.000000E+00 7.052571E-02 1.000000E+15
26 traj.climb.states:distance_5 c 0.000000E+00 7.884292E-02 1.000000E+15
27 traj.climb.states:distance_6 c 0.000000E+00 1.035527E-01 1.000000E+15
28 traj.climb.states:distance_7 c 0.000000E+00 1.376470E-01 1.000000E+15
29 traj.climb.states:distance_8 c 0.000000E+00 1.484378E-01 1.000000E+15
30 traj.climb.states:distance_9 c 0.000000E+00 1.731475E-01 1.000000E+15
31 traj.climb.states:distance_10 c 0.000000E+00 2.072419E-01 1.000000E+15
32 traj.climb.states:distance_11 c 0.000000E+00 2.180327E-01 1.000000E+15
33 traj.climb.states:distance_12 c 0.000000E+00 2.370782E-01 1.000000E+15
34 traj.climb.states:distance_13 c 0.000000E+00 2.633572E-01 1.000000E+15
35 traj.climb.states:distance_14 c 0.000000E+00 2.716744E-01 1.000000E+15
36 traj.climb.states:distance_15 c 0.000000E+00 2.806221E-01 1.000000E+15
37 traj.climb.states:distance_16 c 0.000000E+00 2.929681E-01 1.000000E+15
38 traj.climb.states:distance_17 c 0.000000E+00 2.968756E-01 1.000000E+15
39 traj.cruise.t_initial_0 c 7.260000E+02 1.572000E+03 2.904000E+03
40 traj.cruise.t_duration_0 c 5.000000E-01 1.000000E+00 2.000000E+00
41 traj.cruise.states:mass_0 c 0.000000E+00 5.715264E+00 1.000000E+17
42 traj.cruise.states:mass_1 c 0.000000E+00 5.328748E+00 1.000000E+17
43 traj.cruise.states:mass_2 c 0.000000E+00 4.795434E+00 1.000000E+17
44 traj.cruise.states:mass_3 c 0.000000E+00 4.626642E+00 1.000000E+17
45 traj.cruise.states:distance_0 c 0.000000E+00 2.968756E-01 1.000000E+15
46 traj.cruise.states:distance_1 c 0.000000E+00 2.324511E+00 1.000000E+15
47 traj.cruise.states:distance_2 c 0.000000E+00 5.122233E+00 1.000000E+15
48 traj.cruise.states:distance_3 c 0.000000E+00 6.007703E+00 1.000000E+15
49 traj.descent.t_initial_0 c 1.291140E+04 2.594280E+04 5.164560E+04
50 traj.descent.t_duration_0 c 5.000000E-01 1.000000E+00 2.000000E+00
51 traj.descent.states:mass_0 c 0.000000E+00 4.626642E+00 1.000000E+17
52 traj.descent.states:mass_1 c 0.000000E+00 4.624750E+00 1.000000E+17
53 traj.descent.states:mass_2 c 0.000000E+00 4.622140E+00 1.000000E+17
54 traj.descent.states:mass_3 c 0.000000E+00 4.621314E+00 1.000000E+17
55 traj.descent.states:mass_4 c 0.000000E+00 4.617450E+00 1.000000E+17
56 traj.descent.states:mass_5 c 0.000000E+00 4.612119E+00 1.000000E+17
57 traj.descent.states:mass_6 c 0.000000E+00 4.610431E+00 1.000000E+17
58 traj.descent.states:mass_7 c 0.000000E+00 4.605838E+00 1.000000E+17
59 traj.descent.states:mass_8 c 0.000000E+00 4.599500E+00 1.000000E+17
60 traj.descent.states:mass_9 c 0.000000E+00 4.597494E+00 1.000000E+17
61 traj.descent.states:mass_10 c 0.000000E+00 4.593630E+00 1.000000E+17
62 traj.descent.states:mass_11 c 0.000000E+00 4.588299E+00 1.000000E+17
63 traj.descent.states:mass_12 c 0.000000E+00 4.586611E+00 1.000000E+17
64 traj.descent.states:mass_13 c 0.000000E+00 4.584720E+00 1.000000E+17
65 traj.descent.states:mass_14 c 0.000000E+00 4.582109E+00 1.000000E+17
66 traj.descent.states:mass_15 c 0.000000E+00 4.581283E+00 1.000000E+17
67 traj.descent.states:distance_0 c 0.000000E+00 6.007703E+00 1.000000E+15
68 traj.descent.states:distance_1 c 0.000000E+00 6.018115E+00 1.000000E+15
69 traj.descent.states:distance_2 c 0.000000E+00 6.032483E+00 1.000000E+15
70 traj.descent.states:distance_3 c 0.000000E+00 6.037030E+00 1.000000E+15
71 traj.descent.states:distance_4 c 0.000000E+00 6.058295E+00 1.000000E+15
72 traj.descent.states:distance_5 c 0.000000E+00 6.087637E+00 1.000000E+15
73 traj.descent.states:distance_6 c 0.000000E+00 6.096924E+00 1.000000E+15
74 traj.descent.states:distance_7 c 0.000000E+00 6.122206E+00 1.000000E+15
75 traj.descent.states:distance_8 c 0.000000E+00 6.157091E+00 1.000000E+15
76 traj.descent.states:distance_9 c 0.000000E+00 6.168132E+00 1.000000E+15
77 traj.descent.states:distance_10 c 0.000000E+00 6.189397E+00 1.000000E+15
78 traj.descent.states:distance_11 c 0.000000E+00 6.218739E+00 1.000000E+15
79 traj.descent.states:distance_12 c 0.000000E+00 6.228025E+00 1.000000E+15
80 traj.descent.states:distance_13 c 0.000000E+00 6.238438E+00 1.000000E+15
81 traj.descent.states:distance_14 c 0.000000E+00 6.252805E+00 1.000000E+15
82 traj.descent.states:distance_15 c 0.000000E+00 6.257352E+00 1.000000E+15
Constraints (i - inequality, e - equality)
Index Name Type Lower Value Upper Status Lagrange Multiplier (N/A)
0 mass_resid e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
1 gtow_constraint.GTOW e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
2 traj.linkages.climb:time_final|cruise:time_initial e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
3 traj.linkages.climb:mass_final|cruise:mass_initial e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
4 traj.linkages.climb:distance_final|cruise:distance_initial e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
5 traj.linkages.cruise:time_final|descent:time_initial e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
6 traj.linkages.cruise:mass_final|descent:mass_initial e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
7 traj.linkages.cruise:distance_final|descent:distance_initial e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
8 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
9 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
10 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
11 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
12 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
13 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
14 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
15 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
16 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
17 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
18 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
19 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
20 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
21 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
22 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
23 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
24 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
25 traj.climb.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
26 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
27 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
28 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
29 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
30 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
31 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
32 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
33 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
34 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
35 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
36 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
37 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
38 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
39 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
40 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
41 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
42 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
43 traj.climb.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
44 traj.cruise.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
45 traj.cruise.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
46 traj.cruise.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
47 traj.cruise.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
48 traj.cruise.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
49 traj.cruise.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
50 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
51 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
52 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
53 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
54 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
55 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
56 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
57 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
58 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
59 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
60 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
61 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
62 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
63 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
64 traj.descent.collocation_constraint.defects:mass e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
65 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
66 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
67 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
68 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
69 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
70 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
71 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
72 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
73 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
74 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
75 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
76 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
77 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
78 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
79 traj.descent.collocation_constraint.defects:distance e 0.000000E+00 NAN 0.000000E+00 9.00000E+100
80 traj.phases.cruise->path_constraint->altitude_rate_max i 3.000000E+02 NAN 1.000000E+30 lu 9.00000E+100
81 traj.phases.cruise->path_constraint->altitude_rate_max i 3.000000E+02 NAN 1.000000E+30 lu 9.00000E+100
82 traj.phases.cruise->path_constraint->altitude_rate_max i 3.000000E+02 NAN 1.000000E+30 lu 9.00000E+100
83 traj.phases.cruise->path_constraint->altitude_rate_max i 3.000000E+02 NAN 1.000000E+30 lu 9.00000E+100
--------------------------------------------------------------------------------
+ NL: NewtonSolver 'NL: Newton' on system 'traj.phases.climb.rhs_all': residuals contain 'inf' or 'NaN' after 0 iterations.
NL: NewtonSolver 'NL: Newton' on system 'traj.phases.climb': residuals contain 'inf' or 'NaN' after 0 iterations.
NL: NewtonSolver 'NL: Newton' on system 'traj.phases.cruise.rhs_all': residuals contain 'inf' or 'NaN' after 0 iterations.
/home/runner/work/Aviary/Aviary/aviary/subsystems/aerodynamics/flops_based/lift_dependent_drag.py:221: RuntimeWarning: invalid value encountered in divide
DCDP = FCDP * (1.0 + CAM/10.0) * A/AR
/home/runner/work/Aviary/Aviary/aviary/subsystems/aerodynamics/flops_based/induced_drag.py:95: RuntimeWarning: divide by zero encountered in divide
CDi = CL ** 2 / (np.pi * AR * span_efficiency)
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/vectors/default_vector.py:491: RuntimeWarning: invalid value encountered in add
data[idxs] += val
-------------------------------
times_climb: [1572.] (s)
altitudes_climb: [10668.] (m)
masses_climb: [57152.63862] (kg)
ranges_climb: [296875.6] (m)
velocities_climb: [234.25795132] (m/s)
thrusts_climb: [35286.14075168] (N)
times_cruise: [1.] (s)
altitudes_cruise: [0.3048] (m)
masses_cruise: [1.] (kg)
ranges_cruise: [1.] (m)
velocities_cruise: [1.] (m/s)
thrusts_cruise: [4.44822162] (N)
times_descent: [1.] (s)
altitudes_descent: [0.3048] (m)
masses_descent: [1.] (kg)
ranges_descent: [1.] (m)
velocities_descent: [1.] (m/s)
thrusts_descent: [4.44822162] (N)
-------------------------------
This model demonstrates the flexibility of level 3. For example, we do not load the aircraft model from a .csv
file but from a Python file using the get_flops_inputs()
method.
This function not only reads Aviary and mission variables but also builds the engine. More information can be found in aviary/models/N3CC/N3CC_data.py
.
Note that we can read large single aisle aircraft inputs this way as well:
aviary_inputs = get_flops_inputs('LargeSingleAisle1FLOPS')
aviary_inputs = get_flops_inputs('LargeSingleAisle2FLOPS')
aviary_inputs = get_flops_inputs('LargeSingleAisle2FLOPSdw')
aviary_inputs = get_flops_inputs('LargeSingleAisle2FLOPSalt')
The data files are at:
aviary/models/large_single_aisle_1/large_single_aisle_1_FLOPS_data.py
aviary/models/large_single_aisle_2/large_single_aisle_2_FLOPS_data.py
aviary/models/large_single_aisle_2/large_single_aisle_2_detailwing_FLOPS_data.py
aviary/models/large_single_aisle_2/large_single_aisle_2_altwt_FLOPS_data.py
respectively.
Discussing this example in more detail#
We move all the code blocks on taxi to add_pre_mission_system
function because it is how it is done in methods_for_level2.py
. Similarly, all the code blocks on landing are moved to add_post_mission_systems
function. Be careful! Generally speaking, not all components can be moved around due to the expected order of execution.
In aviary/validation_cases/benchmark_tests
folder, there is another N3CC model test_FLOPS_based_sizing_N3CC.py
. If we had started from that model, you would need to have an add_design_variables
function.
Summary#
We have shown in an example that users have total control over every aspect of the model in level 3. There is one big feature that hasn’t been covered: adding external subsystems. We will move on to discuss how to run Aviary External Subsystem next.