Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Flops tabular aero so that it correctly supports passing the lift independent and dependent polars. #604

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 59 additions & 1 deletion aviary/subsystems/aerodynamics/aerodynamics_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ def get_parameters(self, aviary_inputs=None, phase_info=None):
method = 'computed'

if phase_info is not None:
# Only solved_alpha has connectable inputs.

# Only some methods have connectable training inputs.
if method == 'solved_alpha':
aero_data = aero_opt['aero_data']

Expand Down Expand Up @@ -369,6 +370,63 @@ def get_parameters(self, aviary_inputs=None, phase_info=None):
params[Aircraft.Design.LIFT_POLAR] = lift_opts
params[Aircraft.Design.DRAG_POLAR] = drag_opts

elif method == 'tabular':
CD0_data = aero_opt['CD0_data']

if isinstance(CD0_data, NamedValues):
altitude = CD0_data.get_item('altitude')[0]
mach = CD0_data.get_item('mach')[0]

n1 = altitude.size
n2 = mach.size
n1u = np.unique(altitude).size

if n1 > n1u:
# Data is free-format instead of pre-formatted.
n1 = n1u
n2 = np.unique(mach).size

shape = (n1, n2)

if aviary_inputs is not None and Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR in aviary_inputs:
opts = {
'val': aviary_inputs.get_val(Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR),
'static_target': True
}
else:
opts = {'shape': shape,
'static_target': True}

params[Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR] = opts

CDI_data = aero_opt['CDI_data']

if isinstance(CDI_data, NamedValues):
mach = CDI_data.get_item('mach')[0]
cl = CDI_data.get_item('lift_coefficient')[0]

n1 = mach.size
n2 = cl.size
n1u = np.unique(mach).size

if n1 > n1u:
# Data is free-format instead of pre-formatted.
n1 = n1u
n2 = np.unique(cl).size

shape = (n1, n2)

if aviary_inputs is not None and Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR in aviary_inputs:
opts = {
'val': aviary_inputs.get_val(Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR),
'static_target': True
}
else:
opts = {'shape': shape,
'static_target': True}

params[Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR] = opts

if method == 'computed':

for var in COMPUTED_CORE_INPUTS:
Expand Down
16 changes: 14 additions & 2 deletions aviary/subsystems/aerodynamics/flops_based/tabular_aero_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,24 @@ def setup(self):
Aircraft.Wing.AREA, Dynamic.Mission.DYNAMIC_PRESSURE],
promotes_outputs=[('cl', 'lift_coefficient'), Dynamic.Mission.LIFT])

if connect_training_data:
extra_promotes = [('zero_lift_drag_coefficient_train',
Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR)]
else:
extra_promotes = []

self.add_subsystem('CD0_interp', CD0_interp,
promotes_inputs=['*'],
promotes_inputs=['*'] + extra_promotes,
promotes_outputs=['*'])

if connect_training_data:
extra_promotes = [('lift_dependent_drag_coefficient_train',
Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR)]
else:
extra_promotes = []

self.add_subsystem('CDI_interp', CDI_interp,
promotes_inputs=['*'],
promotes_inputs=['*'] + extra_promotes,
promotes_outputs=['*'])

self.add_subsystem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,13 @@ def setUp(self):

CDI_table = _default_CDI_data()
CDI_values = CDI_table.get_val('lift_dependent_drag_coefficient')
# CDI_table.delete('lift_dependent_drag_coefficient')
CD0_table = _default_CD0_data()
CD0_values = CD0_table.get_val('zero_lift_drag_coefficient')
# CD0_table.delete('zero_lift_drag_coefficient')

drag_data = om.ExecComp()
drag_data.add_output('zero_lift_drag_coefficient_train',
drag_data.add_output(Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR,
CD0_values, units='unitless')
drag_data.add_output('lift_dependent_drag_coefficient_train',
drag_data.add_output(Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR,
CDI_values, units='unitless')

self.prob.model.add_subsystem(
Expand All @@ -151,8 +149,33 @@ def setUp(self):
promotes_outputs=['*']
)

kwargs = {'method': 'tabular', 'CDI_data': CDI_table, 'CD0_data': CD0_table, }
# 'training_data': True}
# Pass zero-arrays for the training data, so that this test won't pass unless
# we are passing the values from the drag_data component.
shape = CDI_table.get_item('lift_dependent_drag_coefficient')[0].shape
CDI_clean_table = _default_CDI_data()
CDI_clean_table.set_val(
'lift_dependent_drag_coefficient',
np.zeros(shape)
)

shape = CD0_table.get_item('zero_lift_drag_coefficient')[0].shape
CD0_clean_table = _default_CD0_data()
CD0_clean_table.set_val(
'zero_lift_drag_coefficient',
np.zeros(shape)
)

self.CDI_values = CDI_values
self.CD0_values = CD0_values
self.CDI_clean_table = CDI_clean_table
self.CD0_clean_table = CD0_clean_table

kwargs = {
'method': 'tabular',
'CDI_data': CDI_clean_table,
'CD0_data': CD0_clean_table,
'connect_training_data': True
}

aero_builder = CoreAerodynamicsBuilder(code_origin=FLOPS)

Expand Down Expand Up @@ -199,6 +222,56 @@ def test_case(self):
partial_data, atol=1e-9, rtol=1e-12
) # check the partial derivatives

def test_parameters(self):

local_phase_info = deepcopy(phase_info)
core_aero = local_phase_info['cruise']['subsystem_options']['core_aerodynamics']

core_aero['method'] = 'tabular'
core_aero['connect_training_data'] = True
core_aero['CDI_data'] = self.CDI_clean_table
core_aero['CD0_data'] = self.CD0_clean_table
local_phase_info.pop('climb')
local_phase_info.pop('descent')

prob = AviaryProblem()

prob.load_inputs(
"subsystems/aerodynamics/flops_based/test/data/high_wing_single_aisle.csv",
local_phase_info
)

# Preprocess inputs
prob.check_and_preprocess_inputs()

prob.add_pre_mission_systems()
prob.add_phases()
prob.add_post_mission_systems()

prob.link_phases()

# Connect or set.
prob.aviary_inputs.set_val(
Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR,
self.CD0_values
)
prob.aviary_inputs.set_val(
Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR,
self.CDI_values
)

prob.setup()

prob.set_initial_guesses()

prob.run_model()

assert_near_equal(
prob.get_val("traj.cruise.rhs_all.drag", units='lbf')[0],
9896.0,
1.0e-3
)


data_sets = ['LargeSingleAisle1FLOPS', 'LargeSingleAisle2FLOPS', 'N3CC']

Expand Down
22 changes: 22 additions & 0 deletions aviary/variable_info/variable_meta_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,28 @@
desc='Scaling factor for lift-dependent drag coefficient'
)

add_meta_data(
Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR,
meta_data=_MetaData,
historical_name={"GASP": None,
"FLOPS": None,
"LEAPS1": None
},
units='unitless',
desc='Lift dependent drag polar computed during Aviary pre-mission.',
)

add_meta_data(
Aircraft.Design.LIFT_INDEPENDENT_DRAG_POLAR,
meta_data=_MetaData,
historical_name={"GASP": None,
"FLOPS": None,
"LEAPS1": None
},
units='unitless',
desc='Lift independent drag polar computed during Aviary pre-mission.',
)

add_meta_data(
Aircraft.Design.LIFT_POLAR,
meta_data=_MetaData,
Expand Down
4 changes: 4 additions & 0 deletions aviary/variable_info/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ class Design:
LIFT_CURVE_SLOPE = 'aircraft:design:lift_curve_slope'
LIFT_DEPENDENT_DRAG_COEFF_FACTOR = \
'aircraft:design:lift_dependent_drag_coeff_factor'

LIFT_DEPENDENT_DRAG_POLAR = 'aircraft:design:lift_dependent_drag_polar'
LIFT_INDEPENDENT_DRAG_POLAR = 'aircraft:design:lift_independent_drag_polar'

LIFT_POLAR = 'aircraft:design:lift_polar'

MAX_FUSELAGE_PITCH_ANGLE = 'aircraft:design:max_fuselage_pitch_angle'
Expand Down
Loading