Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
60918bd
test_balaned_field is starting to come together.
robfalck Aug 1, 2025
e5597df
2 phases working
robfalck Aug 5, 2025
01faad4
Modeled a detailed takeoff and landing up through establishment of cl…
robfalck Aug 5, 2025
bb016e9
takeoff through obstacle working with a newton solver to balance alpha
robfalck Aug 7, 2025
12b4f1c
Merge branch 'main' of https://github.com/OpenMDAO/Aviary into balanc…
robfalck Aug 26, 2025
0fd314d
starting to work
robfalck Aug 27, 2025
31ce9fb
starting to work, part2
robfalck Aug 27, 2025
9b121d0
balanced field is at least working, but needs to be improved.
robfalck Sep 2, 2025
cec5c3f
working
robfalck Sep 15, 2025
e97cc57
Merge branch 'main' of github.com:OpenMDAO/Aviary into balanced_field…
Kenneth-T-Moore Sep 19, 2025
2a856d2
first pass at putting bal field in a subsys
Kenneth-T-Moore Sep 19, 2025
ce58c5d
Successful connection to mass
Kenneth-T-Moore Sep 25, 2025
4cf92e3
a little cleanup
Kenneth-T-Moore Sep 25, 2025
10e1bab
leanup
Kenneth-T-Moore Sep 25, 2025
036d907
Merge branch 'main' of github.com:OpenMDAO/Aviary into balanced_field…
Kenneth-T-Moore Oct 3, 2025
60e05ff
Working on supporting post-mission core subsystems.
Kenneth-T-Moore Oct 6, 2025
d247da8
Merge branch 'balanced_field_model' of github.com:Kenneth-T-Moore/avi…
Kenneth-T-Moore Oct 6, 2025
26056d7
Merge branch 'main' of github.com:OpenMDAO/Aviary into balanced_field…
Kenneth-T-Moore Oct 9, 2025
ca6eace
Merge branch 'ci_20251008' of github.com:Kenneth-T-Moore/aviary into …
Kenneth-T-Moore Oct 9, 2025
c9d2f72
progress
Kenneth-T-Moore Oct 9, 2025
90c43e2
Balanced field works as a performance post-mission system
Kenneth-T-Moore Oct 9, 2025
b33482d
latest
Kenneth-T-Moore Oct 10, 2025
eaf675d
Merge branch 'main' of github.com:OpenMDAO/Aviary into balanced_field…
Kenneth-T-Moore Oct 24, 2025
0c0c649
Merge branch 'adv_robust' of github.com:Kenneth-T-Moore/aviary into b…
Kenneth-T-Moore Oct 24, 2025
0a0586d
Fixed some circular dependencies
Kenneth-T-Moore Oct 24, 2025
c59fa86
mostly a few small changes
Kenneth-T-Moore Oct 24, 2025
5095d6f
mostly a few small changes
Kenneth-T-Moore Oct 24, 2025
3218cbc
resolve conflict'
Kenneth-T-Moore Nov 12, 2025
a8b64bc
Added missing file
Kenneth-T-Moore Nov 12, 2025
7e5a3a6
Added file for rob to investigate
Kenneth-T-Moore Nov 19, 2025
6dfff9d
Adjust mass guess
Kenneth-T-Moore Nov 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion aviary/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
###################

# Miscellaneous
from aviary.subsystems.premission import CorePreMission
from aviary.subsystems.core_premission import CorePreMission
from aviary.subsystems.subsystem_builder_base import SubsystemBuilderBase
from aviary.utils.preprocessors import (
preprocess_crewpayload,
Expand Down Expand Up @@ -148,6 +148,7 @@
LandingNoseDownToStop as DetailedLandingNoseDownToStopPhaseBuilder,
)
from aviary.mission.flops_based.phases.detailed_takeoff_phases import (
DetailedTakeoffPhaseBuilder,
TakeoffBrakeReleaseToDecisionSpeed as DetailedTakeoffBrakeReleaseToDecisionSpeedPhaseBuilder,
TakeoffDecisionSpeedToRotate as DetailedTakeoffDecisionSpeedToRotatePhaseBuilder,
TakeoffDecisionSpeedBrakeDelay as DetailedTakeoffDecisionSpeedBrakeDelayPhaseBuilder,
Expand Down Expand Up @@ -179,6 +180,9 @@
TakeoffTrajectory as DetailedTakeoffTrajectoryBuilder,
)

from aviary.mission.flops_based.phases.balanced_field_trajectory import BalancedFieldPhaseBuilder
from aviary.mission.balanced_field_traj_builder import BalancedFieldTrajectoryBuilder

##############
# Subsystems #
##############
Expand Down
20 changes: 19 additions & 1 deletion aviary/core/aviary_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
from aviary.mission.two_dof_problem_configurator import TwoDOFProblemConfigurator
from aviary.mission.utils import get_phase_mission_bus_lengths, process_guess_var
from aviary.subsystems.aerodynamics.aerodynamics_builder import CoreAerodynamicsBuilder
from aviary.subsystems.core_postmission import CorePostMission
from aviary.subsystems.core_premission import CorePreMission
from aviary.subsystems.geometry.geometry_builder import CoreGeometryBuilder
from aviary.subsystems.mass.mass_builder import CoreMassBuilder
from aviary.subsystems.premission import CorePreMission
from aviary.subsystems.propulsion.propulsion_builder import CorePropulsionBuilder
from aviary.subsystems.performance.performance_builder import CorePerformanceBuilder
from aviary.utils.functions import get_path
Expand Down Expand Up @@ -1032,6 +1033,23 @@ def add_post_mission_systems(self, verbosity=None):
'The aircraft may not have enough space for fuel, so check the value of Mission.Constraints.EXCESS_FUEL_CAPACITY for details.'
)

default_subsystems = [
self.core_subsystems['performance'],
]

post_mission.add_subsystem(
'core_subsystems',
CorePostMission(
aviary_options=self.aviary_inputs,
subsystems=default_subsystems,
phase_info=self.phase_info,
phase_mission_bus_lengths=phase_mission_bus_lengths,
post_mission_info=self.post_mission_info,
),
promotes_inputs=['*'],
promotes_outputs=['*'],
)

def link_phases(self, verbosity=None, comm=None):
"""
Link phases together after they've been added.
Expand Down
11 changes: 11 additions & 0 deletions aviary/core/post_mission_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@
import openmdao.api as om
from packaging import version

from aviary.utils.aviary_values import AviaryValues
from aviary.utils.functions import promote_aircraft_and_mission_vars
from aviary.variable_info.variable_meta_data import _MetaData

use_new_openmdao_syntax = version.parse(openmdao.__version__) >= version.parse('3.28')


class PostMissionGroup(om.Group):
"""OpenMDAO group that holds all post-mission systems."""

def initialize(self):
self.options.declare(
'aviary_options',
types=AviaryValues,
desc='collection of Aircraft/Mission specific options',
)
self.options.declare('subsystems', desc='list of core subsystem builders')
self.options.declare('meta_data', desc='problem metadata', default=_MetaData)

def setup(self, **kwargs):
if use_new_openmdao_syntax:
# rely on openMDAO's auto-ordering for this group
Expand Down
11 changes: 11 additions & 0 deletions aviary/core/pre_mission_group.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import openmdao.api as om

from aviary.utils.aviary_values import AviaryValues
from aviary.utils.functions import promote_aircraft_and_mission_vars
from aviary.variable_info.functions import override_aviary_vars
from aviary.variable_info.variable_meta_data import _MetaData


class PreMissionGroup(om.Group):
"""OpenMDAO group that holds all pre-mission systems."""

def initialize(self):
self.options.declare(
'aviary_options',
types=AviaryValues,
desc='collection of Aircraft/Mission specific options',
)
self.options.declare('subsystems', desc='list of core subsystem builders')
self.options.declare('meta_data', desc='problem metadata', default=_MetaData)

def configure(self):
"""
Configure this group for pre-mission.
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import openmdao.api as om

import aviary.api as av
from aviary.api import Mission
from aviary.examples.external_subsystems.balanced_field.balanced_field_submodel import (
create_balance_field_subprob,
)
from aviary.subsystems.subsystem_builder_base import SubsystemBuilderBase


class BalancedFieldBuilder(SubsystemBuilderBase):

def __init__(self, name=None, meta_data=None):
if name is None:
name = 'balanced_field_length'

super().__init__(name=name, meta_data=meta_data)

def build_post_mission(
self, aviary_inputs, phase_info=None, phase_mission_bus_lengths=None, **kwargs
):
return create_balance_field_subprob(aviary_inputs)


if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import warnings

import dymos as dm
import openmdao.api as om

import aviary.api as av
from aviary.api import Mission
from aviary.interface.methods_for_level2 import AviaryProblem
from aviary.models.aircraft.advanced_single_aisle.advanced_single_aisle_data import inputs
from aviary.utils.preprocessors import preprocess_options


# Note, only creating this aviary problem so that it can read the aircraft csv for us.
prob = AviaryProblem()
prob.load_inputs("models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv", verbosity=0)
aviary_options = prob.aviary_inputs.deepcopy()

# These inputs aren't in the aircraft file yet.
aviary_options.set_val(Mission.Takeoff.AIRPORT_ALTITUDE, 0.0, 'ft')
aviary_options.set_val(Mission.Takeoff.DRAG_COEFFICIENT_MIN, 0.05, 'unitless')
aviary_options.set_val(Mission.Takeoff.LIFT_COEFFICIENT_MAX, 3.0, 'unitless')
aviary_options.set_val(Mission.Takeoff.OBSTACLE_HEIGHT, 35.0, 'ft')
aviary_options.set_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 0.0, 'deg')
aviary_options.set_val(Mission.Takeoff.ROLLING_FRICTION_COEFFICIENT, 0.0175)
aviary_options.set_val(Mission.Takeoff.BRAKING_FRICTION_COEFFICIENT, 0.35)
aviary_options.set_val(Mission.Takeoff.SPOILER_DRAG_COEFFICIENT, 0.085000)
aviary_options.set_val(Mission.Takeoff.SPOILER_LIFT_COEFFICIENT, -0.810000)
aviary_options.set_val(Mission.Takeoff.THRUST_INCIDENCE, 0.0, 'deg')
aviary_options.set_val(Mission.Takeoff.FUEL_SIMPLE, 577.0, 'lbm')
aviary_options.set_val(Mission.Design.GROSS_MASS, 160000, units='lbm')

# This builder can be used for both takeoff and landing phases
aero_builder = av.CoreAerodynamicsBuilder(
name='low_speed_aero', code_origin=av.LegacyCode.FLOPS
)

# fmt: off
takeoff_subsystem_options = {
'low_speed_aero': {
'method': 'low_speed',
'ground_altitude': 0.0, # units='m'
'angles_of_attack': [
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
], # units='deg'
'lift_coefficients': [
0.5178, 0.6, 0.75, 0.85, 0.95, 1.05, 1.15, 1.25,
1.35, 1.5, 1.6, 1.7, 1.8, 1.85, 1.9, 1.95,
],
'drag_coefficients': [
0.0674, 0.065, 0.065, 0.07, 0.072, 0.076, 0.084, 0.09,
0.10, 0.11, 0.12, 0.13, 0.15, 0.16, 0.18, 0.20,
],
'lift_coefficient_factor': 1.0,
'drag_coefficient_factor': 1.0,
}
}
# fmt: off

# when using spoilers, add a few more options
takeoff_spoiler_subsystem_options = {
'low_speed_aero': {
**takeoff_subsystem_options['low_speed_aero'],
'use_spoilers': True,
'spoiler_drag_coefficient': inputs.get_val(Mission.Takeoff.SPOILER_DRAG_COEFFICIENT),
'spoiler_lift_coefficient': inputs.get_val(Mission.Takeoff.SPOILER_LIFT_COEFFICIENT),
}
}

# We also need propulsion analysis for takeoff and landing. No additional configuration
# is needed for this builder
engines = [av.build_engine_deck(aviary_options)]
preprocess_options(aviary_options, engine_models=engines)
prop_builder = av.CorePropulsionBuilder(engine_models=engines)

balanced_field_user_options = av.AviaryValues()

from aviary.utils.test_utils.default_subsystems import get_default_premission_subsystems
from aviary.variable_info.functions import setup_model_options

takeoff_trajectory_builder = av.BalancedFieldTrajectoryBuilder('balanced_field_traj',
core_subsystems=[aero_builder, prop_builder],
subsystem_options=takeoff_subsystem_options,
user_options=balanced_field_user_options)

test_problem = om.Problem()

# default subsystems
default_premission_subsystems = get_default_premission_subsystems('FLOPS', engines)

# Upstream pre-mission analysis for aero
test_problem.model.add_subsystem(
'core_subsystems',
av.CorePreMission(
aviary_options=aviary_options,
subsystems=default_premission_subsystems,
),
promotes_inputs=['*'],
promotes_outputs=['*'],
)

# Instantiate the trajectory and add the phases
traj = takeoff_trajectory_builder.build_trajectory(aviary_options=aviary_options, model=test_problem.model)

varnames = [
av.Aircraft.Wing.AREA,
av.Aircraft.Wing.ASPECT_RATIO,
av.Aircraft.Wing.SPAN,
]
av.set_aviary_input_defaults(test_problem.model, varnames, aviary_options)

setup_model_options(test_problem, aviary_options)

# suppress warnings:
# "input variable '...' promoted using '*' was already promoted using 'aircraft:*'
with warnings.catch_warnings():
warnings.simplefilter('ignore', om.PromotionWarning)
test_problem.setup(check=False)

av.set_aviary_initial_values(test_problem, aviary_options)

takeoff_trajectory_builder.apply_initial_guesses(test_problem, 'traj')

test_problem.final_setup()


import dymos
dymos.run_problem(test_problem, run_driver=False, make_plots=True)

print(test_problem.get_reports_dir())

Loading
Loading